3 Commits

Author SHA1 Message Date
1c6ca2d76a Can get the screenshots of VMs of a group
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2024-11-25 21:36:01 +01:00
7eced6b8b5 Can get the state of VMs of a group 2024-11-25 21:26:28 +01:00
200ccd764d Can suspend and resume VMs 2024-11-25 21:11:33 +01:00
3 changed files with 116 additions and 24 deletions

View File

@@ -2,6 +2,7 @@ use crate::controllers::{HttpResult, LibVirtReq};
use crate::extractors::group_vm_id_extractor::GroupVmIdExtractor; use crate::extractors::group_vm_id_extractor::GroupVmIdExtractor;
use crate::libvirt_rest_structures::vm::VMInfo; use crate::libvirt_rest_structures::vm::VMInfo;
use actix_web::HttpResponse; use actix_web::HttpResponse;
use std::collections::HashMap;
/// Get the list of groups /// Get the list of groups
pub async fn list(client: LibVirtReq) -> HttpResult { pub async fn list(client: LibVirtReq) -> HttpResult {
@@ -18,50 +19,130 @@ pub async fn list(client: LibVirtReq) -> HttpResult {
} }
/// Get information about the VMs of a group /// Get information about the VMs of a group
pub async fn vm_info(vms_ids: GroupVmIdExtractor) -> HttpResult { pub async fn vm_info(vms_xml: GroupVmIdExtractor) -> HttpResult {
let mut vms = Vec::new(); let mut vms = Vec::new();
for vm in vms_ids.0 { for vm in vms_xml.0 {
vms.push(VMInfo::from_domain(vm)?) vms.push(VMInfo::from_domain(vm)?)
} }
Ok(HttpResponse::Ok().json(vms)) Ok(HttpResponse::Ok().json(vms))
} }
#[derive(Default, serde::Serialize)]
pub struct TreatmentResult {
ok: usize,
failed: usize,
}
/// Start the VMs of a group /// Start the VMs of a group
pub async fn vm_start(client: LibVirtReq, vms_ids: GroupVmIdExtractor) -> HttpResult { pub async fn vm_start(client: LibVirtReq, vms: GroupVmIdExtractor) -> HttpResult {
for vm in vms_ids.0 { let mut res = TreatmentResult::default();
for vm in vms.0 {
if let Some(uuid) = vm.uuid { if let Some(uuid) = vm.uuid {
client.start_domain(uuid).await?; match client.start_domain(uuid).await {
Ok(_) => res.ok += 1,
Err(_) => res.failed += 1,
} }
} }
Ok(HttpResponse::Ok().finish()) }
Ok(HttpResponse::Ok().json(res))
} }
/// Shutdown the VMs of a group /// Shutdown the VMs of a group
pub async fn vm_shutdown(client: LibVirtReq, vms_ids: GroupVmIdExtractor) -> HttpResult { pub async fn vm_shutdown(client: LibVirtReq, vms: GroupVmIdExtractor) -> HttpResult {
for vm in vms_ids.0 { let mut res = TreatmentResult::default();
for vm in vms.0 {
if let Some(uuid) = vm.uuid { if let Some(uuid) = vm.uuid {
client.shutdown_domain(uuid).await?; match client.shutdown_domain(uuid).await {
Ok(_) => res.ok += 1,
Err(_) => res.failed += 1,
} }
} }
Ok(HttpResponse::Ok().finish()) }
Ok(HttpResponse::Ok().json(res))
}
/// Suspend the VMs of a group
pub async fn vm_suspend(client: LibVirtReq, vms: GroupVmIdExtractor) -> HttpResult {
let mut res = TreatmentResult::default();
for vm in vms.0 {
if let Some(uuid) = vm.uuid {
match client.suspend_domain(uuid).await {
Ok(_) => res.ok += 1,
Err(_) => res.failed += 1,
}
}
}
Ok(HttpResponse::Ok().json(res))
}
/// Resume the VMs of a group
pub async fn vm_resume(client: LibVirtReq, vms: GroupVmIdExtractor) -> HttpResult {
let mut res = TreatmentResult::default();
for vm in vms.0 {
if let Some(uuid) = vm.uuid {
match client.resume_domain(uuid).await {
Ok(_) => res.ok += 1,
Err(_) => res.failed += 1,
}
}
}
Ok(HttpResponse::Ok().json(res))
} }
/// Kill the VMs of a group /// Kill the VMs of a group
pub async fn vm_kill(client: LibVirtReq, vms_ids: GroupVmIdExtractor) -> HttpResult { pub async fn vm_kill(client: LibVirtReq, vms: GroupVmIdExtractor) -> HttpResult {
for vm in vms_ids.0 { let mut res = TreatmentResult::default();
for vm in vms.0 {
if let Some(uuid) = vm.uuid { if let Some(uuid) = vm.uuid {
client.kill_domain(uuid).await?; match client.kill_domain(uuid).await {
Ok(_) => res.ok += 1,
Err(_) => res.failed += 1,
} }
} }
Ok(HttpResponse::Ok().finish()) }
Ok(HttpResponse::Ok().json(res))
} }
/// Reset the VMs of a group /// Reset the VMs of a group
pub async fn vm_reset(client: LibVirtReq, vms_ids: GroupVmIdExtractor) -> HttpResult { pub async fn vm_reset(client: LibVirtReq, vms: GroupVmIdExtractor) -> HttpResult {
for vm in vms_ids.0 { let mut res = TreatmentResult::default();
for vm in vms.0 {
if let Some(uuid) = vm.uuid { if let Some(uuid) = vm.uuid {
client.reset_domain(uuid).await?; match client.reset_domain(uuid).await {
Ok(_) => res.ok += 1,
Err(_) => res.failed += 1,
} }
} }
Ok(HttpResponse::Ok().finish()) }
Ok(HttpResponse::Ok().json(res))
}
/// Get the screenshot of the VMs of a group
pub async fn vm_screenshot(client: LibVirtReq, vms: GroupVmIdExtractor) -> HttpResult {
if vms.0.is_empty() {
return Ok(HttpResponse::NoContent().finish());
}
let image = if vms.0.len() == 1 {
client.screenshot_domain(vms.0[0].uuid.unwrap()).await?
} else {
return Ok(
HttpResponse::UnprocessableEntity().json("Cannot return multiple VM screenshots!!")
);
};
Ok(HttpResponse::Ok().content_type("image/png").body(image))
}
/// Get the state of the VMs
pub async fn vm_state(client: LibVirtReq, vms: GroupVmIdExtractor) -> HttpResult {
let mut states = HashMap::new();
for vm in vms.0 {
if let Some(uuid) = vm.uuid {
states.insert(uuid, client.get_domain_state(uuid).await?);
}
}
Ok(HttpResponse::Ok().json(states))
} }

View File

@@ -1,4 +1,4 @@
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug, Eq, PartialEq)] #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct XMLUuid(pub uuid::Uuid); pub struct XMLUuid(pub uuid::Uuid);
impl XMLUuid { impl XMLUuid {

View File

@@ -224,8 +224,14 @@ async fn main() -> std::io::Result<()> {
"/api/group/{gid}/vm/shutdown", "/api/group/{gid}/vm/shutdown",
web::get().to(groups_controller::vm_shutdown), web::get().to(groups_controller::vm_shutdown),
) )
// TODO suspend VM .route(
// TODO resume VM "/api/group/{gid}/vm/suspend",
web::get().to(groups_controller::vm_suspend),
)
.route(
"/api/group/{gid}/vm/resume",
web::get().to(groups_controller::vm_resume),
)
.route( .route(
"/api/group/{gid}/vm/kill", "/api/group/{gid}/vm/kill",
web::get().to(groups_controller::vm_kill), web::get().to(groups_controller::vm_kill),
@@ -234,9 +240,14 @@ async fn main() -> std::io::Result<()> {
"/api/group/{gid}/vm/reset", "/api/group/{gid}/vm/reset",
web::get().to(groups_controller::vm_reset), web::get().to(groups_controller::vm_reset),
) )
// TODO reset VM .route(
// TODO screenshot VM "/api/group/{gid}/vm/screenshot",
// TODO state of VM web::get().to(groups_controller::vm_screenshot),
)
.route(
"/api/group/{gid}/vm/state",
web::get().to(groups_controller::vm_state),
)
// Network controller // Network controller
.route( .route(
"/api/network/create", "/api/network/create",