nzr-virt: smbios strings support

This commit is contained in:
snow flurry 2024-08-14 23:00:36 -07:00
parent d10d98de96
commit b350e73b8a
3 changed files with 102 additions and 0 deletions

View file

@ -113,6 +113,14 @@ impl DomainBuilder {
self
}
pub fn smbios(mut self, data: Sysinfo) -> Self {
self.domain.os.smbios = Some(SmbiosInfo {
mode: "sysinfo".into(),
});
self.domain.sysinfo = Some(data);
self
}
pub fn cpu_topology(mut self, sockets: u8, dies: u8, cores: u8, threads: u8) -> Self {
self.domain.cpu.topology = CpuTopology {
sockets,

View file

@ -25,6 +25,7 @@ pub struct Domain {
pub cpu: Cpu,
pub devices: DeviceList,
pub os: OsData,
pub sysinfo: Option<Sysinfo>,
pub on_poweroff: Option<PowerAction>,
pub on_reboot: Option<PowerAction>,
pub on_crash: Option<PowerAction>,
@ -68,7 +69,9 @@ impl Default for Domain {
useserial: "yes".to_owned(),
reboot_timeout: 0,
},
..Default::default()
},
sysinfo: None,
on_poweroff: None,
on_reboot: None,
on_crash: None,
@ -358,6 +361,12 @@ impl Default for OsType {
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct SmbiosInfo {
#[serde(rename = "@mode")]
mode: String,
}
#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct OsData {
@ -365,6 +374,7 @@ pub struct OsData {
r#type: OsType,
// we will not be doing PV, no <bootloader>/<kernel>/<initrd>/etc
bios: BiosData,
smbios: Option<SmbiosInfo>,
}
impl Default for OsData {
@ -378,6 +388,7 @@ impl Default for OsData {
useserial: "yes".to_owned(),
reboot_timeout: 0,
},
smbios: None,
}
}
}
@ -477,6 +488,75 @@ pub struct Cpu {
topology: CpuTopology,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct InfoEntry {
#[serde(rename = "@name")]
name: Option<String>,
#[serde(rename = "$value")]
value: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct InfoMap {
entry: Vec<InfoEntry>,
}
impl InfoMap {
pub fn new() -> Self {
Self { entry: Vec::new() }
}
pub fn push(&mut self, name: impl Into<String>, value: impl Into<String>) -> &mut Self {
self.entry.push(InfoEntry {
name: Some(name.into()),
value: value.into(),
});
self
}
}
impl Default for InfoMap {
fn default() -> Self {
Self::new()
}
}
#[skip_serializing_none]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Sysinfo {
#[serde(rename = "@type")]
r#type: String,
bios: Option<InfoMap>,
system: Option<InfoMap>,
base_board: Option<InfoMap>,
chassis: Option<InfoMap>,
oem_strings: Option<InfoMap>,
}
impl Sysinfo {
pub fn new() -> Self {
Self {
r#type: "smbios".into(),
bios: None,
system: None,
base_board: None,
chassis: None,
oem_strings: None,
}
}
pub fn system(&mut self, info: InfoMap) {
self.system = Some(info);
}
}
impl Default for Sysinfo {
fn default() -> Self {
Self::new()
}
}
// =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^= =^..^=
#[skip_serializing_none]

View file

@ -47,12 +47,25 @@ fn domain_serde() {
<boot dev="hd"/>
<type arch="x86_64" machine="pc-i440fx-5.2">hvm</type>
<bios useserial="yes" rebootTimeout="0"/>
<smbios mode="sysinfo"/>
</os>
<sysinfo type="smbios">
<system>
<entry name="serial">hello!</entry>
</system>
</sysinfo>
</domain>"#
.unprettify();
println!("Serializing domain...");
let mac = MacAddr::new(0x02, 0x0b, 0xee, 0xca, 0xfe, 0x42);
let uuid = uuid!("9a8f2611-a976-4d06-ac91-2750ac3462b3");
let sysinfo = {
let mut system_map = InfoMap::new();
system_map.push("serial", "hello!");
let mut sysinfo = Sysinfo::new();
sysinfo.system(system_map);
sysinfo
};
let domain = DomainBuilder::default()
.name("test-vm")
.uuid(uuid)
@ -62,6 +75,7 @@ fn domain_serde() {
.target("sda", "virtio")
})
.net_device(|net| net.with_bridge("virbr0").mac_addr(mac))
.smbios(sysinfo)
.build();
let dom_xml = quick_xml::se::to_string(&domain).unwrap();
println!("{}", dom_xml);