Can create NAT networks

This commit is contained in:
2023-12-07 20:03:11 +01:00
parent 5f0f56a9f9
commit 54a3013c59
7 changed files with 210 additions and 12 deletions

View File

@ -107,17 +107,24 @@ impl Handler<DefineDomainReq> for LibVirtActor {
type Result = anyhow::Result<XMLUuid>;
fn handle(&mut self, mut msg: DefineDomainReq, _ctx: &mut Self::Context) -> Self::Result {
// A issue with the disks definition serialization needs them to be serialized aside
let mut disks_xml = Vec::with_capacity(msg.0.devices.disks.len());
// A issue with the disks & network interface definition serialization needs them to be serialized aside
let mut devices_xml = Vec::with_capacity(msg.0.devices.disks.len());
for disk in msg.0.devices.disks {
let disk_xml = serde_xml_rs::to_string(&disk)?;
let start_offset = disk_xml.find("<disk").unwrap();
disks_xml.push(disk_xml[start_offset..].to_string());
devices_xml.push(disk_xml[start_offset..].to_string());
}
for network in msg.0.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());
}
msg.0.devices.disks = vec![];
msg.0.devices.net_interfaces = vec![];
let mut xml = serde_xml_rs::to_string(&msg.0)?;
let disks_xml = disks_xml.join("\n");
let disks_xml = devices_xml.join("\n");
xml = xml.replacen("<devices>", &format!("<devices>{disks_xml}"), 1);
log::debug!("Define domain:\n{}", xml);

View File

@ -63,6 +63,13 @@ pub struct FeaturesXML {
#[serde(rename = "acpi")]
pub struct ACPIXML {}
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename = "interface")]
pub struct DomainNetInterfaceXML {
#[serde(rename(serialize = "@type"))]
pub r#type: String,
}
/// Devices information
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename = "devices")]
@ -74,6 +81,10 @@ pub struct DevicesXML {
/// 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>,
}
/// Screen information
@ -276,7 +287,7 @@ pub struct NetworkDNSXML {
/// Network DNS information
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[serde(rename = "fowarder")]
#[serde(rename = "forwarder")]
pub struct NetworkDNSForwarderXML {
/// Address of the DNS server
#[serde(rename(serialize = "@addr"))]

View File

@ -2,10 +2,10 @@ use crate::app_config::AppConfig;
use crate::constants;
use crate::libvirt_lib_structures::{
DevicesXML, DiskBootXML, DiskDriverXML, DiskReadOnlyXML, DiskSourceXML, DiskTargetXML, DiskXML,
DomainCPUTopology, DomainCPUXML, DomainMemoryXML, DomainVCPUXML, DomainXML, FeaturesXML,
GraphicsXML, NetworkDHCPRangeXML, NetworkDHCPXML, NetworkDNSForwarderXML, NetworkDNSXML,
NetworkDomainXML, NetworkForwardXML, NetworkIPXML, NetworkXML, OSLoaderXML, OSTypeXML, XMLUuid,
ACPIXML, OSXML,
DomainCPUTopology, DomainCPUXML, DomainMemoryXML, DomainNetInterfaceXML, DomainVCPUXML,
DomainXML, FeaturesXML, GraphicsXML, NetworkDHCPRangeXML, NetworkDHCPXML,
NetworkDNSForwarderXML, NetworkDNSXML, NetworkDomainXML, NetworkForwardXML, NetworkIPXML,
NetworkXML, OSLoaderXML, OSTypeXML, XMLUuid, ACPIXML, OSXML,
};
use crate::libvirt_rest_structures::LibVirtStructError::StructureExtraction;
use crate::utils::disks_utils::Disk;
@ -64,6 +64,13 @@ pub enum VMArchitecture {
X86_64,
}
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(tag = "type")]
pub enum Network {
UserspaceSLIRPStack,
// TODO : complete network types
}
#[derive(serde::Serialize, serde::Deserialize)]
pub struct VMInfo {
/// VM name (alphanumeric characters only)
@ -84,7 +91,8 @@ pub struct VMInfo {
pub iso_file: Option<String>,
/// Storage - https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-virtualization-virtualized_block_devices-adding_storage_devices_to_guests#sect-Virtualization-Adding_storage_devices_to_guests-Adding_file_based_storage_to_a_guest
pub disks: Vec<Disk>,
// TODO : network interfaces
/// Network cards
pub networks: Vec<Network>,
}
impl VMInfo {
@ -213,6 +221,15 @@ impl VMInfo {
})
}
let mut networks = vec![];
for n in self.networks {
networks.push(match n {
Network::UserspaceSLIRPStack => DomainNetInterfaceXML {
r#type: "user".to_string(),
},
})
}
Ok(DomainXML {
r#type: "kvm".to_string(),
name: self.name,
@ -245,6 +262,7 @@ impl VMInfo {
devices: DevicesXML {
graphics: vnc_graphics,
disks,
net_interfaces: networks,
},
memory: DomainMemoryXML {
@ -319,6 +337,18 @@ impl VMInfo {
.filter(|d| d.device == "disk")
.map(|d| Disk::load_from_file(&d.source.file).unwrap())
.collect(),
networks: domain
.devices
.net_interfaces
.iter()
.map(|d| match d.r#type.as_str() {
"user" => Ok(Network::UserspaceSLIRPStack),
a => Err(LibVirtStructError::DomainExtraction(format!(
"Unknown network interface type: {a}! "
))),
})
.collect::<Result<Vec<_>, _>>()?,
})
}
}