mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-02 11:35:46 +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));
|
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
|
// Create the VM first
|
||||||
let cpu_count: u8 = 4;
|
let cpu_count: u8 = 4;
|
||||||
let http_body = guest.api_create_body(cpu_count);
|
let http_body = guest.api_create_body(cpu_count);
|
||||||
@ -2778,6 +2781,9 @@ mod tests {
|
|||||||
|
|
||||||
thread::sleep(std::time::Duration::new(1, 0));
|
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
|
// Create the VM first
|
||||||
let cpu_count: u8 = 4;
|
let cpu_count: u8 = 4;
|
||||||
let http_body = guest.api_create_body(cpu_count);
|
let http_body = guest.api_create_body(cpu_count);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// 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::api::{ApiRequest, VmAction};
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result};
|
||||||
use micro_http::{HttpServer, MediaType, Request, Response, StatusCode, Version};
|
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.shutdown"), Box::new(VmActionHandler::new(VmAction::Shutdown)));
|
||||||
r.routes.insert(endpoint!("/vm.reboot"), Box::new(VmActionHandler::new(VmAction::Reboot)));
|
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.shutdown"), Box::new(VmmShutdown {}));
|
||||||
|
r.routes.insert(endpoint!("/vmm.ping"), Box::new(VmmPing {}));
|
||||||
|
|
||||||
r
|
r
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use crate::api::http::EndpointHandler;
|
use crate::api::http::EndpointHandler;
|
||||||
use crate::api::{
|
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,
|
vmm_shutdown, ApiError, ApiRequest, ApiResult, VmAction, VmConfig,
|
||||||
};
|
};
|
||||||
use micro_http::{Body, Method, Request, Response, StatusCode, Version};
|
use micro_http::{Body, Method, Request, Response, StatusCode, Version};
|
||||||
@ -46,6 +46,9 @@ pub enum HttpError {
|
|||||||
|
|
||||||
/// Could not shut the VMM down
|
/// Could not shut the VMM down
|
||||||
VmmShutdown(ApiError),
|
VmmShutdown(ApiError),
|
||||||
|
|
||||||
|
/// Could not handle VMM ping
|
||||||
|
VmmPing(ApiError),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_response(error: HttpError, status: StatusCode) -> Response {
|
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
|
// /api/v1/vmm.shutdown handler
|
||||||
pub struct VmmShutdown {}
|
pub struct VmmShutdown {}
|
||||||
|
|
||||||
|
@ -105,12 +105,20 @@ pub struct VmInfo {
|
|||||||
pub state: VmState,
|
pub state: VmState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
pub struct VmmPingResponse {
|
||||||
|
pub version: String,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum ApiResponsePayload {
|
pub enum ApiResponsePayload {
|
||||||
/// No data is sent on the channel.
|
/// No data is sent on the channel.
|
||||||
Empty,
|
Empty,
|
||||||
|
|
||||||
/// Virtual machine information
|
/// Virtual machine information
|
||||||
VmInfo(VmInfo),
|
VmInfo(VmInfo),
|
||||||
|
|
||||||
|
/// Vmm ping response
|
||||||
|
VmmPing(VmmPingResponse),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the response sent by the VMM API server through the mpsc channel.
|
/// 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.
|
/// Request the VM information.
|
||||||
VmInfo(Sender<ApiResponse>),
|
VmInfo(Sender<ApiResponse>),
|
||||||
|
|
||||||
|
/// Request the VMM API server status
|
||||||
|
VmmPing(Sender<ApiResponse>),
|
||||||
|
|
||||||
/// Pause a VM.
|
/// Pause a VM.
|
||||||
VmPause(Sender<ApiResponse>),
|
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<()> {
|
pub fn vmm_shutdown(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<()> {
|
||||||
let (response_sender, response_receiver) = channel();
|
let (response_sender, response_receiver) = channel();
|
||||||
|
|
||||||
|
@ -12,16 +12,16 @@ servers:
|
|||||||
|
|
||||||
paths:
|
paths:
|
||||||
|
|
||||||
/vmm.info:
|
/vmm.ping:
|
||||||
get:
|
get:
|
||||||
summary: Returns general information about the cloud-hypervisor Virtual Machine Monitor (VMM).
|
summary: Ping the VMM to check for API server availability
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: The VMM information
|
description: The VMM information
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/VmmInfo'
|
$ref: '#/components/schemas/VmmPingResponse'
|
||||||
|
|
||||||
/vmm.shutdown:
|
/vmm.shutdown:
|
||||||
put:
|
put:
|
||||||
@ -126,7 +126,7 @@ paths:
|
|||||||
components:
|
components:
|
||||||
schemas:
|
schemas:
|
||||||
|
|
||||||
VmmInfo:
|
VmmPingResponse:
|
||||||
required:
|
required:
|
||||||
- version
|
- version
|
||||||
type: object
|
type: object
|
||||||
|
@ -14,7 +14,7 @@ extern crate serde_derive;
|
|||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate vmm_sys_util;
|
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::config::VmConfig;
|
||||||
use crate::vm::{Error as VmError, Vm, VmState};
|
use crate::vm::{Error as VmError, Vm, VmState};
|
||||||
use libc::EFD_NONBLOCK;
|
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> {
|
fn vm_delete(&mut self) -> result::Result<(), VmError> {
|
||||||
if self.vm_config.is_none() {
|
if self.vm_config.is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -433,6 +439,11 @@ impl Vmm {
|
|||||||
|
|
||||||
sender.send(response).map_err(Error::ApiResponseSend)?;
|
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) => {
|
ApiRequest::VmPause(sender) => {
|
||||||
let response = self
|
let response = self
|
||||||
.vm_pause()
|
.vm_pause()
|
||||||
|
Loading…
Reference in New Issue
Block a user