From f2f44aca42946779b313178b54a0b07941c5e28d Mon Sep 17 00:00:00 2001 From: karencfv Date: Thu, 17 Jul 2025 20:50:22 +1200 Subject: [PATCH 1/4] [reconfigurator-cli] RoT bootloader support --- dev-tools/reconfigurator-cli/src/lib.rs | 70 +++++++ .../reconfigurator-cli/tests/input/cmds.txt | 12 ++ .../tests/output/cmds-example-stdout | 4 + .../output/cmds-noop-image-source-stdout | 2 +- .../tests/output/cmds-stderr | 7 + .../tests/output/cmds-stdout | 187 ++++++++++++++++++ .../tests/output/cmds-target-release-stdout | 6 +- nexus/reconfigurator/planning/src/system.rs | 152 ++++++++++++++ nexus/reconfigurator/simulation/src/system.rs | 8 + update-common/manifests/fake.toml | 2 +- 10 files changed, 445 insertions(+), 5 deletions(-) diff --git a/dev-tools/reconfigurator-cli/src/lib.rs b/dev-tools/reconfigurator-cli/src/lib.rs index 928a64793e9..3d755fda5bf 100644 --- a/dev-tools/reconfigurator-cli/src/lib.rs +++ b/dev-tools/reconfigurator-cli/src/lib.rs @@ -231,6 +231,9 @@ fn process_command( cmd_sled_update_install_dataset(sim, args) } Commands::SledUpdateSp(args) => cmd_sled_update_sp(sim, args), + Commands::SledUpdateRotBootloader(args) => { + cmd_sled_update_rot_bootlaoder(sim, args) + } Commands::SiloList => cmd_silo_list(sim), Commands::SiloAdd(args) => cmd_silo_add(sim, args), Commands::SiloRemove(args) => cmd_silo_remove(sim, args), @@ -284,6 +287,8 @@ enum Commands { SledSet(SledSetArgs), /// update the install dataset on a sled, simulating a mupdate SledUpdateInstallDataset(SledUpdateInstallDatasetArgs), + /// simulate updating the sled's RoT Bootloader versions + SledUpdateRotBootloader(SledUpdateRotBootloaderArgs), /// simulate updating the sled's SP versions SledUpdateSp(SledUpdateSpArgs), @@ -484,6 +489,21 @@ struct SledMupdateValidSource { to_target_release: bool, } +#[derive(Debug, Args)] +struct SledUpdateRotBootloaderArgs { + /// id of the sled + sled_id: SledOpt, + + /// sets the version reported for the RoT bootloader stage0 (active) slot + #[clap(long, required_unless_present_any = &["stage0_next"])] + stage0: Option, + + /// sets the version reported for the RoT bootloader stage0_next (inactive) + /// slot + #[clap(long, required_unless_present_any = &["stage0"])] + stage0_next: Option, +} + #[derive(Debug, Args)] struct SledUpdateSpArgs { /// id of the sled @@ -1278,6 +1298,8 @@ fn cmd_sled_show( let state = sim.current_state(); let description = state.system().description(); let sled_id = args.sled_id.to_sled_id(description)?; + let stage0_version = description.sled_stage0_version(sled_id)?; + let stage0_next_version = description.sled_stage0_next_version(sled_id)?; let sp_active_version = description.sled_sp_active_version(sled_id)?; let sp_inactive_version = description.sled_sp_inactive_version(sled_id)?; let planning_input = description @@ -1290,6 +1312,12 @@ fn cmd_sled_show( swriteln!(s, "sled {} ({}, {})", sled_id, sled.policy, sled.state); swriteln!(s, "serial {}", sled.baseboard_id.serial_number); swriteln!(s, "subnet {}", sled_resources.subnet.net()); + swriteln!(s, "RoT bootloader stage 0 version: {:?}", stage0_version); + swriteln!( + s, + "RoT bootloader stage 0 next version: {:?}", + stage0_next_version + ); swriteln!(s, "SP active version: {:?}", sp_active_version); swriteln!(s, "SP inactive version: {:?}", sp_inactive_version); swriteln!(s, "zpools ({}):", sled_resources.zpools.len()); @@ -1373,6 +1401,48 @@ fn cmd_sled_update_install_dataset( ))) } +fn cmd_sled_update_rot_bootlaoder( + sim: &mut ReconfiguratorSim, + args: SledUpdateRotBootloaderArgs, +) -> anyhow::Result> { + let mut labels = Vec::new(); + if let Some(stage0) = &args.stage0 { + labels.push(format!("stage0 -> {}", stage0)); + } + if let Some(stage0_next) = &args.stage0_next { + labels.push(format!("stage0_next -> {}", stage0_next)); + } + + assert!( + !labels.is_empty(), + "clap configuration requires that at least one argument is specified" + ); + + let mut state = sim.current_state().to_mut(); + let system = state.system_mut(); + let sled_id = args.sled_id.to_sled_id(system.description())?; + system.description_mut().sled_update_rot_bootloader_versions( + sled_id, + args.stage0, + args.stage0_next, + )?; + + sim.commit_and_bump( + format!( + "reconfigurator-cli sled-update-rot-bootloader: {}: {}", + sled_id, + labels.join(", "), + ), + state, + ); + + Ok(Some(format!( + "set sled {} RoT bootloader versions: {}", + sled_id, + labels.join(", ") + ))) +} + fn cmd_sled_update_sp( sim: &mut ReconfiguratorSim, args: SledUpdateSpArgs, diff --git a/dev-tools/reconfigurator-cli/tests/input/cmds.txt b/dev-tools/reconfigurator-cli/tests/input/cmds.txt index 671a89303b1..713fc0dfafd 100644 --- a/dev-tools/reconfigurator-cli/tests/input/cmds.txt +++ b/dev-tools/reconfigurator-cli/tests/input/cmds.txt @@ -25,6 +25,18 @@ sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a sled-update-sp dde1c0e2-b10d-4621-b420-f179f7a7a00a --active 4.0.0 --inactive 5.0.0 sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0 1.0.0 +sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0-next 2.0.0 +sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0 3.0.0 +sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0 4.0.0 --stage0-next invalid +sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0 4.0.0 --stage0-next 5.0.0 +sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a + inventory-generate inventory-list diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout index 4b2c4f5e167..18ccfd275ee 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout @@ -40,6 +40,8 @@ T ENA ID PARENT sled 2eb69596-f081-4e2d-9425-9994926e0832 (in service, active) serial serial1 subnet fd00:1122:3344:102::/64 +RoT bootloader stage 0 version: Some("0.0.1") +RoT bootloader stage 0 next version: None SP active version: Some("0.0.1") SP inactive version: None zpools (10): @@ -425,6 +427,8 @@ T ENA ID PARENT sled 89d02b1b-478c-401a-8e28-7a26f74fa41b (in service, active) serial serial0 subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("0.0.1") +RoT bootloader stage 0 next version: None SP active version: Some("0.0.1") SP inactive version: None zpools (4): diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout index 95a4c206dd7..bd344107868 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout @@ -42,7 +42,7 @@ INFO created directory to store extracted artifacts, path: --inactive For more information, try '--help'. +error: the following required arguments were not provided: + --stage0 + --stage0-next + +Usage: sled-update-rot-bootloader --stage0 --stage0-next + +For more information, try '--help'. diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-stdout index 26619691d05..3c70c247bdc 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-stdout @@ -28,6 +28,8 @@ dde1c0e2-b10d-4621-b420-f179f7a7a00a serial0 10 fd00:1122:3344:101::/64 sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) serial serial0 subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("0.0.1") +RoT bootloader stage 0 next version: None SP active version: Some("0.0.1") SP inactive version: None zpools (10): @@ -75,6 +77,8 @@ set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a SP versions: active -> 1.0.0 sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) serial serial0 subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("0.0.1") +RoT bootloader stage 0 next version: None SP active version: Some("1.0.0") SP inactive version: None zpools (10): @@ -107,6 +111,8 @@ set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a SP versions: inactive -> 2.0.0 sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) serial serial0 subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("0.0.1") +RoT bootloader stage 0 next version: None SP active version: Some("1.0.0") SP inactive version: Some("2.0.0") zpools (10): @@ -139,6 +145,8 @@ set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a SP versions: active -> 3.0.0 sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) serial serial0 subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("0.0.1") +RoT bootloader stage 0 next version: None SP active version: Some("3.0.0") SP inactive version: Some("2.0.0") zpools (10): @@ -171,6 +179,8 @@ set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a SP versions: active -> 4.0.0, inac sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) serial serial0 subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("0.0.1") +RoT bootloader stage 0 next version: None SP active version: Some("4.0.0") SP inactive version: None zpools (10): @@ -203,6 +213,181 @@ set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a SP versions: active -> 4.0.0, inac sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) serial serial0 subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("0.0.1") +RoT bootloader stage 0 next version: None +SP active version: Some("4.0.0") +SP inactive version: Some("5.0.0") +zpools (10): + 674c6591-11be-44f2-9df1-db3bb663ec01 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-674c6591-11be-44f2-9df1-db3bb663ec01" }, disk_id: a52a7c57-7fd0-4139-8293-bda299523c53 (physical_disk), policy: InService, state: Active } + 677dd944-6761-4a89-8606-4d7fe485a63c (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-677dd944-6761-4a89-8606-4d7fe485a63c" }, disk_id: fcf54220-3ff4-463e-b4a2-58447f51b68c (physical_disk), policy: InService, state: Active } + 70e81eac-6ed4-4c2d-b16a-fabe2aec56fc (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-70e81eac-6ed4-4c2d-b16a-fabe2aec56fc" }, disk_id: 42643377-e4d1-41a0-ac32-38d6e56cb22a (physical_disk), policy: InService, state: Active } + 7b26c659-bf8f-4c60-ab75-fd2dd8ef5866 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-7b26c659-bf8f-4c60-ab75-fd2dd8ef5866" }, disk_id: 5b2df08c-ea6a-4771-8363-80031249c97b (physical_disk), policy: InService, state: Active } + 8e0008d0-9313-4caf-bc20-305ccce29846 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-8e0008d0-9313-4caf-bc20-305ccce29846" }, disk_id: 0f5e7fc1-8d87-45f8-a00e-f5127b7a3905 (physical_disk), policy: InService, state: Active } + 929e328a-dd25-447d-9af7-6e2216adf4aa (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-929e328a-dd25-447d-9af7-6e2216adf4aa" }, disk_id: f62e3201-e89b-4667-9707-e49f86b9df07 (physical_disk), policy: InService, state: Active } + 9a25ff89-5446-4233-bf58-20a24c80aa58 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-9a25ff89-5446-4233-bf58-20a24c80aa58" }, disk_id: 49b87668-e08b-4939-91f7-a82612e2ebff (physical_disk), policy: InService, state: Active } + a9cd1fe6-f1ba-4227-bff7-978992c3d6ad (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-a9cd1fe6-f1ba-4227-bff7-978992c3d6ad" }, disk_id: dcde393a-3ac6-4e98-8833-012787e73e15 (physical_disk), policy: InService, state: Active } + b3ede1e1-3264-4b21-8c7d-9ea5d3715210 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-b3ede1e1-3264-4b21-8c7d-9ea5d3715210" }, disk_id: 4863117c-b77d-4dbc-996d-d18ddf0f5ff7 (physical_disk), policy: InService, state: Active } + e0f5c287-3296-4a35-b597-7452283ff329 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-e0f5c287-3296-4a35-b597-7452283ff329" }, disk_id: 0f13d3dd-1830-4a06-b664-e6f0473ba704 (physical_disk), policy: InService, state: Active } + + + +> sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a + +> sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0 1.0.0 +set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a RoT bootloader versions: stage0 -> 1.0.0 + +> sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) +serial serial0 +subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("1.0.0") +RoT bootloader stage 0 next version: None +SP active version: Some("4.0.0") +SP inactive version: Some("5.0.0") +zpools (10): + 674c6591-11be-44f2-9df1-db3bb663ec01 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-674c6591-11be-44f2-9df1-db3bb663ec01" }, disk_id: a52a7c57-7fd0-4139-8293-bda299523c53 (physical_disk), policy: InService, state: Active } + 677dd944-6761-4a89-8606-4d7fe485a63c (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-677dd944-6761-4a89-8606-4d7fe485a63c" }, disk_id: fcf54220-3ff4-463e-b4a2-58447f51b68c (physical_disk), policy: InService, state: Active } + 70e81eac-6ed4-4c2d-b16a-fabe2aec56fc (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-70e81eac-6ed4-4c2d-b16a-fabe2aec56fc" }, disk_id: 42643377-e4d1-41a0-ac32-38d6e56cb22a (physical_disk), policy: InService, state: Active } + 7b26c659-bf8f-4c60-ab75-fd2dd8ef5866 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-7b26c659-bf8f-4c60-ab75-fd2dd8ef5866" }, disk_id: 5b2df08c-ea6a-4771-8363-80031249c97b (physical_disk), policy: InService, state: Active } + 8e0008d0-9313-4caf-bc20-305ccce29846 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-8e0008d0-9313-4caf-bc20-305ccce29846" }, disk_id: 0f5e7fc1-8d87-45f8-a00e-f5127b7a3905 (physical_disk), policy: InService, state: Active } + 929e328a-dd25-447d-9af7-6e2216adf4aa (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-929e328a-dd25-447d-9af7-6e2216adf4aa" }, disk_id: f62e3201-e89b-4667-9707-e49f86b9df07 (physical_disk), policy: InService, state: Active } + 9a25ff89-5446-4233-bf58-20a24c80aa58 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-9a25ff89-5446-4233-bf58-20a24c80aa58" }, disk_id: 49b87668-e08b-4939-91f7-a82612e2ebff (physical_disk), policy: InService, state: Active } + a9cd1fe6-f1ba-4227-bff7-978992c3d6ad (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-a9cd1fe6-f1ba-4227-bff7-978992c3d6ad" }, disk_id: dcde393a-3ac6-4e98-8833-012787e73e15 (physical_disk), policy: InService, state: Active } + b3ede1e1-3264-4b21-8c7d-9ea5d3715210 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-b3ede1e1-3264-4b21-8c7d-9ea5d3715210" }, disk_id: 4863117c-b77d-4dbc-996d-d18ddf0f5ff7 (physical_disk), policy: InService, state: Active } + e0f5c287-3296-4a35-b597-7452283ff329 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-e0f5c287-3296-4a35-b597-7452283ff329" }, disk_id: 0f13d3dd-1830-4a06-b664-e6f0473ba704 (physical_disk), policy: InService, state: Active } + + +> sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0-next 2.0.0 +set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a RoT bootloader versions: stage0_next -> 2.0.0 + +> sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) +serial serial0 +subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("1.0.0") +RoT bootloader stage 0 next version: Some("2.0.0") +SP active version: Some("4.0.0") +SP inactive version: Some("5.0.0") +zpools (10): + 674c6591-11be-44f2-9df1-db3bb663ec01 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-674c6591-11be-44f2-9df1-db3bb663ec01" }, disk_id: a52a7c57-7fd0-4139-8293-bda299523c53 (physical_disk), policy: InService, state: Active } + 677dd944-6761-4a89-8606-4d7fe485a63c (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-677dd944-6761-4a89-8606-4d7fe485a63c" }, disk_id: fcf54220-3ff4-463e-b4a2-58447f51b68c (physical_disk), policy: InService, state: Active } + 70e81eac-6ed4-4c2d-b16a-fabe2aec56fc (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-70e81eac-6ed4-4c2d-b16a-fabe2aec56fc" }, disk_id: 42643377-e4d1-41a0-ac32-38d6e56cb22a (physical_disk), policy: InService, state: Active } + 7b26c659-bf8f-4c60-ab75-fd2dd8ef5866 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-7b26c659-bf8f-4c60-ab75-fd2dd8ef5866" }, disk_id: 5b2df08c-ea6a-4771-8363-80031249c97b (physical_disk), policy: InService, state: Active } + 8e0008d0-9313-4caf-bc20-305ccce29846 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-8e0008d0-9313-4caf-bc20-305ccce29846" }, disk_id: 0f5e7fc1-8d87-45f8-a00e-f5127b7a3905 (physical_disk), policy: InService, state: Active } + 929e328a-dd25-447d-9af7-6e2216adf4aa (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-929e328a-dd25-447d-9af7-6e2216adf4aa" }, disk_id: f62e3201-e89b-4667-9707-e49f86b9df07 (physical_disk), policy: InService, state: Active } + 9a25ff89-5446-4233-bf58-20a24c80aa58 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-9a25ff89-5446-4233-bf58-20a24c80aa58" }, disk_id: 49b87668-e08b-4939-91f7-a82612e2ebff (physical_disk), policy: InService, state: Active } + a9cd1fe6-f1ba-4227-bff7-978992c3d6ad (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-a9cd1fe6-f1ba-4227-bff7-978992c3d6ad" }, disk_id: dcde393a-3ac6-4e98-8833-012787e73e15 (physical_disk), policy: InService, state: Active } + b3ede1e1-3264-4b21-8c7d-9ea5d3715210 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-b3ede1e1-3264-4b21-8c7d-9ea5d3715210" }, disk_id: 4863117c-b77d-4dbc-996d-d18ddf0f5ff7 (physical_disk), policy: InService, state: Active } + e0f5c287-3296-4a35-b597-7452283ff329 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-e0f5c287-3296-4a35-b597-7452283ff329" }, disk_id: 0f13d3dd-1830-4a06-b664-e6f0473ba704 (physical_disk), policy: InService, state: Active } + + +> sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0 3.0.0 +set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a RoT bootloader versions: stage0 -> 3.0.0 + +> sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) +serial serial0 +subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("3.0.0") +RoT bootloader stage 0 next version: Some("2.0.0") +SP active version: Some("4.0.0") +SP inactive version: Some("5.0.0") +zpools (10): + 674c6591-11be-44f2-9df1-db3bb663ec01 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-674c6591-11be-44f2-9df1-db3bb663ec01" }, disk_id: a52a7c57-7fd0-4139-8293-bda299523c53 (physical_disk), policy: InService, state: Active } + 677dd944-6761-4a89-8606-4d7fe485a63c (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-677dd944-6761-4a89-8606-4d7fe485a63c" }, disk_id: fcf54220-3ff4-463e-b4a2-58447f51b68c (physical_disk), policy: InService, state: Active } + 70e81eac-6ed4-4c2d-b16a-fabe2aec56fc (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-70e81eac-6ed4-4c2d-b16a-fabe2aec56fc" }, disk_id: 42643377-e4d1-41a0-ac32-38d6e56cb22a (physical_disk), policy: InService, state: Active } + 7b26c659-bf8f-4c60-ab75-fd2dd8ef5866 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-7b26c659-bf8f-4c60-ab75-fd2dd8ef5866" }, disk_id: 5b2df08c-ea6a-4771-8363-80031249c97b (physical_disk), policy: InService, state: Active } + 8e0008d0-9313-4caf-bc20-305ccce29846 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-8e0008d0-9313-4caf-bc20-305ccce29846" }, disk_id: 0f5e7fc1-8d87-45f8-a00e-f5127b7a3905 (physical_disk), policy: InService, state: Active } + 929e328a-dd25-447d-9af7-6e2216adf4aa (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-929e328a-dd25-447d-9af7-6e2216adf4aa" }, disk_id: f62e3201-e89b-4667-9707-e49f86b9df07 (physical_disk), policy: InService, state: Active } + 9a25ff89-5446-4233-bf58-20a24c80aa58 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-9a25ff89-5446-4233-bf58-20a24c80aa58" }, disk_id: 49b87668-e08b-4939-91f7-a82612e2ebff (physical_disk), policy: InService, state: Active } + a9cd1fe6-f1ba-4227-bff7-978992c3d6ad (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-a9cd1fe6-f1ba-4227-bff7-978992c3d6ad" }, disk_id: dcde393a-3ac6-4e98-8833-012787e73e15 (physical_disk), policy: InService, state: Active } + b3ede1e1-3264-4b21-8c7d-9ea5d3715210 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-b3ede1e1-3264-4b21-8c7d-9ea5d3715210" }, disk_id: 4863117c-b77d-4dbc-996d-d18ddf0f5ff7 (physical_disk), policy: InService, state: Active } + e0f5c287-3296-4a35-b597-7452283ff329 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-e0f5c287-3296-4a35-b597-7452283ff329" }, disk_id: 0f13d3dd-1830-4a06-b664-e6f0473ba704 (physical_disk), policy: InService, state: Active } + + +> sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0 4.0.0 --stage0-next invalid +set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a RoT bootloader versions: stage0 -> 4.0.0, stage0_next -> invalid + +> sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) +serial serial0 +subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("4.0.0") +RoT bootloader stage 0 next version: None +SP active version: Some("4.0.0") +SP inactive version: Some("5.0.0") +zpools (10): + 674c6591-11be-44f2-9df1-db3bb663ec01 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-674c6591-11be-44f2-9df1-db3bb663ec01" }, disk_id: a52a7c57-7fd0-4139-8293-bda299523c53 (physical_disk), policy: InService, state: Active } + 677dd944-6761-4a89-8606-4d7fe485a63c (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-677dd944-6761-4a89-8606-4d7fe485a63c" }, disk_id: fcf54220-3ff4-463e-b4a2-58447f51b68c (physical_disk), policy: InService, state: Active } + 70e81eac-6ed4-4c2d-b16a-fabe2aec56fc (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-70e81eac-6ed4-4c2d-b16a-fabe2aec56fc" }, disk_id: 42643377-e4d1-41a0-ac32-38d6e56cb22a (physical_disk), policy: InService, state: Active } + 7b26c659-bf8f-4c60-ab75-fd2dd8ef5866 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-7b26c659-bf8f-4c60-ab75-fd2dd8ef5866" }, disk_id: 5b2df08c-ea6a-4771-8363-80031249c97b (physical_disk), policy: InService, state: Active } + 8e0008d0-9313-4caf-bc20-305ccce29846 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-8e0008d0-9313-4caf-bc20-305ccce29846" }, disk_id: 0f5e7fc1-8d87-45f8-a00e-f5127b7a3905 (physical_disk), policy: InService, state: Active } + 929e328a-dd25-447d-9af7-6e2216adf4aa (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-929e328a-dd25-447d-9af7-6e2216adf4aa" }, disk_id: f62e3201-e89b-4667-9707-e49f86b9df07 (physical_disk), policy: InService, state: Active } + 9a25ff89-5446-4233-bf58-20a24c80aa58 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-9a25ff89-5446-4233-bf58-20a24c80aa58" }, disk_id: 49b87668-e08b-4939-91f7-a82612e2ebff (physical_disk), policy: InService, state: Active } + a9cd1fe6-f1ba-4227-bff7-978992c3d6ad (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-a9cd1fe6-f1ba-4227-bff7-978992c3d6ad" }, disk_id: dcde393a-3ac6-4e98-8833-012787e73e15 (physical_disk), policy: InService, state: Active } + b3ede1e1-3264-4b21-8c7d-9ea5d3715210 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-b3ede1e1-3264-4b21-8c7d-9ea5d3715210" }, disk_id: 4863117c-b77d-4dbc-996d-d18ddf0f5ff7 (physical_disk), policy: InService, state: Active } + e0f5c287-3296-4a35-b597-7452283ff329 (zpool) + SledDisk { disk_identity: DiskIdentity { vendor: "fake-vendor", model: "fake-model", serial: "serial-e0f5c287-3296-4a35-b597-7452283ff329" }, disk_id: 0f13d3dd-1830-4a06-b664-e6f0473ba704 (physical_disk), policy: InService, state: Active } + + +> sled-update-rot-bootloader dde1c0e2-b10d-4621-b420-f179f7a7a00a --stage0 4.0.0 --stage0-next 5.0.0 +set sled dde1c0e2-b10d-4621-b420-f179f7a7a00a RoT bootloader versions: stage0 -> 4.0.0, stage0_next -> 5.0.0 + +> sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a +sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) +serial serial0 +subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("4.0.0") +RoT bootloader stage 0 next version: Some("5.0.0") SP active version: Some("4.0.0") SP inactive version: Some("5.0.0") zpools (10): @@ -267,6 +452,8 @@ result: sled dde1c0e2-b10d-4621-b420-f179f7a7a00a (in service, active) serial serial0 subnet fd00:1122:3344:101::/64 +RoT bootloader stage 0 version: Some("4.0.0") +RoT bootloader stage 0 next version: Some("5.0.0") SP active version: Some("4.0.0") SP inactive version: Some("5.0.0") zpools (10): diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout index a994234a81a..8cf7cc57733 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout @@ -33,7 +33,7 @@ INFO created directory to store extracted artifacts, path: , + stage0_next_version: Option, + ) -> anyhow::Result<&mut Self> { + let sled = self.sleds.get_mut(&sled_id).with_context(|| { + format!("attempted to access sled {} not found in system", sled_id) + })?; + let sled = Arc::make_mut(sled); + sled.set_rot_bootloader_versions(stage0_version, stage0_next_version); + Ok(self) + } + + pub fn sled_stage0_version( + &self, + sled_id: SledUuid, + ) -> anyhow::Result> { + let sled = self.sleds.get(&sled_id).with_context(|| { + format!("attempted to access sled {} not found in system", sled_id) + })?; + Ok(sled.stage0_caboose().map(|c| c.version.as_ref())) + } + + pub fn sled_stage0_next_version( + &self, + sled_id: SledUuid, + ) -> anyhow::Result> { + let sled = self.sleds.get(&sled_id).with_context(|| { + format!("attempted to access sled {} not found in system", sled_id) + })?; + Ok(sled.stage0_next_caboose().map(|c| c.version.as_ref())) + } + /// Update the SP versions reported for a sled. /// /// Where `None` is provided, no changes are made. @@ -596,6 +633,43 @@ impl SystemDescription { part_number: sp_state.model.clone(), serial_number: sp_state.serial_number.clone(), }; + if let Some(stage0) = &s.stage0_caboose() { + builder + .found_caboose( + &baseboard_id, + CabooseWhich::Stage0, + "fake MGS 1", + SpComponentCaboose { + board: stage0.board.clone(), + epoch: None, + git_commit: stage0.git_commit.clone(), + name: stage0.name.clone(), + sign: stage0.sign.clone(), + version: stage0.version.clone(), + }, + ) + .context("recording RoT bootloader stage0 caboose")?; + } + + if let Some(stage0_next) = &s.stage0_next_caboose() { + builder + .found_caboose( + &baseboard_id, + CabooseWhich::Stage0Next, + "fake MGS 1", + SpComponentCaboose { + board: stage0_next.board.clone(), + epoch: None, + git_commit: stage0_next.git_commit.clone(), + name: stage0_next.name.clone(), + sign: stage0_next.sign.clone(), + version: stage0_next.version.clone(), + }, + ) + .context( + "recording RoT bootloader stage0_next caboose", + )?; + } if let Some(active) = &s.sp_active_caboose() { builder .found_caboose( @@ -805,6 +879,8 @@ pub struct SledHwInventory<'a> { pub baseboard_id: &'a BaseboardId, pub sp: &'a nexus_types::inventory::ServiceProcessor, pub rot: &'a nexus_types::inventory::RotState, + pub stage0: Option>, + pub stage0_next: Option>, pub sp_active: Option>, pub sp_inactive: Option>, } @@ -822,6 +898,8 @@ pub struct Sled { policy: SledPolicy, state: SledState, resources: SledResources, + stage0_caboose: Option>, + stage0_next_caboose: Option>, sp_active_caboose: Option>, sp_inactive_caboose: Option>, } @@ -972,6 +1050,10 @@ impl Sled { policy, state: SledState::Active, resources: SledResources { subnet: sled_subnet, zpools }, + stage0_caboose: Some(Arc::new( + Self::default_rot_bootloader_caboose(String::from("0.0.1")), + )), + stage0_next_caboose: None, sp_active_caboose: Some(Arc::new(Self::default_sp_caboose( String::from("0.0.1"), ))), @@ -1006,6 +1088,10 @@ impl Sled { }) .unwrap_or(Baseboard::Unknown); + let stage0_caboose = + inventory_sp.as_ref().and_then(|hw| hw.stage0.clone()); + let stage0_next_caboose = + inventory_sp.as_ref().and_then(|hw| hw.stage0_next.clone()); let sp_active_caboose = inventory_sp.as_ref().and_then(|hw| hw.sp_active.clone()); let sp_inactive_caboose = @@ -1119,6 +1205,8 @@ impl Sled { policy: sled_policy, state: sled_state, resources: sled_resources, + stage0_caboose, + stage0_next_caboose, sp_active_caboose, sp_inactive_caboose, } @@ -1159,6 +1247,14 @@ impl Sled { self.sp_inactive_caboose.as_deref() } + fn stage0_caboose(&self) -> Option<&Caboose> { + self.stage0_caboose.as_deref() + } + + fn stage0_next_caboose(&self) -> Option<&Caboose> { + self.stage0_next_caboose.as_deref() + } + fn set_zone_manifest( &mut self, boot_inventory: Result, @@ -1169,6 +1265,51 @@ impl Sled { .boot_inventory = boot_inventory; } + /// Update the reported RoT bootloader versions + /// + /// If either field is `None`, that field is _unchanged_. + // Note that this means there's no way to _unset_ the version. + fn set_rot_bootloader_versions( + &mut self, + stage0_version: Option, + stage0_next_version: Option, + ) { + if let Some(stage0_version) = stage0_version { + match &mut self.stage0_caboose { + Some(caboose) => { + Arc::make_mut(caboose).version = stage0_version.to_string() + } + new @ None => { + *new = Some(Arc::new(Self::default_sp_caboose( + stage0_version.to_string(), + ))); + } + } + } + + if let Some(stage0_next_version) = stage0_next_version { + match stage0_next_version { + ExpectedVersion::NoValidVersion => { + self.stage0_next_caboose = None; + } + ExpectedVersion::Version(v) => { + match &mut self.stage0_next_caboose { + Some(caboose) => { + Arc::make_mut(caboose).version = v.to_string() + } + new @ None => { + *new = Some(Arc::new( + Self::default_rot_bootloader_caboose( + v.to_string(), + ), + )); + } + } + } + } + } + } + /// Update the reported SP versions /// /// If either field is `None`, that field is _unchanged_. @@ -1212,6 +1353,17 @@ impl Sled { } } + fn default_rot_bootloader_caboose(version: String) -> Caboose { + let board = sp_sim::SIM_ROT_STAGE0_BOARD.to_string(); + Caboose { + board: board.clone(), + git_commit: String::from("unknown"), + name: board, + version: version.to_string(), + sign: None, + } + } + fn default_sp_caboose(version: String) -> Caboose { let board = sp_sim::SIM_GIMLET_BOARD.to_string(); Caboose { diff --git a/nexus/reconfigurator/simulation/src/system.rs b/nexus/reconfigurator/simulation/src/system.rs index 958a77df351..f803496124b 100644 --- a/nexus/reconfigurator/simulation/src/system.rs +++ b/nexus/reconfigurator/simulation/src/system.rs @@ -769,6 +769,12 @@ impl SimSystemBuilderInner { .and_then(|baseboard_id| { let inv_sp = primary_collection.sps.get(baseboard_id); let inv_rot = primary_collection.rots.get(baseboard_id); + let stage0 = primary_collection + .caboose_for(CabooseWhich::Stage0, baseboard_id) + .map(|c| c.caboose.clone()); + let stage0_next = primary_collection + .caboose_for(CabooseWhich::Stage0Next, baseboard_id) + .map(|c| c.caboose.clone()); let sp_active = primary_collection .caboose_for(CabooseWhich::SpSlot0, baseboard_id) .map(|c| c.caboose.clone()); @@ -780,6 +786,8 @@ impl SimSystemBuilderInner { baseboard_id: &baseboard_id, sp: inv_sp, rot: inv_rot, + stage0, + stage0_next, sp_active, sp_inactive, }) diff --git a/update-common/manifests/fake.toml b/update-common/manifests/fake.toml index 354296c404e..4661e4592ea 100644 --- a/update-common/manifests/fake.toml +++ b/update-common/manifests/fake.toml @@ -79,7 +79,7 @@ archive_a = { kind = "fake", size = "512KiB" } archive_b = { kind = "fake", size = "512KiB" } [[artifact.gimlet_rot_bootloader]] -name = "fake-gimlet-rot-bootloader" +name = "SimRotStage0" version = "1.0.0" source = { kind = "fake", size = "1MiB" } From 22fdb16beb9ba10755e01eed6f37b57f188e043c Mon Sep 17 00:00:00 2001 From: karencfv Date: Fri, 18 Jul 2025 13:21:05 +1200 Subject: [PATCH 2/4] small fix --- nexus/reconfigurator/planning/src/system.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nexus/reconfigurator/planning/src/system.rs b/nexus/reconfigurator/planning/src/system.rs index cb9e5f0c03d..2189f2cc1ea 100644 --- a/nexus/reconfigurator/planning/src/system.rs +++ b/nexus/reconfigurator/planning/src/system.rs @@ -1280,9 +1280,10 @@ impl Sled { Arc::make_mut(caboose).version = stage0_version.to_string() } new @ None => { - *new = Some(Arc::new(Self::default_sp_caboose( - stage0_version.to_string(), - ))); + *new = + Some(Arc::new(Self::default_rot_bootloader_caboose( + stage0_version.to_string(), + ))); } } } From d4c9251d5bfec8d05d445bf969f5fa90ba10a1bf Mon Sep 17 00:00:00 2001 From: karencfv Date: Fri, 18 Jul 2025 15:44:10 +1200 Subject: [PATCH 3/4] address comments --- nexus/reconfigurator/planning/src/system.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nexus/reconfigurator/planning/src/system.rs b/nexus/reconfigurator/planning/src/system.rs index 2189f2cc1ea..fd364db66c1 100644 --- a/nexus/reconfigurator/planning/src/system.rs +++ b/nexus/reconfigurator/planning/src/system.rs @@ -484,7 +484,7 @@ impl SystemDescription { Ok(prev) } - /// Update the RoT bootlaoder versions reported for a sled. + /// Update the RoT bootloader versions reported for a sled. /// /// Where `None` is provided, no changes are made. pub fn sled_update_rot_bootloader_versions( @@ -633,7 +633,7 @@ impl SystemDescription { part_number: sp_state.model.clone(), serial_number: sp_state.serial_number.clone(), }; - if let Some(stage0) = &s.stage0_caboose() { + if let Some(stage0) = s.stage0_caboose() { builder .found_caboose( &baseboard_id, @@ -651,7 +651,7 @@ impl SystemDescription { .context("recording RoT bootloader stage0 caboose")?; } - if let Some(stage0_next) = &s.stage0_next_caboose() { + if let Some(stage0_next) = s.stage0_next_caboose() { builder .found_caboose( &baseboard_id, From a498b868de0a2b55ed764d79c08d9744cec6c01a Mon Sep 17 00:00:00 2001 From: karencfv Date: Wed, 23 Jul 2025 12:41:20 +1200 Subject: [PATCH 4/4] expectorate --- .../tests/output/cmds-example-stdout | 15 +++++++++------ .../tests/output/cmds-mupdate-update-flow-stdout | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout index 3e8f3ab26d6..3b4f776fd65 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-example-stdout @@ -1035,8 +1035,9 @@ Sled serial0 A 0101010101010101010101010101010101010101010101010101010101010101 B 0202020202020202020202020202020202020202020202020202020202020202 cabooses: - SLOT BOARD NAME VERSION GIT_COMMIT SIGN - SpSlot0 SimGimletSp SimGimletSp 0.0.1 unknown n/a + SLOT BOARD NAME VERSION GIT_COMMIT SIGN + SpSlot0 SimGimletSp SimGimletSp 0.0.1 unknown n/a + Stage0 SimRotStage0 SimRotStage0 0.0.1 unknown n/a RoT pages: SLOT DATA_BASE64 RoT: active slot: slot A @@ -1057,8 +1058,9 @@ Sled serial1 A 0101010101010101010101010101010101010101010101010101010101010101 B 0202020202020202020202020202020202020202020202020202020202020202 cabooses: - SLOT BOARD NAME VERSION GIT_COMMIT SIGN - SpSlot0 SimGimletSp SimGimletSp 0.0.1 unknown n/a + SLOT BOARD NAME VERSION GIT_COMMIT SIGN + SpSlot0 SimGimletSp SimGimletSp 0.0.1 unknown n/a + Stage0 SimRotStage0 SimRotStage0 0.0.1 unknown n/a RoT pages: SLOT DATA_BASE64 RoT: active slot: slot A @@ -1079,8 +1081,9 @@ Sled serial2 A 0101010101010101010101010101010101010101010101010101010101010101 B 0202020202020202020202020202020202020202020202020202020202020202 cabooses: - SLOT BOARD NAME VERSION GIT_COMMIT SIGN - SpSlot0 SimGimletSp SimGimletSp 0.0.1 unknown n/a + SLOT BOARD NAME VERSION GIT_COMMIT SIGN + SpSlot0 SimGimletSp SimGimletSp 0.0.1 unknown n/a + Stage0 SimRotStage0 SimRotStage0 0.0.1 unknown n/a RoT pages: SLOT DATA_BASE64 RoT: active slot: slot A diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout index 80c88c1edfc..cae6cc385ce 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout @@ -20,7 +20,7 @@ INFO created directory to store extracted artifacts, path: