From 0c7128e6eb4efc7d09844a936e7a729b5ecbd14e Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Tue, 10 Oct 2023 12:35:43 +0200 Subject: [PATCH] Can start a domain --- virtweb_backend/src/actors/libvirt_actor.rs | 15 +++++++++++++++ virtweb_backend/src/controllers/vm_controller.rs | 11 +++++++++++ virtweb_backend/src/libvirt_client.rs | 5 +++++ virtweb_backend/src/libvirt_lib_structures.rs | 2 +- virtweb_backend/src/libvirt_rest_structures.rs | 5 +++++ virtweb_backend/src/main.rs | 1 + 6 files changed, 38 insertions(+), 1 deletion(-) diff --git a/virtweb_backend/src/actors/libvirt_actor.rs b/virtweb_backend/src/actors/libvirt_actor.rs index 7d8fdb6..bf0b1e5 100644 --- a/virtweb_backend/src/actors/libvirt_actor.rs +++ b/virtweb_backend/src/actors/libvirt_actor.rs @@ -135,3 +135,18 @@ impl Handler for LibVirtActor { }) } } + +#[derive(Message)] +#[rtype(result = "anyhow::Result<()>")] +pub struct StartDomainReq(pub DomainXMLUuid); + +impl Handler for LibVirtActor { + type Result = anyhow::Result<()>; + + fn handle(&mut self, msg: StartDomainReq, _ctx: &mut Self::Context) -> Self::Result { + log::debug!("Start domain:\n{}", msg.0.as_string()); + let domain = Domain::lookup_by_uuid_string(&self.m, &msg.0.as_string())?; + domain.create()?; + Ok(()) + } +} diff --git a/virtweb_backend/src/controllers/vm_controller.rs b/virtweb_backend/src/controllers/vm_controller.rs index 1b72aec..e9c53df 100644 --- a/virtweb_backend/src/controllers/vm_controller.rs +++ b/virtweb_backend/src/controllers/vm_controller.rs @@ -64,3 +64,14 @@ pub async fn get_single(client: LibVirtReq, id: web::Path) -> H state, })) } + +/// Start a VM +pub async fn start(client: LibVirtReq, id: web::Path) -> HttpResult { + Ok(match client.start_domain(id.uid).await { + Ok(_) => HttpResponse::Ok().json("Domain started"), + Err(e) => { + log::error!("Failed to start domain {:?} ! {e}", id.uid); + HttpResponse::InternalServerError().json("Failed to start domain!") + } + }) +} diff --git a/virtweb_backend/src/libvirt_client.rs b/virtweb_backend/src/libvirt_client.rs index 41b71ed..62849cb 100644 --- a/virtweb_backend/src/libvirt_client.rs +++ b/virtweb_backend/src/libvirt_client.rs @@ -37,4 +37,9 @@ impl LibVirtClient { pub async fn get_domain_state(&self, id: DomainXMLUuid) -> anyhow::Result { self.0.send(libvirt_actor::GetDomainStateReq(id)).await? } + + /// Start a domain + pub async fn start_domain(&self, id: DomainXMLUuid) -> anyhow::Result<()> { + self.0.send(libvirt_actor::StartDomainReq(id)).await? + } } diff --git a/virtweb_backend/src/libvirt_lib_structures.rs b/virtweb_backend/src/libvirt_lib_structures.rs index e283d5b..8b04cff 100644 --- a/virtweb_backend/src/libvirt_lib_structures.rs +++ b/virtweb_backend/src/libvirt_lib_structures.rs @@ -1,4 +1,4 @@ -#[derive(serde::Serialize, serde::Deserialize, Clone, Copy)] +#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug)] pub struct DomainXMLUuid(pub uuid::Uuid); impl DomainXMLUuid { diff --git a/virtweb_backend/src/libvirt_rest_structures.rs b/virtweb_backend/src/libvirt_rest_structures.rs index 1a8e627..e00940c 100644 --- a/virtweb_backend/src/libvirt_rest_structures.rs +++ b/virtweb_backend/src/libvirt_rest_structures.rs @@ -66,6 +66,11 @@ pub struct VMInfo { pub architecture: VMArchitecture, /// VM allocated memory, in megabytes pub memory: usize, + // TODO : storage + // TODO : iso + // TODO : autostart + // TODO : vnc + // TODO : interface } impl VMInfo { diff --git a/virtweb_backend/src/main.rs b/virtweb_backend/src/main.rs index 4434c25..2e84fcd 100644 --- a/virtweb_backend/src/main.rs +++ b/virtweb_backend/src/main.rs @@ -138,6 +138,7 @@ async fn main() -> std::io::Result<()> { .route("/api/vm/create", web::post().to(vm_controller::create)) .route("/api/vm/list", web::get().to(vm_controller::list_all)) .route("/api/vm/{uid}", web::get().to(vm_controller::get_single)) + .route("/api/vm/{uid}/start", web::get().to(vm_controller::start)) }) .bind(&AppConfig::get().listen_address)? .run()