Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions bin/propolis-server/src/lib/spec/api_spec_latest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ pub(crate) fn latest_to_spec_builder(
value: latest::instance_spec::InstanceSpec,
) -> Result<SpecBuilder, ApiSpecError> {
let mut builder = SpecBuilder::with_instance_spec_board(value.board)?;

if let Some(smbios) = value.smbios {
builder.set_smbios_type1_input(smbios);
}

let mut devices: Vec<(SpecKey, latest::instance_spec::Component)> = vec![];
let mut boot_settings = None;
let mut storage_backends: BTreeMap<SpecKey, StorageBackend> =
Expand Down Expand Up @@ -216,3 +221,49 @@ pub(crate) fn latest_to_spec_builder(

Ok(builder)
}

#[cfg(test)]
mod test {
use super::*;
use latest::components::board::{
Board, Chipset, Cpuid, GuestHypervisorInterface, I440Fx,
};
use latest::instance_spec::{CpuidVendor, SmbiosType1Input};

// Regression test: the SMBIOS type 1 input must survive conversion
// from the API instance spec to the internal spec. The conversion rework in
// #1178 dropped it, leaving guests with default type 1 contents.
#[test]
fn smbios_type1_input_preserved() {
let api_spec = latest::instance_spec::InstanceSpec {
board: Board {
cpus: 4,
memory_mb: 512,
chipset: Chipset::I440Fx(I440Fx { enable_pcie: false }),
guest_hv_interface: GuestHypervisorInterface::Bhyve,
// Explicit values keep the builder from querying bhyve for
// its default guest CPUID set, which needs VMM device access
// the test runner may lack.
cpuid: Some(Cpuid {
entries: vec![],
vendor: CpuidVendor::Amd,
}),
},
components: Default::default(),
smbios: Some(SmbiosType1Input {
manufacturer: "a4x2".to_string(),
product_name: "913-0000019".to_string(),
serial_number: "2FAKE000".to_string(),
version: 2,
}),
};

let spec = latest_to_spec_builder(api_spec).unwrap().finish();
let smbios =
spec.smbios_type1_input.expect("SMBIOS type 1 input preserved");
assert_eq!(smbios.manufacturer, "a4x2");
assert_eq!(smbios.product_name, "913-0000019");
assert_eq!(smbios.serial_number, "2FAKE000");
assert_eq!(smbios.version, 2);
}
}
7 changes: 6 additions & 1 deletion bin/propolis-server/src/lib/spec/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use propolis_api_types::instance_spec::{
board::Board as InstanceSpecBoard,
devices::{PciPciBridge, SerialPortNumber},
},
PciPath, SpecKey,
PciPath, SmbiosType1Input, SpecKey,
};
use thiserror::Error;

Expand Down Expand Up @@ -391,6 +391,11 @@ impl SpecBuilder {
Ok(self)
}

/// Sets the SMBIOS type 1 table contents to expose to the guest.
pub fn set_smbios_type1_input(&mut self, input: SmbiosType1Input) {
self.spec.smbios_type1_input = Some(input);
}

/// Yields the completed spec, consuming the builder.
pub fn finish(self) -> super::Spec {
self.spec
Expand Down
Loading