diff --git a/bin/mock-server/src/lib/lib.rs b/bin/mock-server/src/lib/lib.rs index f450939bf..0c14738e7 100644 --- a/bin/mock-server/src/lib/lib.rs +++ b/bin/mock-server/src/lib/lib.rs @@ -232,8 +232,6 @@ async fn instance_get( let instance_info = api::Instance { properties: instance.properties.clone(), state: instance.state, - disks: vec![], - nics: vec![], }; Ok(HttpResponseOk(api::InstanceGetResponse { instance: instance_info })) } diff --git a/bin/propolis-cli/src/main.rs b/bin/propolis-cli/src/main.rs index 4cf9ac85d..ba00f0a87 100644 --- a/bin/propolis-cli/src/main.rs +++ b/bin/propolis-cli/src/main.rs @@ -15,7 +15,7 @@ use anyhow::{anyhow, Context}; use clap::{Parser, Subcommand}; use futures::{future, SinkExt}; use newtype_uuid::{GenericUuid, TypedUuid, TypedUuidKind, TypedUuidTag}; -use propolis_client::types::InstanceMetadata; +use propolis_client::types::{InstanceMetadata, VersionedInstanceSpec}; use slog::{o, Drain, Level, Logger}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio_tungstenite::tungstenite::{ @@ -253,16 +253,12 @@ async fn new_instance( name, description: "propolis-cli generated instance".to_string(), metadata, - // TODO: Use real UUID - image_id: Uuid::default(), - // TODO: Use real UUID - bootrom_id: Uuid::default(), - memory, - vcpus, }; let request = InstanceEnsureRequest { properties, + vcpus, + memory, // TODO: Allow specifying NICs nics: vec![], disks, @@ -504,17 +500,20 @@ async fn migrate_instance( ) -> anyhow::Result<()> { // Grab the instance details let src_instance = - src_client.instance_get().send().await.with_context(|| { + src_client.instance_spec_get().send().await.with_context(|| { anyhow!("failed to get src instance properties") })?; - let src_uuid = src_instance.instance.properties.id; + let src_uuid = src_instance.properties.id; + let VersionedInstanceSpec::V0(spec) = &src_instance.spec; let request = InstanceEnsureRequest { properties: InstanceProperties { // Use a new ID for the destination instance we're creating id: dst_uuid, - ..src_instance.instance.properties.clone() + ..src_instance.properties.clone() }, + vcpus: spec.board.cpus, + memory: spec.board.memory_mb, // TODO: Handle migrating NICs nics: vec![], disks, diff --git a/bin/propolis-server/src/lib/initializer.rs b/bin/propolis-server/src/lib/initializer.rs index e2b308957..5e8069b7d 100644 --- a/bin/propolis-server/src/lib/initializer.rs +++ b/bin/propolis-server/src/lib/initializer.rs @@ -191,6 +191,7 @@ pub struct MachineInitializer<'a> { pub(crate) producer_registry: Option, pub(crate) state: MachineInitializerState, pub(crate) kstat_sampler: Option, + pub(crate) stats_vm: crate::stats::VirtualMachine, } impl<'a> MachineInitializer<'a> { @@ -744,7 +745,7 @@ impl<'a> MachineInitializer<'a> { track_network_interface_kstats( &self.log, sampler, - self.properties, + &self.stats_vm, interface_ids.unwrap(), ) .await @@ -1031,15 +1032,15 @@ impl<'a> MachineInitializer<'a> { // unknown proc_upgrade: 0x2, // make core and thread counts equal for now - core_count: self.properties.vcpus, - core_enabled: self.properties.vcpus, - thread_count: self.properties.vcpus, + core_count: self.spec.board.cpus, + core_enabled: self.spec.board.cpus, + thread_count: self.spec.board.cpus, proc_characteristics: type4::Characteristics::IS_64_BIT | type4::Characteristics::MULTI_CORE, ..Default::default() }; - let memsize_bytes = (self.properties.memory as usize) * MB; + let memsize_bytes = (self.spec.board.memory_mb as usize) * MB; let mut smb_type16 = smbios::table::Type16 { location: type16::Location::SystemBoard, array_use: type16::ArrayUse::System, @@ -1228,7 +1229,7 @@ impl<'a> MachineInitializer<'a> { self.devices.insert(format!("vcpu-{}", vcpu.id), vcpu.clone()); } if let Some(sampler) = self.kstat_sampler.as_ref() { - track_vcpu_kstats(&self.log, sampler, self.properties).await; + track_vcpu_kstats(&self.log, sampler, &self.stats_vm).await; } Ok(()) } diff --git a/bin/propolis-server/src/lib/server.rs b/bin/propolis-server/src/lib/server.rs index bb6e894ba..a5e669cb0 100644 --- a/bin/propolis-server/src/lib/server.rs +++ b/bin/propolis-server/src/lib/server.rs @@ -117,7 +117,7 @@ fn instance_spec_from_request( request: &api::InstanceEnsureRequest, toml_config: &VmTomlConfig, ) -> Result { - let mut spec_builder = SpecBuilder::new(&request.properties); + let mut spec_builder = SpecBuilder::new(request.vcpus, request.memory); spec_builder.add_devices_from_config(toml_config)?; @@ -376,8 +376,6 @@ async fn instance_get( instance: api::Instance { properties: full.properties, state: full.state, - disks: vec![], - nics: vec![], }, }) }) diff --git a/bin/propolis-server/src/lib/spec/builder.rs b/bin/propolis-server/src/lib/spec/builder.rs index 75a3f8ece..1a5dee420 100644 --- a/bin/propolis-server/src/lib/spec/builder.rs +++ b/bin/propolis-server/src/lib/spec/builder.rs @@ -15,7 +15,7 @@ use propolis_api_types::{ }, PciPath, }, - DiskRequest, InstanceProperties, NetworkInterfaceRequest, + DiskRequest, NetworkInterfaceRequest, }; use thiserror::Error; @@ -78,10 +78,10 @@ pub(crate) struct SpecBuilder { } impl SpecBuilder { - pub fn new(properties: &InstanceProperties) -> Self { + pub fn new(cpus: u8, memory_mb: u64) -> Self { let board = Board { - cpus: properties.vcpus, - memory_mb: properties.memory, + cpus, + memory_mb, chipset: Chipset::I440Fx(I440Fx { enable_pcie: false }), }; @@ -455,7 +455,7 @@ mod test { backends::{BlobStorageBackend, VirtioNetworkBackend}, devices::{VirtioDisk, VirtioNic}, }, - InstanceMetadata, Slot, VolumeConstructionRequest, + Slot, VolumeConstructionRequest, }; use uuid::Uuid; @@ -463,28 +463,8 @@ mod test { use super::*; - fn test_metadata() -> InstanceMetadata { - InstanceMetadata { - silo_id: uuid::uuid!("556a67f8-8b14-4659-bd9f-d8f85ecd36bf"), - project_id: uuid::uuid!("75f60038-daeb-4a1d-916a-5fa5b7237299"), - sled_id: uuid::uuid!("43a789ac-a0dd-4e1e-ac33-acdada142faa"), - sled_serial: "some-gimlet".into(), - sled_revision: 1, - sled_model: "abcd".into(), - } - } - fn test_builder() -> SpecBuilder { - SpecBuilder::new(&InstanceProperties { - id: Default::default(), - name: Default::default(), - description: Default::default(), - metadata: test_metadata(), - image_id: Default::default(), - bootrom_id: Default::default(), - memory: 512, - vcpus: 4, - }) + SpecBuilder::new(4, 512) } #[test] diff --git a/bin/propolis-server/src/lib/stats/mod.rs b/bin/propolis-server/src/lib/stats/mod.rs index 0a23d3e84..750825d49 100644 --- a/bin/propolis-server/src/lib/stats/mod.rs +++ b/bin/propolis-server/src/lib/stats/mod.rs @@ -14,7 +14,6 @@ use oximeter::{ }; use oximeter_instruments::kstat::KstatSampler; use oximeter_producer::{Config, Error, Server}; -use propolis_api_types::InstanceProperties; use slog::Logger; use uuid::Uuid; @@ -188,11 +187,10 @@ pub fn start_oximeter_server( /// Create an object that can be used to sample kstat-based metrics. pub(crate) fn create_kstat_sampler( log: &Logger, - properties: &InstanceProperties, spec: &Spec, ) -> Option { let kstat_limit = usize::try_from( - (u32::from(properties.vcpus) * KSTAT_LIMIT_PER_VCPU) + (u32::from(spec.board.cpus) * KSTAT_LIMIT_PER_VCPU) + (spec.nics.len() as u32 * SAMPLE_BUFFER), ) .unwrap(); @@ -216,7 +214,7 @@ pub(crate) fn create_kstat_sampler( pub(crate) async fn track_vcpu_kstats( log: &Logger, _: &KstatSampler, - _: &InstanceProperties, + _: &VirtualMachine, ) { slog::error!(log, "vCPU stats are not supported on this platform"); } @@ -226,13 +224,12 @@ pub(crate) async fn track_vcpu_kstats( pub(crate) async fn track_vcpu_kstats( log: &Logger, sampler: &KstatSampler, - properties: &InstanceProperties, + virtual_machine: &VirtualMachine, ) { - let virtual_machine = VirtualMachine::from(properties); let details = oximeter_instruments::kstat::CollectionDetails::never( VCPU_KSTAT_INTERVAL, ); - if let Err(e) = sampler.add_target(virtual_machine, details).await { + if let Err(e) = sampler.add_target(virtual_machine.clone(), details).await { slog::error!( log, "failed to add VirtualMachine target, \ @@ -247,7 +244,7 @@ pub(crate) async fn track_vcpu_kstats( pub(crate) async fn track_network_interface_kstats( log: &Logger, _: &KstatSampler, - _: &InstanceProperties, + _: &VirtualMachine, _: NetworkInterfaceIds, ) { slog::error!( @@ -261,10 +258,10 @@ pub(crate) async fn track_network_interface_kstats( pub(crate) async fn track_network_interface_kstats( log: &Logger, sampler: &KstatSampler, - properties: &InstanceProperties, + virtual_machine: &VirtualMachine, interface_ids: NetworkInterfaceIds, ) { - let nics = InstanceNetworkInterfaces::new(properties, &interface_ids); + let nics = InstanceNetworkInterfaces::new(virtual_machine, &interface_ids); let details = oximeter_instruments::kstat::CollectionDetails::never( NETWORK_INTERFACE_SAMPLE_INTERVAL, ); diff --git a/bin/propolis-server/src/lib/stats/network_interface.rs b/bin/propolis-server/src/lib/stats/network_interface.rs index b464ce287..6cc3aaa6e 100644 --- a/bin/propolis-server/src/lib/stats/network_interface.rs +++ b/bin/propolis-server/src/lib/stats/network_interface.rs @@ -151,7 +151,7 @@ impl InstanceNetworkInterfaces { /// metrics from. #[cfg(all(not(test), target_os = "illumos"))] pub(crate) fn new( - properties: &propolis_api_types::InstanceProperties, + virtual_machine: &super::VirtualMachine, interface_ids: &NetworkInterfaceIds, ) -> Self { Self { @@ -160,9 +160,9 @@ impl InstanceNetworkInterfaces { // multiple targets in the `to_samples` method and override // this. interface_id: uuid::Uuid::nil(), - instance_id: properties.id, - project_id: properties.metadata.project_id, - silo_id: properties.metadata.silo_id, + instance_id: virtual_machine.target.instance_id, + project_id: virtual_machine.target.project_id, + silo_id: virtual_machine.target.silo_id, }, interface_ids: interface_ids.to_vec(), } diff --git a/bin/propolis-server/src/lib/stats/virtual_machine.rs b/bin/propolis-server/src/lib/stats/virtual_machine.rs index 6a612e4df..75c5ba0ac 100644 --- a/bin/propolis-server/src/lib/stats/virtual_machine.rs +++ b/bin/propolis-server/src/lib/stats/virtual_machine.rs @@ -61,8 +61,11 @@ pub struct VirtualMachine { vm_name: String, } -impl From<&propolis_api_types::InstanceProperties> for VirtualMachine { - fn from(properties: &propolis_api_types::InstanceProperties) -> Self { +impl VirtualMachine { + pub fn new( + n_vcpus: u8, + properties: &propolis_api_types::InstanceProperties, + ) -> Self { Self { target: VirtualMachineTarget { silo_id: properties.metadata.silo_id, @@ -73,7 +76,7 @@ impl From<&propolis_api_types::InstanceProperties> for VirtualMachine { sled_revision: properties.metadata.sled_revision, sled_serial: properties.metadata.sled_serial.clone().into(), }, - n_vcpus: properties.vcpus.into(), + n_vcpus: u32::from(n_vcpus), vm_name: properties.vm_name(), } } diff --git a/bin/propolis-server/src/lib/vm/ensure.rs b/bin/propolis-server/src/lib/vm/ensure.rs index f1983a56e..ff4fec107 100644 --- a/bin/propolis-server/src/lib/vm/ensure.rs +++ b/bin/propolis-server/src/lib/vm/ensure.rs @@ -40,7 +40,7 @@ use crate::{ build_instance, MachineInitializer, MachineInitializerState, }, spec::Spec, - stats::create_kstat_sampler, + stats::{create_kstat_sampler, VirtualMachine}, vm::request_queue::InstanceAutoStart, }; @@ -187,10 +187,10 @@ impl<'a> VmEnsureNotStarted<'a> { state: MachineInitializerState::default(), kstat_sampler: initialize_kstat_sampler( self.log, - properties, self.instance_spec(), options.oximeter_registry.clone(), ), + stats_vm: VirtualMachine::new(spec.board.cpus, properties), }; init.initialize_rom(options.toml_config.bootrom.as_path())?; @@ -205,7 +205,10 @@ impl<'a> VmEnsureNotStarted<'a> { let com1 = Arc::new(init.initialize_uart(&chipset)); let ps2ctrl = init.initialize_ps2(&chipset); init.initialize_qemu_debug_port()?; - init.initialize_qemu_pvpanic(properties.into())?; + init.initialize_qemu_pvpanic(VirtualMachine::new( + self.instance_spec().board.cpus, + properties, + ))?; init.initialize_network_devices(&chipset).await?; #[cfg(not(feature = "omicron-build"))] @@ -378,12 +381,11 @@ impl<'a> VmEnsureActive<'a> { /// Create an object used to sample kstats. fn initialize_kstat_sampler( log: &slog::Logger, - properties: &InstanceProperties, spec: &Spec, producer_registry: Option, ) -> Option { let registry = producer_registry?; - let sampler = create_kstat_sampler(log, properties, spec)?; + let sampler = create_kstat_sampler(log, spec)?; match registry.register_producer(sampler.clone()) { Ok(_) => Some(sampler), diff --git a/bin/propolis-server/src/lib/vm/services.rs b/bin/propolis-server/src/lib/vm/services.rs index 2ed585bb1..31f4a6e02 100644 --- a/bin/propolis-server/src/lib/vm/services.rs +++ b/bin/propolis-server/src/lib/vm/services.rs @@ -14,6 +14,7 @@ use slog::{error, info, Logger}; use crate::{ serial::SerialTaskControlMessage, server::MetricsEndpointConfig, + spec::Spec, stats::{ServerStats, VirtualMachine}, vnc::VncServer, }; @@ -56,16 +57,23 @@ impl VmServices { vm_properties: &InstanceProperties, ensure_options: &super::EnsureOptions, ) -> Self { + let vm_objects = vm_objects.lock_shared().await; let oximeter_state = if let Some(cfg) = &ensure_options.metrics_config { let registry = ensure_options.oximeter_registry.as_ref().expect( "should have a producer registry if metrics are configured", ); - register_oximeter_producer(log, cfg, registry, vm_properties).await + register_oximeter_producer( + log, + cfg, + registry, + vm_objects.instance_spec(), + vm_properties, + ) + .await } else { OximeterState::default() }; - let vm_objects = vm_objects.lock_shared().await; let vnc_server = ensure_options.vnc_server.clone(); if let Some(ramfb) = vm_objects.framebuffer() { vnc_server.attach(vm_objects.ps2ctrl().clone(), ramfb.clone()); @@ -110,10 +118,11 @@ async fn register_oximeter_producer( log: &slog::Logger, cfg: &MetricsEndpointConfig, registry: &ProducerRegistry, + spec: &Spec, vm_properties: &InstanceProperties, ) -> OximeterState { let mut oximeter_state = OximeterState::default(); - let virtual_machine = VirtualMachine::from(vm_properties); + let virtual_machine = VirtualMachine::new(spec.board.cpus, vm_properties); // Create the server itself. // diff --git a/crates/propolis-api-types/src/lib.rs b/crates/propolis-api-types/src/lib.rs index a6de2d547..44bd7a68d 100644 --- a/crates/propolis-api-types/src/lib.rs +++ b/crates/propolis-api-types/src/lib.rs @@ -52,6 +52,12 @@ pub struct InstanceMetadata { pub struct InstanceEnsureRequest { pub properties: InstanceProperties, + /// Number of vCPUs to be allocated to the Instance. + pub vcpus: u8, + + /// Size of memory allocated to the Instance, in MiB. + pub memory: u64, + #[serde(default)] pub nics: Vec, @@ -218,14 +224,6 @@ pub struct InstanceProperties { pub description: String, /// Metadata used to track statistics for this Instance. pub metadata: InstanceMetadata, - /// ID of the image used to initialize this Instance. - pub image_id: Uuid, - /// ID of the bootrom used to initialize this Instance. - pub bootrom_id: Uuid, - /// Size of memory allocated to the Instance, in MiB. - pub memory: u64, - /// Number of vCPUs to be allocated to the Instance. - pub vcpus: u8, } impl InstanceProperties { @@ -239,8 +237,6 @@ impl InstanceProperties { pub struct Instance { pub properties: InstanceProperties, pub state: InstanceState, - pub disks: Vec, - pub nics: Vec, } /// Request a specific range of an Instance's serial console output history. @@ -340,27 +336,6 @@ pub struct Disk { pub interface: DiskType, } -// TODO: Struggling to make this struct derive "JsonSchema" -/* -bitflags! { - #[derive(Deserialize, Serialize)] - pub struct DiskFlags: u32 { - const READ = 0b0000_0001; - const WRITE = 0b0000_0010; - const READ_WRITE = Self::READ.bits | Self::WRITE.bits; - } -} -*/ - -// TODO: Remove this; it's a hack to workaround the above bug. -#[allow(dead_code)] -pub const DISK_FLAG_READ: u32 = 0b0000_0001; -#[allow(dead_code)] -pub const DISK_FLAG_WRITE: u32 = 0b0000_0010; -#[allow(dead_code)] -pub const DISK_FLAG_READ_WRITE: u32 = DISK_FLAG_READ | DISK_FLAG_WRITE; -type DiskFlags = u32; - #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] pub struct DiskRequest { pub name: String, @@ -373,27 +348,6 @@ pub struct DiskRequest { crucible_client_types::VolumeConstructionRequest, } -#[derive(Clone, Deserialize, Serialize, JsonSchema)] -pub struct DiskAttachmentInfo { - pub flags: DiskFlags, - pub slot: u16, -} - -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -pub enum DiskAttachmentState { - Attached(Uuid), - Detached, - Destroyed, - Faulted, -} - -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -pub struct DiskAttachment { - pub generation_id: u64, - pub disk_id: Uuid, - pub state: DiskAttachmentState, -} - /// A stable index which is translated by Propolis /// into a PCI BDF, visible to the guest. #[derive(Copy, Clone, Debug, Deserialize, Serialize, JsonSchema)] @@ -406,19 +360,6 @@ pub struct NetworkInterfaceRequest { pub slot: Slot, } -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -pub struct NetworkInterface { - pub name: String, - pub attachment: NetworkInterfaceAttachmentState, -} - -#[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] -pub enum NetworkInterfaceAttachmentState { - Attached(Slot), - Detached, - Faulted, -} - #[derive(Deserialize, JsonSchema)] pub struct SnapshotRequestPathParams { pub id: Uuid, diff --git a/openapi/propolis-server.json b/openapi/propolis-server.json index 6edd55014..964b630c8 100644 --- a/openapi/propolis-server.json +++ b/openapi/propolis-server.json @@ -1036,53 +1036,6 @@ ], "additionalProperties": false }, - "DiskAttachment": { - "type": "object", - "properties": { - "disk_id": { - "type": "string", - "format": "uuid" - }, - "generation_id": { - "type": "integer", - "format": "uint64", - "minimum": 0 - }, - "state": { - "$ref": "#/components/schemas/DiskAttachmentState" - } - }, - "required": [ - "disk_id", - "generation_id", - "state" - ] - }, - "DiskAttachmentState": { - "oneOf": [ - { - "type": "string", - "enum": [ - "Detached", - "Destroyed", - "Faulted" - ] - }, - { - "type": "object", - "properties": { - "Attached": { - "type": "string", - "format": "uuid" - } - }, - "required": [ - "Attached" - ], - "additionalProperties": false - } - ] - }, "DiskRequest": { "type": "object", "properties": { @@ -1179,18 +1132,6 @@ "Instance": { "type": "object", "properties": { - "disks": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DiskAttachment" - } - }, - "nics": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NetworkInterface" - } - }, "properties": { "$ref": "#/components/schemas/InstanceProperties" }, @@ -1199,8 +1140,6 @@ } }, "required": [ - "disks", - "nics", "properties", "state" ] @@ -1228,6 +1167,12 @@ "$ref": "#/components/schemas/DiskRequest" } }, + "memory": { + "description": "Size of memory allocated to the Instance, in MiB.", + "type": "integer", + "format": "uint64", + "minimum": 0 + }, "migrate": { "nullable": true, "allOf": [ @@ -1245,10 +1190,18 @@ }, "properties": { "$ref": "#/components/schemas/InstanceProperties" + }, + "vcpus": { + "description": "Number of vCPUs to be allocated to the Instance.", + "type": "integer", + "format": "uint8", + "minimum": 0 } }, "required": [ - "properties" + "memory", + "properties", + "vcpus" ] }, "InstanceEnsureResponse": { @@ -1394,11 +1347,6 @@ "InstanceProperties": { "type": "object", "properties": { - "bootrom_id": { - "description": "ID of the bootrom used to initialize this Instance.", - "type": "string", - "format": "uuid" - }, "description": { "description": "Free-form text description of an Instance.", "type": "string" @@ -1408,17 +1356,6 @@ "type": "string", "format": "uuid" }, - "image_id": { - "description": "ID of the image used to initialize this Instance.", - "type": "string", - "format": "uuid" - }, - "memory": { - "description": "Size of memory allocated to the Instance, in MiB.", - "type": "integer", - "format": "uint64", - "minimum": 0 - }, "metadata": { "description": "Metadata used to track statistics for this Instance.", "allOf": [ @@ -1430,23 +1367,13 @@ "name": { "description": "Human-readable name of the Instance.", "type": "string" - }, - "vcpus": { - "description": "Number of vCPUs to be allocated to the Instance.", - "type": "integer", - "format": "uint8", - "minimum": 0 } }, "required": [ - "bootrom_id", "description", "id", - "image_id", - "memory", "metadata", - "name", - "vcpus" + "name" ] }, "InstanceSerialConsoleHistoryResponse": { @@ -1623,44 +1550,6 @@ "Error" ] }, - "NetworkInterface": { - "type": "object", - "properties": { - "attachment": { - "$ref": "#/components/schemas/NetworkInterfaceAttachmentState" - }, - "name": { - "type": "string" - } - }, - "required": [ - "attachment", - "name" - ] - }, - "NetworkInterfaceAttachmentState": { - "oneOf": [ - { - "type": "string", - "enum": [ - "Detached", - "Faulted" - ] - }, - { - "type": "object", - "properties": { - "Attached": { - "$ref": "#/components/schemas/Slot" - } - }, - "required": [ - "Attached" - ], - "additionalProperties": false - } - ] - }, "NetworkInterfaceRequest": { "type": "object", "properties": { diff --git a/phd-tests/framework/src/test_vm/mod.rs b/phd-tests/framework/src/test_vm/mod.rs index 2fd454e3e..ca2fef4f9 100644 --- a/phd-tests/framework/src/test_vm/mod.rs +++ b/phd-tests/framework/src/test_vm/mod.rs @@ -311,10 +311,6 @@ impl TestVm { name: format!("phd-vm-{}", self.id), metadata: self.spec.metadata.clone(), description: "Pheidippides-managed VM".to_string(), - image_id: Uuid::default(), - bootrom_id: Uuid::default(), - memory: memory_mib, - vcpus, }; // The non-spec ensure interface requires a set of `DiskRequest` @@ -356,6 +352,8 @@ impl TestVm { InstanceEnsureApi::Ensure => { let ensure_req = InstanceEnsureRequest { cloud_init_bytes: None, + vcpus, + memory: memory_mib, disks: disk_reqs.clone().unwrap(), migrate: migrate.clone(), nics: vec![],