Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion nexus/src/app/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ impl super::Nexus {

check_instance_cpu_memory_sizes(*ncpus, *memory)?;

let boot_disk_id = match boot_disk {
let boot_disk_id = match &**boot_disk {
Some(disk) => {
let selector = params::DiskSelector {
project: match &disk {
Expand Down
6 changes: 3 additions & 3 deletions nexus/tests/integration_tests/endpoints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,9 +687,9 @@ pub static DEMO_STOPPED_INSTANCE_CREATE: LazyLock<params::InstanceCreate> =
});
pub static DEMO_INSTANCE_UPDATE: LazyLock<params::InstanceUpdate> =
LazyLock::new(|| params::InstanceUpdate {
boot_disk: None,
cpu_platform: None,
auto_restart_policy: None,
boot_disk: Nullable(None),
cpu_platform: Nullable(None),
auto_restart_policy: Nullable(None),
ncpus: InstanceCpuCount(1),
memory: ByteCount::from_gibibytes_u32(16),
});
Expand Down
107 changes: 50 additions & 57 deletions nexus/tests/integration_tests/instances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ use omicron_common::api::external::InstanceNetworkInterface;
use omicron_common::api::external::InstanceState;
use omicron_common::api::external::Name;
use omicron_common::api::external::NameOrId;
use omicron_common::api::external::Nullable;
use omicron_common::api::external::Vni;
use omicron_common::api::internal::shared::ResolvedVpcRoute;
use omicron_common::api::internal::shared::RouterId;
Expand Down Expand Up @@ -4920,9 +4921,9 @@ async fn test_cannot_detach_boot_disk(cptestctx: &ControlPlaneTestContext) {
&client,
&instance.identity.id,
params::InstanceUpdate {
boot_disk: None,
auto_restart_policy: None,
cpu_platform: None,
boot_disk: Nullable(None),
auto_restart_policy: Nullable(None),
cpu_platform: Nullable(None),
ncpus: InstanceCpuCount::try_from(2).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
},
Expand Down Expand Up @@ -5025,9 +5026,9 @@ async fn test_updating_running_instance_boot_disk_is_conflict(
&client,
&instance_id.into_untyped_uuid(),
params::InstanceUpdate {
boot_disk: Some(alsodata.clone().into()),
auto_restart_policy: None,
cpu_platform: None,
boot_disk: Nullable(Some(alsodata.clone().into())),
auto_restart_policy: Nullable(None),
cpu_platform: Nullable(None),
ncpus: InstanceCpuCount::try_from(2).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
},
Expand All @@ -5044,9 +5045,11 @@ async fn test_updating_running_instance_boot_disk_is_conflict(
params::InstanceUpdate {
// Leave the boot disk the same as the one with which the instance
// was created.
boot_disk: Some(probablydata.clone().into()),
auto_restart_policy: Some(InstanceAutoRestartPolicy::BestEffort),
cpu_platform: None,
boot_disk: Nullable(Some(probablydata.clone().into())),
auto_restart_policy: Nullable(Some(
InstanceAutoRestartPolicy::BestEffort,
)),
cpu_platform: Nullable(None),
ncpus: InstanceCpuCount::try_from(2).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
},
Expand All @@ -5067,9 +5070,9 @@ async fn test_updating_missing_instance_is_not_found(
&client,
&UUID_THAT_DOESNT_EXIST,
params::InstanceUpdate {
boot_disk: None,
auto_restart_policy: None,
cpu_platform: None,
boot_disk: Nullable(None),
auto_restart_policy: Nullable(None),
cpu_platform: Nullable(None),
ncpus: InstanceCpuCount::try_from(0).unwrap(),
memory: ByteCount::from_gibibytes_u32(0),
},
Expand Down Expand Up @@ -5185,16 +5188,22 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
let new_ncpus = InstanceCpuCount::try_from(4).unwrap();
let new_memory = ByteCount::from_gibibytes_u32(8);

let base_update = params::InstanceUpdate {
auto_restart_policy: Nullable(auto_restart_policy),
boot_disk: Nullable(boot_disk_nameorid.clone()),
cpu_platform: Nullable(None),
ncpus: initial_ncpus,
memory: initial_memory,
};
Comment on lines +5191 to +5197
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this to avoid repeating code? For what it's worth, I found the prior structure easier to understand--especially when looking locally. Is your thought that this makes it easier to add new settings in the future? Perhaps this argues for a PATCH interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was basically me grumbling about the fact that I would have had to fix a lot fewer lines of code if this had already been in place. But that is a narrow reason and it's easy to change it back.


// Resizing the instance immediately will error; the instance is running.
let err = expect_instance_reconfigure_err(
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: new_ncpus,
memory: new_memory,
..base_update.clone()
},
StatusCode::CONFLICT,
)
Expand All @@ -5213,11 +5222,9 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: new_ncpus,
memory: new_memory,
..base_update.clone()
},
)
.await;
Expand All @@ -5229,11 +5236,9 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: initial_ncpus,
memory: new_memory,
..base_update.clone()
},
)
.await;
Expand All @@ -5244,11 +5249,9 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: initial_ncpus,
memory: initial_memory,
..base_update.clone()
},
)
.await;
Expand All @@ -5263,11 +5266,9 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: InstanceCpuCount(MAX_VCPU_PER_INSTANCE + 1),
memory: instance.memory,
..base_update.clone()
},
StatusCode::BAD_REQUEST,
)
Expand All @@ -5285,11 +5286,9 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: instance.ncpus,
memory: ByteCount::from_mebibytes_u32(0),
..base_update.clone()
},
StatusCode::BAD_REQUEST,
)
Expand All @@ -5301,12 +5300,10 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: instance.ncpus,
memory: ByteCount::try_from(MAX_MEMORY_BYTES_PER_INSTANCE - 1)
.unwrap(),
..base_update.clone()
},
StatusCode::BAD_REQUEST,
)
Expand All @@ -5319,13 +5316,11 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: instance.ncpus,
memory: ByteCount::from_mebibytes_u32(
(max_mib + 1024).try_into().unwrap(),
),
..base_update.clone()
},
StatusCode::BAD_REQUEST,
)
Expand All @@ -5342,11 +5337,9 @@ async fn test_size_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
params::InstanceUpdate {
auto_restart_policy,
boot_disk: boot_disk_nameorid.clone(),
cpu_platform: None,
ncpus: new_ncpus,
memory: new_memory,
..base_update.clone()
},
StatusCode::NOT_FOUND,
)
Expand Down Expand Up @@ -5404,9 +5397,9 @@ async fn test_auto_restart_policy_can_be_changed(
client,
&instance.identity.id,
dbg!(params::InstanceUpdate {
auto_restart_policy,
boot_disk: None,
cpu_platform: None,
auto_restart_policy: Nullable(auto_restart_policy),
boot_disk: Nullable(None),
cpu_platform: Nullable(None),
ncpus: InstanceCpuCount::try_from(2).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
}),
Expand Down Expand Up @@ -5477,9 +5470,9 @@ async fn test_cpu_platform_can_be_changed(cptestctx: &ControlPlaneTestContext) {
client,
&instance.identity.id,
dbg!(params::InstanceUpdate {
auto_restart_policy: None,
boot_disk: None,
cpu_platform,
auto_restart_policy: Nullable(None),
boot_disk: Nullable(None),
cpu_platform: Nullable(cpu_platform),
ncpus: InstanceCpuCount::try_from(2).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
}),
Expand Down Expand Up @@ -5572,9 +5565,9 @@ async fn test_boot_disk_can_be_changed(cptestctx: &ControlPlaneTestContext) {
&client,
&instance.identity.id,
params::InstanceUpdate {
boot_disk: Some(disks[1].identity.id.into()),
auto_restart_policy: None,
cpu_platform: None,
boot_disk: Nullable(Some(disks[1].identity.id.into())),
auto_restart_policy: Nullable(None),
cpu_platform: Nullable(None),
ncpus: InstanceCpuCount::try_from(2).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
},
Expand Down Expand Up @@ -5641,9 +5634,9 @@ async fn test_boot_disk_must_be_attached(cptestctx: &ControlPlaneTestContext) {
&client,
&instance.identity.id,
params::InstanceUpdate {
boot_disk: Some(disks[0].identity.id.into()),
auto_restart_policy: None,
cpu_platform: None,
boot_disk: Nullable(Some(disks[0].identity.id.into())),
auto_restart_policy: Nullable(None),
cpu_platform: Nullable(None),
ncpus: InstanceCpuCount::try_from(2).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
},
Expand Down Expand Up @@ -5675,9 +5668,9 @@ async fn test_boot_disk_must_be_attached(cptestctx: &ControlPlaneTestContext) {
&client,
&instance.identity.id,
params::InstanceUpdate {
boot_disk: Some(disks[0].identity.id.into()),
auto_restart_policy: None,
cpu_platform: None,
boot_disk: Nullable(Some(disks[0].identity.id.into())),
auto_restart_policy: Nullable(None),
cpu_platform: Nullable(None),
ncpus: InstanceCpuCount::try_from(2).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
},
Expand Down Expand Up @@ -6654,9 +6647,9 @@ async fn test_can_start_instance_with_cpu_platform(
&client,
&instance.identity.id,
params::InstanceUpdate {
boot_disk: None,
auto_restart_policy: None,
cpu_platform: Some(InstanceCpuPlatform::AmdTurin),
boot_disk: Nullable(None),
auto_restart_policy: Nullable(None),
cpu_platform: Nullable(Some(InstanceCpuPlatform::AmdTurin)),
ncpus: InstanceCpuCount::try_from(1).unwrap(),
memory: ByteCount::from_gibibytes_u32(4),
},
Expand Down
6 changes: 3 additions & 3 deletions nexus/types/src/external_api/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1302,7 +1302,7 @@ pub struct InstanceUpdate {
/// Name or ID of the disk the instance should be instructed to boot from.
///
/// If not provided, unset the instance's boot disk.
pub boot_disk: Option<NameOrId>,
pub boot_disk: Nullable<NameOrId>,

/// Sets the auto-restart policy for this instance.
///
Expand All @@ -1318,11 +1318,11 @@ pub struct InstanceUpdate {
/// configurable through other mechanisms, such as on a per-project basis.
/// In that case, any configured default policy will be used if this is
/// `null`.
pub auto_restart_policy: Option<InstanceAutoRestartPolicy>,
pub auto_restart_policy: Nullable<InstanceAutoRestartPolicy>,

/// The CPU platform to be used for this instance. If this is `null`, the
/// instance requires no particular CPU platform.
pub cpu_platform: Option<InstanceCpuPlatform>,
pub cpu_platform: Nullable<InstanceCpuPlatform>,
}

#[inline]
Expand Down
3 changes: 3 additions & 0 deletions openapi/nexus.json
Original file line number Diff line number Diff line change
Expand Up @@ -20876,6 +20876,9 @@
}
},
"required": [
"auto_restart_policy",
"boot_disk",
"cpu_platform",
"memory",
"ncpus"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This lets the TS client generator mark these fields as nullable but not optional.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, this rules.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, the Rust generator doesn't (currently) draw this distinction; I don't know about the go generator.

]
Expand Down
Loading