use crate::libvirt_lib_structures::XMLUuid; /// OS information #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "os")] pub struct OSXML { #[serde(rename = "@firmware", default)] pub firmware: String, pub r#type: OSTypeXML, pub loader: Option, } /// OS Type information #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "os")] pub struct OSTypeXML { #[serde(rename = "@arch")] pub arch: String, #[serde(rename = "@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 = "@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 = "@address")] pub address: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "source")] pub struct NetIntSourceXML { #[serde(rename = "@network")] pub network: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "model")] pub struct NetIntModelXML { #[serde(rename = "@type")] pub r#type: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "filterref")] pub struct NetIntFilterParameterXML { #[serde(rename = "@name")] pub name: String, #[serde(rename = "@value")] pub value: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "filterref")] pub struct NetIntfilterRefXML { #[serde(rename = "@filter")] pub filter: String, #[serde(rename = "parameter", default)] pub parameters: Vec, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "interface")] pub struct DomainNetInterfaceXML { #[serde(rename = "@type")] pub r#type: String, pub mac: NetMacAddress, #[serde(skip_serializing_if = "Option::is_none")] pub source: Option, #[serde(skip_serializing_if = "Option::is_none")] pub model: Option, #[serde(skip_serializing_if = "Option::is_none")] pub filterref: Option, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "input")] pub struct DomainInputXML { #[serde(rename = "@type")] pub r#type: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "backend")] pub struct TPMBackendXML { #[serde(rename = "@type")] pub r#type: String, #[serde(rename = "@version")] pub r#version: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "tpm")] pub struct TPMDeviceXML { #[serde(rename = "@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, /// Graphics (used for VNC) #[serde(skip_serializing_if = "Option::is_none")] pub video: Option, /// Disks (used for storage) #[serde(default, rename = "disk", skip_serializing_if = "Vec::is_empty")] pub disks: Vec, /// Networks cards #[serde(default, rename = "interface", skip_serializing_if = "Vec::is_empty")] pub net_interfaces: Vec, /// Input devices #[serde(default, rename = "input", skip_serializing_if = "Vec::is_empty")] pub inputs: Vec, /// TPM device #[serde(skip_serializing_if = "Option::is_none")] pub tpm: Option, } /// Graphics information #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "graphics")] pub struct GraphicsXML { #[serde(rename = "@type")] pub r#type: String, #[serde(rename = "@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 = "@type")] pub r#type: String, } /// Disk information #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "disk")] pub struct DiskXML { #[serde(rename = "@type")] pub r#type: String, #[serde(rename = "@device")] pub r#device: String, pub driver: DiskDriverXML, pub source: DiskSourceXML, pub target: DiskTargetXML, #[serde(skip_serializing_if = "Option::is_none")] pub readonly: Option, pub boot: DiskBootXML, #[serde(skip_serializing_if = "Option::is_none")] pub address: Option, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "driver")] pub struct DiskDriverXML { #[serde(rename = "@name")] pub name: String, #[serde(rename = "@type")] pub r#type: String, #[serde(default, rename = "@cache")] pub r#cache: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "source")] pub struct DiskSourceXML { #[serde(rename = "@file")] pub file: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "target")] pub struct DiskTargetXML { #[serde(rename = "@dev")] pub dev: String, #[serde(rename = "@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 = "@order")] pub order: String, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "address")] pub struct DiskAddressXML { #[serde(rename = "@type")] pub r#type: String, #[serde( default, skip_serializing_if = "Option::is_none", rename = "@controller" )] pub r#controller: Option, #[serde(rename = "@bus")] pub r#bus: String, #[serde(default, skip_serializing_if = "Option::is_none", rename = "@target")] pub r#target: Option, #[serde(default, skip_serializing_if = "Option::is_none", rename = "@unit")] pub r#unit: Option, } /// Domain RAM information #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "memory")] pub struct DomainMemoryXML { #[serde(rename = "@unit")] pub unit: String, #[serde(rename = "$value")] pub memory: usize, } #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "topology")] pub struct DomainCPUTopology { #[serde(rename = "@sockets")] pub sockets: usize, #[serde(rename = "@cores")] pub cores: usize, #[serde(rename = "@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 = "@mode")] pub mode: String, pub topology: Option, } /// Domain information, see https://libvirt.org/formatdomain.html #[derive(serde::Serialize, serde::Deserialize)] #[serde(rename = "domain")] pub struct DomainXML { /// Domain type (kvm) #[serde(rename = "@type")] pub r#type: String, pub name: String, pub uuid: Option, pub genid: Option, pub title: Option, pub description: Option, 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 { /// Decode Domain structure from XML definition pub fn parse_xml(xml: &str) -> anyhow::Result { Ok(quick_xml::de::from_str(xml)?) } /// Turn this domain into its XML definition pub fn as_xml(&self) -> anyhow::Result { Ok(quick_xml::se::to_string(self)?) } } /// Domain state #[derive(serde::Serialize, Debug, Copy, Clone)] pub enum DomainState { NoState, Running, Blocked, Paused, Shutdown, Shutoff, Crashed, PowerManagementSuspended, Other, }