mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 21:55:20 +00:00
http: api: implement vmm.ping
vmm.ping will help to check if http API server is up and running. This also removes the vmm.info endpoint. Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
This commit is contained in:
parent
348a1bc30e
commit
a518651402
@ -2722,6 +2722,9 @@ mod tests {
|
||||
|
||||
thread::sleep(std::time::Duration::new(1, 0));
|
||||
|
||||
// Verify API server is running
|
||||
curl_command(&api_socket, "GET", "http://localhost/api/v1/vmm.ping", None);
|
||||
|
||||
// Create the VM first
|
||||
let cpu_count: u8 = 4;
|
||||
let http_body = guest.api_create_body(cpu_count);
|
||||
@ -2778,6 +2781,9 @@ mod tests {
|
||||
|
||||
thread::sleep(std::time::Duration::new(1, 0));
|
||||
|
||||
// Verify API server is running
|
||||
curl_command(&api_socket, "GET", "http://localhost/api/v1/vmm.ping", None);
|
||||
|
||||
// Create the VM first
|
||||
let cpu_count: u8 = 4;
|
||||
let http_body = guest.api_create_body(cpu_count);
|
||||
|
@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
use crate::api::http_endpoint::{VmActionHandler, VmCreate, VmInfo, VmmShutdown};
|
||||
use crate::api::http_endpoint::{VmActionHandler, VmCreate, VmInfo, VmmPing, VmmShutdown};
|
||||
use crate::api::{ApiRequest, VmAction};
|
||||
use crate::{Error, Result};
|
||||
use micro_http::{HttpServer, MediaType, Request, Response, StatusCode, Version};
|
||||
@ -58,6 +58,7 @@ lazy_static! {
|
||||
r.routes.insert(endpoint!("/vm.shutdown"), Box::new(VmActionHandler::new(VmAction::Shutdown)));
|
||||
r.routes.insert(endpoint!("/vm.reboot"), Box::new(VmActionHandler::new(VmAction::Reboot)));
|
||||
r.routes.insert(endpoint!("/vmm.shutdown"), Box::new(VmmShutdown {}));
|
||||
r.routes.insert(endpoint!("/vmm.ping"), Box::new(VmmPing {}));
|
||||
|
||||
r
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
use crate::api::http::EndpointHandler;
|
||||
use crate::api::{
|
||||
vm_boot, vm_create, vm_delete, vm_info, vm_pause, vm_reboot, vm_resume, vm_shutdown,
|
||||
vm_boot, vm_create, vm_delete, vm_info, vm_pause, vm_reboot, vm_resume, vm_shutdown, vmm_ping,
|
||||
vmm_shutdown, ApiError, ApiRequest, ApiResult, VmAction, VmConfig,
|
||||
};
|
||||
use micro_http::{Body, Method, Request, Response, StatusCode, Version};
|
||||
@ -46,6 +46,9 @@ pub enum HttpError {
|
||||
|
||||
/// Could not shut the VMM down
|
||||
VmmShutdown(ApiError),
|
||||
|
||||
/// Could not handle VMM ping
|
||||
VmmPing(ApiError),
|
||||
}
|
||||
|
||||
fn error_response(error: HttpError, status: StatusCode) -> Response {
|
||||
@ -169,6 +172,32 @@ impl EndpointHandler for VmInfo {
|
||||
}
|
||||
}
|
||||
|
||||
// /api/v1/vmm.info handler
|
||||
pub struct VmmPing {}
|
||||
|
||||
impl EndpointHandler for VmmPing {
|
||||
fn handle_request(
|
||||
&self,
|
||||
req: &Request,
|
||||
api_notifier: EventFd,
|
||||
api_sender: Sender<ApiRequest>,
|
||||
) -> Response {
|
||||
match req.method() {
|
||||
Method::Get => match vmm_ping(api_notifier, api_sender).map_err(HttpError::VmmPing) {
|
||||
Ok(pong) => {
|
||||
let mut response = Response::new(Version::Http11, StatusCode::OK);
|
||||
let info_serialized = serde_json::to_string(&pong).unwrap();
|
||||
|
||||
response.set_body(Body::new(info_serialized));
|
||||
response
|
||||
}
|
||||
Err(e) => error_response(e, StatusCode::InternalServerError),
|
||||
},
|
||||
_ => Response::new(Version::Http11, StatusCode::BadRequest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /api/v1/vmm.shutdown handler
|
||||
pub struct VmmShutdown {}
|
||||
|
||||
|
@ -105,12 +105,20 @@ pub struct VmInfo {
|
||||
pub state: VmState,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct VmmPingResponse {
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
pub enum ApiResponsePayload {
|
||||
/// No data is sent on the channel.
|
||||
Empty,
|
||||
|
||||
/// Virtual machine information
|
||||
VmInfo(VmInfo),
|
||||
|
||||
/// Vmm ping response
|
||||
VmmPing(VmmPingResponse),
|
||||
}
|
||||
|
||||
/// This is the response sent by the VMM API server through the mpsc channel.
|
||||
@ -138,6 +146,9 @@ pub enum ApiRequest {
|
||||
/// Request the VM information.
|
||||
VmInfo(Sender<ApiResponse>),
|
||||
|
||||
/// Request the VMM API server status
|
||||
VmmPing(Sender<ApiResponse>),
|
||||
|
||||
/// Pause a VM.
|
||||
VmPause(Sender<ApiResponse>),
|
||||
|
||||
@ -263,6 +274,22 @@ pub fn vm_info(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<Vm
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vmm_ping(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<VmmPingResponse> {
|
||||
let (response_sender, response_receiver) = channel();
|
||||
|
||||
api_sender
|
||||
.send(ApiRequest::VmmPing(response_sender))
|
||||
.map_err(ApiError::RequestSend)?;
|
||||
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
||||
|
||||
let vmm_pong = response_receiver.recv().map_err(ApiError::ResponseRecv)??;
|
||||
|
||||
match vmm_pong {
|
||||
ApiResponsePayload::VmmPing(pong) => Ok(pong),
|
||||
_ => Err(ApiError::ResponsePayloadType),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vmm_shutdown(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<()> {
|
||||
let (response_sender, response_receiver) = channel();
|
||||
|
||||
|
@ -12,16 +12,16 @@ servers:
|
||||
|
||||
paths:
|
||||
|
||||
/vmm.info:
|
||||
/vmm.ping:
|
||||
get:
|
||||
summary: Returns general information about the cloud-hypervisor Virtual Machine Monitor (VMM).
|
||||
summary: Ping the VMM to check for API server availability
|
||||
responses:
|
||||
200:
|
||||
description: The VMM information
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/VmmInfo'
|
||||
$ref: '#/components/schemas/VmmPingResponse'
|
||||
|
||||
/vmm.shutdown:
|
||||
put:
|
||||
@ -126,7 +126,7 @@ paths:
|
||||
components:
|
||||
schemas:
|
||||
|
||||
VmmInfo:
|
||||
VmmPingResponse:
|
||||
required:
|
||||
- version
|
||||
type: object
|
||||
|
@ -14,7 +14,7 @@ extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
extern crate vmm_sys_util;
|
||||
|
||||
use crate::api::{ApiError, ApiRequest, ApiResponse, ApiResponsePayload, VmInfo};
|
||||
use crate::api::{ApiError, ApiRequest, ApiResponse, ApiResponsePayload, VmInfo, VmmPingResponse};
|
||||
use crate::config::VmConfig;
|
||||
use crate::vm::{Error as VmError, Vm, VmState};
|
||||
use libc::EFD_NONBLOCK;
|
||||
@ -302,6 +302,12 @@ impl Vmm {
|
||||
}
|
||||
}
|
||||
|
||||
fn vmm_ping(&self) -> result::Result<VmmPingResponse, ApiError> {
|
||||
Ok(VmmPingResponse {
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
fn vm_delete(&mut self) -> result::Result<(), VmError> {
|
||||
if self.vm_config.is_none() {
|
||||
return Ok(());
|
||||
@ -433,6 +439,11 @@ impl Vmm {
|
||||
|
||||
sender.send(response).map_err(Error::ApiResponseSend)?;
|
||||
}
|
||||
ApiRequest::VmmPing(sender) => {
|
||||
let response = self.vmm_ping().map(ApiResponsePayload::VmmPing);
|
||||
|
||||
sender.send(response).map_err(Error::ApiResponseSend)?;
|
||||
}
|
||||
ApiRequest::VmPause(sender) => {
|
||||
let response = self
|
||||
.vm_pause()
|
||||
|
Loading…
Reference in New Issue
Block a user