mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: api: Be more specific on "Still pending remove vcpu" errors
Although the CPU manager gives us a quite descriptive error, on the application side (the part calling Cloud Hypervisor) we have absolutely no way to distinguish such error from any other error that may happen when resizing a VM. With this in mind, let's be more specific and return a TooManyRequests (429) error, allowing the caller to have a chance to decide whether they want to retry the operation or not. https://datatracker.ietf.org/doc/html/rfc6585#section-4 Signed-off-by: Fabiano Fidêncio <fidencio@northflank.com>
This commit is contained in:
committed by
Bo Chen
parent
87007a288f
commit
d0225fe68f
@@ -15,12 +15,14 @@ use crate::api::http::{error_response, EndpointHandler, HttpError};
|
|||||||
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
|
||||||
use crate::api::VmCoredump;
|
use crate::api::VmCoredump;
|
||||||
use crate::api::{
|
use crate::api::{
|
||||||
AddDisk, ApiAction, ApiRequest, NetConfig, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem,
|
AddDisk, ApiAction, ApiError, ApiRequest, NetConfig, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem,
|
||||||
VmAddUserDevice, VmAddVdpa, VmAddVsock, VmBoot, VmConfig, VmCounters, VmDelete, VmNmi, VmPause,
|
VmAddUserDevice, VmAddVdpa, VmAddVsock, VmBoot, VmConfig, VmCounters, VmDelete, VmNmi, VmPause,
|
||||||
VmPowerButton, VmReboot, VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeZone, VmRestore,
|
VmPowerButton, VmReboot, VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeZone, VmRestore,
|
||||||
VmResume, VmSendMigration, VmShutdown, VmSnapshot,
|
VmResume, VmSendMigration, VmShutdown, VmSnapshot,
|
||||||
};
|
};
|
||||||
use crate::config::RestoreConfig;
|
use crate::config::RestoreConfig;
|
||||||
|
use crate::cpu::Error as CpuError;
|
||||||
|
use crate::vm::Error as VmError;
|
||||||
|
|
||||||
// /api/v1/vm.create handler
|
// /api/v1/vm.create handler
|
||||||
pub struct VmCreate {}
|
pub struct VmCreate {}
|
||||||
@@ -183,7 +185,6 @@ vm_action_put_handler_body!(VmAddVdpa);
|
|||||||
vm_action_put_handler_body!(VmAddVsock);
|
vm_action_put_handler_body!(VmAddVsock);
|
||||||
vm_action_put_handler_body!(VmAddUserDevice);
|
vm_action_put_handler_body!(VmAddUserDevice);
|
||||||
vm_action_put_handler_body!(VmRemoveDevice);
|
vm_action_put_handler_body!(VmRemoveDevice);
|
||||||
vm_action_put_handler_body!(VmResize);
|
|
||||||
vm_action_put_handler_body!(VmResizeZone);
|
vm_action_put_handler_body!(VmResizeZone);
|
||||||
vm_action_put_handler_body!(VmSnapshot);
|
vm_action_put_handler_body!(VmSnapshot);
|
||||||
vm_action_put_handler_body!(VmReceiveMigration);
|
vm_action_put_handler_body!(VmReceiveMigration);
|
||||||
@@ -220,6 +221,34 @@ impl PutHandler for VmAddNet {
|
|||||||
|
|
||||||
impl GetHandler for VmAddNet {}
|
impl GetHandler for VmAddNet {}
|
||||||
|
|
||||||
|
impl PutHandler for VmResize {
|
||||||
|
fn handle_request(
|
||||||
|
&'static self,
|
||||||
|
api_notifier: EventFd,
|
||||||
|
api_sender: Sender<ApiRequest>,
|
||||||
|
body: &Option<Body>,
|
||||||
|
_files: Vec<File>,
|
||||||
|
) -> std::result::Result<Option<Body>, HttpError> {
|
||||||
|
if let Some(body) = body {
|
||||||
|
self.send(
|
||||||
|
api_notifier,
|
||||||
|
api_sender,
|
||||||
|
serde_json::from_slice(body.raw())?,
|
||||||
|
)
|
||||||
|
.map_err(|e| match e {
|
||||||
|
ApiError::VmResize(VmError::CpuManager(CpuError::VcpuPendingRemovedVcpu)) => {
|
||||||
|
HttpError::TooManyRequests
|
||||||
|
}
|
||||||
|
_ => HttpError::ApiError(e),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(HttpError::BadRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GetHandler for VmResize {}
|
||||||
|
|
||||||
impl PutHandler for VmRestore {
|
impl PutHandler for VmRestore {
|
||||||
fn handle_request(
|
fn handle_request(
|
||||||
&'static self,
|
&'static self,
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ pub enum HttpError {
|
|||||||
/// Undefined endpoints
|
/// Undefined endpoints
|
||||||
NotFound,
|
NotFound,
|
||||||
|
|
||||||
|
/// Too many requests
|
||||||
|
TooManyRequests,
|
||||||
|
|
||||||
/// Internal Server Error
|
/// Internal Server Error
|
||||||
InternalServerError,
|
InternalServerError,
|
||||||
|
|
||||||
@@ -65,6 +68,7 @@ impl Display for HttpError {
|
|||||||
match self {
|
match self {
|
||||||
BadRequest => write!(f, "Bad Request"),
|
BadRequest => write!(f, "Bad Request"),
|
||||||
NotFound => write!(f, "Not Found"),
|
NotFound => write!(f, "Not Found"),
|
||||||
|
TooManyRequests => write!(f, "Too Many Requests"),
|
||||||
InternalServerError => write!(f, "Internal Server Error"),
|
InternalServerError => write!(f, "Internal Server Error"),
|
||||||
SerdeJsonDeserialize(serde_error) => write!(f, "{}", serde_error),
|
SerdeJsonDeserialize(serde_error) => write!(f, "{}", serde_error),
|
||||||
ApiError(api_error) => write!(f, "{}", api_error),
|
ApiError(api_error) => write!(f, "{}", api_error),
|
||||||
@@ -125,6 +129,7 @@ pub trait EndpointHandler {
|
|||||||
Err(e @ HttpError::SerdeJsonDeserialize(_)) => {
|
Err(e @ HttpError::SerdeJsonDeserialize(_)) => {
|
||||||
error_response(e, StatusCode::BadRequest)
|
error_response(e, StatusCode::BadRequest)
|
||||||
}
|
}
|
||||||
|
Err(e @ HttpError::TooManyRequests) => error_response(e, StatusCode::TooManyRequests),
|
||||||
Err(e) => error_response(e, StatusCode::InternalServerError),
|
Err(e) => error_response(e, StatusCode::InternalServerError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ paths:
|
|||||||
description: The VM instance was successfully resized.
|
description: The VM instance was successfully resized.
|
||||||
404:
|
404:
|
||||||
description: The VM instance could not be resized because it is not created.
|
description: The VM instance could not be resized because it is not created.
|
||||||
|
429:
|
||||||
|
description: The VM instance could not be resized because a cpu removal is still pending.
|
||||||
|
|
||||||
/vm.resize-zone:
|
/vm.resize-zone:
|
||||||
put:
|
put:
|
||||||
|
|||||||
Reference in New Issue
Block a user