Refacto structures definition
This commit is contained in:
virtweb_backend/src
actors
controllers
libvirt_client.rslibvirt_lib_structures.rslibvirt_lib_structures
libvirt_rest_structures.rslibvirt_rest_structures
utils
354
virtweb_backend/src/libvirt_lib_structures/domain.rs
Normal file
354
virtweb_backend/src/libvirt_lib_structures/domain.rs
Normal file
@ -0,0 +1,354 @@
|
||||
use crate::libvirt_lib_structures::XMLUuid;
|
||||
|
||||
/// OS information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "os")]
|
||||
pub struct OSXML {
|
||||
#[serde(rename(serialize = "@firmware"), default)]
|
||||
pub firmware: String,
|
||||
pub r#type: OSTypeXML,
|
||||
pub loader: Option<OSLoaderXML>,
|
||||
}
|
||||
|
||||
/// OS Type information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "os")]
|
||||
pub struct OSTypeXML {
|
||||
#[serde(rename(serialize = "@arch"))]
|
||||
pub arch: String,
|
||||
#[serde(rename(serialize = "@machine"))]
|
||||
pub machine: String,
|
||||
#[serde(rename = "$value")]
|
||||
pub body: String,
|
||||
}
|
||||
|
||||
/// OS Loader information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "loader")]
|
||||
pub struct OSLoaderXML {
|
||||
#[serde(rename(serialize = "@secure"))]
|
||||
pub secure: String,
|
||||
}
|
||||
|
||||
/// Hypervisor features
|
||||
#[derive(serde::Serialize, serde::Deserialize, Default)]
|
||||
#[serde(rename = "features")]
|
||||
pub struct FeaturesXML {
|
||||
pub acpi: ACPIXML,
|
||||
}
|
||||
|
||||
/// ACPI feature
|
||||
#[derive(serde::Serialize, serde::Deserialize, Default)]
|
||||
#[serde(rename = "acpi")]
|
||||
pub struct ACPIXML {}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "mac")]
|
||||
pub struct NetMacAddress {
|
||||
#[serde(rename(serialize = "@address"))]
|
||||
pub address: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "source")]
|
||||
pub struct NetIntSourceXML {
|
||||
#[serde(rename(serialize = "@network"))]
|
||||
pub network: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "model")]
|
||||
pub struct NetIntModelXML {
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "interface")]
|
||||
pub struct DomainNetInterfaceXML {
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
pub mac: NetMacAddress,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub source: Option<NetIntSourceXML>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub model: Option<NetIntModelXML>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "input")]
|
||||
pub struct DomainInputXML {
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "backend")]
|
||||
pub struct TPMBackendXML {
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
|
||||
#[serde(rename(serialize = "@version"))]
|
||||
pub r#version: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "tpm")]
|
||||
pub struct TPMDeviceXML {
|
||||
#[serde(rename(serialize = "@model"))]
|
||||
pub model: String,
|
||||
pub backend: TPMBackendXML,
|
||||
}
|
||||
|
||||
/// Devices information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "devices")]
|
||||
pub struct DevicesXML {
|
||||
/// Graphics (used for VNC)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub graphics: Option<GraphicsXML>,
|
||||
|
||||
/// Graphics (used for VNC)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub video: Option<VideoXML>,
|
||||
|
||||
/// Disks (used for storage)
|
||||
#[serde(default, rename = "disk", skip_serializing_if = "Vec::is_empty")]
|
||||
pub disks: Vec<DiskXML>,
|
||||
|
||||
/// Networks cards
|
||||
#[serde(default, rename = "interface", skip_serializing_if = "Vec::is_empty")]
|
||||
pub net_interfaces: Vec<DomainNetInterfaceXML>,
|
||||
|
||||
/// Input devices
|
||||
#[serde(default, rename = "input", skip_serializing_if = "Vec::is_empty")]
|
||||
pub inputs: Vec<DomainInputXML>,
|
||||
|
||||
/// TPM device
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub tpm: Option<TPMDeviceXML>,
|
||||
}
|
||||
|
||||
/// Graphics information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "graphics")]
|
||||
pub struct GraphicsXML {
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
#[serde(rename(serialize = "@socket"))]
|
||||
pub socket: String,
|
||||
}
|
||||
|
||||
/// Video device information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "video")]
|
||||
pub struct VideoXML {
|
||||
pub model: VideoModelXML,
|
||||
}
|
||||
|
||||
/// Video model device information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "model")]
|
||||
pub struct VideoModelXML {
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
}
|
||||
|
||||
/// Disk information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "disk")]
|
||||
pub struct DiskXML {
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
#[serde(rename(serialize = "@device"))]
|
||||
pub r#device: String,
|
||||
|
||||
pub driver: DiskDriverXML,
|
||||
pub source: DiskSourceXML,
|
||||
pub target: DiskTargetXML,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub readonly: Option<DiskReadOnlyXML>,
|
||||
pub boot: DiskBootXML,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub address: Option<DiskAddressXML>,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "driver")]
|
||||
pub struct DiskDriverXML {
|
||||
#[serde(rename(serialize = "@name"))]
|
||||
pub name: String,
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
#[serde(default, rename(serialize = "@cache"))]
|
||||
pub r#cache: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "source")]
|
||||
pub struct DiskSourceXML {
|
||||
#[serde(rename(serialize = "@file"))]
|
||||
pub file: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "target")]
|
||||
pub struct DiskTargetXML {
|
||||
#[serde(rename(serialize = "@dev"))]
|
||||
pub dev: String,
|
||||
#[serde(rename(serialize = "@bus"))]
|
||||
pub bus: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "readonly")]
|
||||
pub struct DiskReadOnlyXML {}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "boot")]
|
||||
pub struct DiskBootXML {
|
||||
#[serde(rename(serialize = "@order"))]
|
||||
pub order: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "address")]
|
||||
pub struct DiskAddressXML {
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
rename(serialize = "@controller")
|
||||
)]
|
||||
pub r#controller: Option<String>,
|
||||
#[serde(rename(serialize = "@bus"))]
|
||||
pub r#bus: String,
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
rename(serialize = "@target")
|
||||
)]
|
||||
pub r#target: Option<String>,
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
rename(serialize = "@unit")
|
||||
)]
|
||||
pub r#unit: Option<String>,
|
||||
}
|
||||
|
||||
/// Domain RAM information
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "memory")]
|
||||
pub struct DomainMemoryXML {
|
||||
#[serde(rename(serialize = "@unit"))]
|
||||
pub unit: String,
|
||||
|
||||
#[serde(rename = "$value")]
|
||||
pub memory: usize,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "topology")]
|
||||
pub struct DomainCPUTopology {
|
||||
#[serde(rename(serialize = "@sockets"))]
|
||||
pub sockets: usize,
|
||||
#[serde(rename(serialize = "@cores"))]
|
||||
pub cores: usize,
|
||||
#[serde(rename(serialize = "@threads"))]
|
||||
pub threads: usize,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "cpu")]
|
||||
pub struct DomainVCPUXML {
|
||||
#[serde(rename = "$value")]
|
||||
pub body: usize,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "cpu")]
|
||||
pub struct DomainCPUXML {
|
||||
#[serde(rename(serialize = "@mode"))]
|
||||
pub mode: String,
|
||||
pub topology: Option<DomainCPUTopology>,
|
||||
}
|
||||
|
||||
/// Domain information, see https://libvirt.org/formatdomain.html
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename = "domain")]
|
||||
pub struct DomainXML {
|
||||
/// Domain type (kvm)
|
||||
#[serde(rename(serialize = "@type"))]
|
||||
pub r#type: String,
|
||||
|
||||
pub name: String,
|
||||
pub uuid: Option<XMLUuid>,
|
||||
pub genid: Option<uuid::Uuid>,
|
||||
pub title: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub os: OSXML,
|
||||
#[serde(default)]
|
||||
pub features: FeaturesXML,
|
||||
pub devices: DevicesXML,
|
||||
|
||||
/// The maximum allocation of memory for the guest at boot time
|
||||
pub memory: DomainMemoryXML,
|
||||
|
||||
/// Number of vCPU
|
||||
pub vcpu: DomainVCPUXML,
|
||||
|
||||
/// CPU information
|
||||
pub cpu: DomainCPUXML,
|
||||
|
||||
pub on_poweroff: String,
|
||||
pub on_reboot: String,
|
||||
pub on_crash: String,
|
||||
}
|
||||
|
||||
impl DomainXML {
|
||||
/// Turn this domain into its XML definition
|
||||
pub fn into_xml(mut self) -> anyhow::Result<String> {
|
||||
// A issue with the disks & network interface definition serialization needs them to be serialized aside
|
||||
let mut devices_xml = Vec::with_capacity(self.devices.disks.len());
|
||||
for disk in self.devices.disks {
|
||||
let disk_xml = serde_xml_rs::to_string(&disk)?;
|
||||
let start_offset = disk_xml.find("<disk").unwrap();
|
||||
devices_xml.push(disk_xml[start_offset..].to_string());
|
||||
}
|
||||
for network in self.devices.net_interfaces {
|
||||
let network_xml = serde_xml_rs::to_string(&network)?;
|
||||
let start_offset = network_xml.find("<interface").unwrap();
|
||||
devices_xml.push(network_xml[start_offset..].to_string());
|
||||
}
|
||||
for input in self.devices.inputs {
|
||||
let input_xml = serde_xml_rs::to_string(&input)?;
|
||||
let start_offset = input_xml.find("<input").unwrap();
|
||||
devices_xml.push(input_xml[start_offset..].to_string());
|
||||
}
|
||||
|
||||
self.devices.disks = vec![];
|
||||
self.devices.net_interfaces = vec![];
|
||||
self.devices.inputs = vec![];
|
||||
|
||||
let mut xml = serde_xml_rs::to_string(&self)?;
|
||||
let disks_xml = devices_xml.join("\n");
|
||||
xml = xml.replacen("<devices>", &format!("<devices>{disks_xml}"), 1);
|
||||
Ok(xml)
|
||||
}
|
||||
}
|
||||
|
||||
/// Domain state
|
||||
#[derive(serde::Serialize, Debug, Copy, Clone)]
|
||||
pub enum DomainState {
|
||||
NoState,
|
||||
Running,
|
||||
Blocked,
|
||||
Paused,
|
||||
Shutdown,
|
||||
Shutoff,
|
||||
Crashed,
|
||||
PowerManagementSuspended,
|
||||
Other,
|
||||
}
|
Reference in New Issue
Block a user