Return VM state

This commit is contained in:
Pierre HUBERT 2023-10-09 18:45:41 +02:00
parent ce393995f9
commit b69c97e6fe
4 changed files with 62 additions and 4 deletions

View File

@ -1,9 +1,10 @@
use crate::app_config::AppConfig; use crate::app_config::AppConfig;
use crate::libvirt_lib_structures::{DomainXML, DomainXMLUuid}; use crate::libvirt_lib_structures::{DomainState, DomainXML, DomainXMLUuid};
use crate::libvirt_rest_structures::*; use crate::libvirt_rest_structures::*;
use actix::{Actor, Context, Handler, Message}; use actix::{Actor, Context, Handler, Message};
use virt::connect::Connect; use virt::connect::Connect;
use virt::domain::Domain; use virt::domain::Domain;
use virt::sys;
use virt::sys::VIR_DOMAIN_XML_SECURE; use virt::sys::VIR_DOMAIN_XML_SECURE;
pub struct LibVirtActor { pub struct LibVirtActor {
@ -88,3 +89,29 @@ impl Handler<DefineDomainReq> for LibVirtActor {
DomainXMLUuid::parse_from_str(&domain.get_uuid_string()?) DomainXMLUuid::parse_from_str(&domain.get_uuid_string()?)
} }
} }
#[derive(Message)]
#[rtype(result = "anyhow::Result<DomainState>")]
pub struct GetDomainStateReq(pub DomainXMLUuid);
impl Handler<GetDomainStateReq> for LibVirtActor {
type Result = anyhow::Result<DomainState>;
fn handle(&mut self, msg: GetDomainStateReq, _ctx: &mut Self::Context) -> Self::Result {
log::debug!("Get domain state:\n{}", msg.0.as_string());
let domain = Domain::lookup_by_uuid_string(&self.m, &msg.0.as_string())?;
let (state, _) = domain.get_state()?;
Ok(match state {
sys::VIR_DOMAIN_NOSTATE => DomainState::NoState,
sys::VIR_DOMAIN_RUNNING => DomainState::Running,
sys::VIR_DOMAIN_BLOCKED => DomainState::Blocked,
sys::VIR_DOMAIN_PAUSED => DomainState::Paused,
sys::VIR_DOMAIN_SHUTDOWN => DomainState::Shutdown,
sys::VIR_DOMAIN_SHUTOFF => DomainState::Shutoff,
sys::VIR_DOMAIN_CRASHED => DomainState::Crashed,
sys::VIR_DOMAIN_PMSUSPENDED => DomainState::PowerManagementSuspended,
_ => DomainState::Other,
})
}
}

View File

@ -1,8 +1,15 @@
use crate::controllers::{HttpResult, LibVirtReq}; use crate::controllers::{HttpResult, LibVirtReq};
use crate::libvirt_lib_structures::DomainXMLUuid; use crate::libvirt_lib_structures::{DomainState, DomainXMLUuid};
use crate::libvirt_rest_structures::VMInfo; use crate::libvirt_rest_structures::VMInfo;
use actix_web::{web, HttpResponse}; use actix_web::{web, HttpResponse};
#[derive(serde::Serialize)]
struct VMInfoAndState {
#[serde(flatten)]
info: VMInfo,
state: DomainState,
}
/// Create a new VM /// Create a new VM
pub async fn create(client: LibVirtReq, req: web::Json<VMInfo>) -> HttpResult { pub async fn create(client: LibVirtReq, req: web::Json<VMInfo>) -> HttpResult {
let domain = match req.0.to_domain() { let domain = match req.0.to_domain() {
@ -32,5 +39,10 @@ pub async fn get_single(client: LibVirtReq, id: web::Path<SingleVMUUidReq>) -> H
} }
}; };
Ok(HttpResponse::Ok().json(VMInfo::from_domain(info)?)) let state = client.get_domain_state(id.uid).await?;
Ok(HttpResponse::Ok().json(VMInfoAndState {
info: VMInfo::from_domain(info)?,
state,
}))
} }

View File

@ -1,6 +1,6 @@
use crate::actors::libvirt_actor; use crate::actors::libvirt_actor;
use crate::actors::libvirt_actor::LibVirtActor; use crate::actors::libvirt_actor::LibVirtActor;
use crate::libvirt_lib_structures::{DomainXML, DomainXMLUuid}; use crate::libvirt_lib_structures::{DomainState, DomainXML, DomainXMLUuid};
use crate::libvirt_rest_structures::HypervisorInfo; use crate::libvirt_rest_structures::HypervisorInfo;
use actix::Addr; use actix::Addr;
@ -22,4 +22,9 @@ impl LibVirtClient {
pub async fn update_domain(&self, xml: DomainXML) -> anyhow::Result<DomainXMLUuid> { pub async fn update_domain(&self, xml: DomainXML) -> anyhow::Result<DomainXMLUuid> {
self.0.send(libvirt_actor::DefineDomainReq(xml)).await? self.0.send(libvirt_actor::DefineDomainReq(xml)).await?
} }
/// Get the state of a domain
pub async fn get_domain_state(&self, id: DomainXMLUuid) -> anyhow::Result<DomainState> {
self.0.send(libvirt_actor::GetDomainStateReq(id)).await?
}
} }

View File

@ -73,3 +73,17 @@ pub struct DomainXML {
pub on_reboot: String, pub on_reboot: String,
pub on_crash: String, pub on_crash: String,
} }
/// Domain state
#[derive(serde::Serialize, Debug, Copy, Clone)]
pub enum DomainState {
NoState,
Running,
Blocked,
Paused,
Shutdown,
Shutoff,
Crashed,
PowerManagementSuspended,
Other,
}