Skip to content

Commit 05b806a

Browse files
authored
[22/n] [reconfigurator-cli] specify sled by serial number (#8489)
These serial numbers are somewhat easier to parse in many cases, and also synergize with the next commit in this stack (which allows setting a specific policy on each sled while loading the initial example). Switch one of the tests over as an example -- I hope its intent becomes clearer.
1 parent fc4d99d commit 05b806a

File tree

6 files changed

+192
-86
lines changed

6 files changed

+192
-86
lines changed

dev-tools/reconfigurator-cli/src/lib.rs

Lines changed: 96 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use omicron_uuid_kinds::SledUuid;
5151
use omicron_uuid_kinds::VnicUuid;
5252
use omicron_uuid_kinds::{BlueprintUuid, MupdateOverrideUuid};
5353
use std::borrow::Cow;
54+
use std::convert::Infallible;
5455
use std::fmt::{self, Write};
5556
use std::io::IsTerminal;
5657
use std::num::ParseIntError;
@@ -341,7 +342,7 @@ struct SledAddArgs {
341342
#[derive(Debug, Args)]
342343
struct SledArgs {
343344
/// id of the sled
344-
sled_id: SledUuid,
345+
sled_id: SledOpt,
345346

346347
/// Filter to match sled ID against
347348
#[clap(short = 'F', long, value_enum, default_value_t = SledFilter::Commissioned)]
@@ -351,7 +352,7 @@ struct SledArgs {
351352
#[derive(Debug, Args)]
352353
struct SledSetPolicyArgs {
353354
/// id of the sled
354-
sled_id: SledUuid,
355+
sled_id: SledOpt,
355356

356357
/// The policy to set for the sled
357358
#[clap(value_enum)]
@@ -392,7 +393,7 @@ impl From<SledPolicyOpt> for SledPolicy {
392393
#[derive(Debug, Args)]
393394
struct SledUpdateSpArgs {
394395
/// id of the sled
395-
sled_id: SledUuid,
396+
sled_id: SledOpt,
396397

397398
/// sets the version reported for the SP active slot
398399
#[clap(long, required_unless_present_any = &["inactive"])]
@@ -406,7 +407,7 @@ struct SledUpdateSpArgs {
406407
#[derive(Debug, Args)]
407408
struct SledRemoveArgs {
408409
/// id of the sled
409-
sled_id: SledUuid,
410+
sled_id: SledOpt,
410411
}
411412

412413
#[derive(Debug, Args)]
@@ -452,10 +453,10 @@ enum BlueprintEditCommands {
452453
/// add a Nexus instance to a particular sled
453454
AddNexus {
454455
/// sled on which to deploy the new instance
455-
sled_id: SledUuid,
456+
sled_id: SledOpt,
456457
},
457458
/// add a CockroachDB instance to a particular sled
458-
AddCockroach { sled_id: SledUuid },
459+
AddCockroach { sled_id: SledOpt },
459460
/// set the image source for a zone
460461
SetZoneImage {
461462
/// id of zone whose image to set
@@ -466,7 +467,7 @@ enum BlueprintEditCommands {
466467
/// set the remove_mupdate_override field for a sled
467468
SetRemoveMupdateOverride {
468469
/// sled to set the field on
469-
sled_id: SledUuid,
470+
sled_id: SledOpt,
470471

471472
/// the UUID to set the field to, or "unset"
472473
value: MupdateOverrideUuidOpt,
@@ -521,17 +522,66 @@ enum BlueprintEditDebugCommands {
521522
/// the sled from the blueprint.
522523
RemoveSled {
523524
/// the sled to remove
524-
sled: SledUuid,
525+
sled: SledOpt,
525526
},
526527

527528
/// Bump a sled's generation number, even if nothing else about the sled has
528529
/// changed.
529530
ForceSledGenerationBump {
530531
/// the sled to bump the sled-agent generation number of
531-
sled: SledUuid,
532+
sled: SledOpt,
532533
},
533534
}
534535

536+
/// Identifies a sled in a system.
537+
#[derive(Clone, Debug)]
538+
enum SledOpt {
539+
/// Identifies a sled by its UUID.
540+
Uuid(SledUuid),
541+
/// Identifies a sled by its serial number.
542+
Serial(String),
543+
}
544+
545+
impl SledOpt {
546+
/// Resolves this sled option into a sled UUID.
547+
fn to_sled_id(
548+
&self,
549+
description: &SystemDescription,
550+
) -> anyhow::Result<SledUuid> {
551+
match self {
552+
SledOpt::Uuid(uuid) => Ok(*uuid),
553+
SledOpt::Serial(serial) => description.serial_to_sled_id(&serial),
554+
}
555+
}
556+
}
557+
558+
impl FromStr for SledOpt {
559+
type Err = Infallible;
560+
561+
fn from_str(s: &str) -> Result<Self, Self::Err> {
562+
// If the sled looks like a UUID, parse it as that.
563+
if let Ok(uuid) = s.parse::<SledUuid>() {
564+
return Ok(SledOpt::Uuid(uuid));
565+
}
566+
567+
// We treat anything that doesn't parse as a UUID as a serial number.
568+
//
569+
// Can we do something more intelligent here, like looking for a
570+
// particular prefix? In principle, yes, but in reality there are
571+
// several different sources of serial numbers:
572+
//
573+
// * simulated sleds ("serial0", "serial1", ...)
574+
// * real sleds ("BRM42220014")
575+
// * a4x2 ("g0", "g1", ...)
576+
// * single-sled dev deployments
577+
//
578+
// and possibly more. We could exhaustively enumerate all of them, but
579+
// it's easier to assume that if it doesn't look like a UUID, it's a
580+
// serial number.
581+
Ok(Self::Serial(s.to_owned()))
582+
}
583+
}
584+
535585
#[derive(Clone, Debug)]
536586
enum BlueprintIdOpt {
537587
/// use the target blueprint
@@ -905,23 +955,33 @@ fn cmd_sled_add(
905955
let mut state = sim.current_state().to_mut();
906956
let sled_id = add.sled_id.unwrap_or_else(|| state.rng_mut().next_sled_id());
907957
let new_sled = SledBuilder::new().id(sled_id).npools(add.ndisks);
908-
state.system_mut().description_mut().sled(new_sled)?;
958+
let system = state.system_mut();
959+
system.description_mut().sled(new_sled)?;
960+
// Figure out what serial number this sled was assigned.
961+
let added_sled = system
962+
.description()
963+
.get_sled(sled_id)
964+
.expect("we just added this sled");
965+
let serial = match added_sled.sp_state() {
966+
Some((_, sp_state)) => sp_state.serial_number.clone(),
967+
None => "(none)".to_owned(),
968+
};
909969
sim.commit_and_bump(
910-
format!("reconfigurator-cli sled-add: {sled_id}"),
970+
format!("reconfigurator-cli sled-add: {sled_id} (serial: {serial})"),
911971
state,
912972
);
913973

914-
Ok(Some(format!("added sled {}", sled_id)))
974+
Ok(Some(format!("added sled {} (serial: {})", sled_id, serial)))
915975
}
916976

917977
fn cmd_sled_remove(
918978
sim: &mut ReconfiguratorSim,
919979
args: SledRemoveArgs,
920980
) -> anyhow::Result<Option<String>> {
921981
let mut state = sim.current_state().to_mut();
922-
let sled_id = args.sled_id;
923-
state
924-
.system_mut()
982+
let system = state.system_mut();
983+
let sled_id = args.sled_id.to_sled_id(system.description())?;
984+
system
925985
.description_mut()
926986
.sled_remove(sled_id)
927987
.context("failed to remove sled")?;
@@ -938,7 +998,7 @@ fn cmd_sled_show(
938998
) -> anyhow::Result<Option<String>> {
939999
let state = sim.current_state();
9401000
let description = state.system().description();
941-
let sled_id = args.sled_id;
1001+
let sled_id = args.sled_id.to_sled_id(description)?;
9421002
let sp_active_version = description.sled_sp_active_version(sled_id)?;
9431003
let sp_inactive_version = description.sled_sp_inactive_version(sled_id)?;
9441004
let planning_input = description
@@ -966,18 +1026,17 @@ fn cmd_sled_set_policy(
9661026
args: SledSetPolicyArgs,
9671027
) -> anyhow::Result<Option<String>> {
9681028
let mut state = sim.current_state().to_mut();
969-
state
970-
.system_mut()
971-
.description_mut()
972-
.sled_set_policy(args.sled_id, args.policy.into())?;
1029+
let system = state.system_mut();
1030+
let sled_id = args.sled_id.to_sled_id(system.description())?;
1031+
system.description_mut().sled_set_policy(sled_id, args.policy.into())?;
9731032
sim.commit_and_bump(
9741033
format!(
9751034
"reconfigurator-cli sled-set-policy: {} to {}",
976-
args.sled_id, args.policy,
1035+
sled_id, args.policy,
9771036
),
9781037
state,
9791038
);
980-
Ok(Some(format!("set sled {} policy to {}", args.sled_id, args.policy)))
1039+
Ok(Some(format!("set sled {} policy to {}", sled_id, args.policy)))
9811040
}
9821041

9831042
fn cmd_sled_update_sp(
@@ -998,26 +1057,24 @@ fn cmd_sled_update_sp(
9981057
);
9991058

10001059
let mut state = sim.current_state().to_mut();
1001-
state.system_mut().description_mut().sled_update_sp_versions(
1002-
args.sled_id,
1060+
let system = state.system_mut();
1061+
let sled_id = args.sled_id.to_sled_id(system.description())?;
1062+
system.description_mut().sled_update_sp_versions(
1063+
sled_id,
10031064
args.active,
10041065
args.inactive,
10051066
)?;
10061067

10071068
sim.commit_and_bump(
10081069
format!(
10091070
"reconfigurator-cli sled-update-sp: {}: {}",
1010-
args.sled_id,
1071+
sled_id,
10111072
labels.join(", "),
10121073
),
10131074
state,
10141075
);
10151076

1016-
Ok(Some(format!(
1017-
"set sled {} SP versions: {}",
1018-
args.sled_id,
1019-
labels.join(", ")
1020-
)))
1077+
Ok(Some(format!("set sled {} SP versions: {}", sled_id, labels.join(", "))))
10211078
}
10221079

10231080
fn cmd_inventory_list(
@@ -1226,18 +1283,21 @@ fn cmd_blueprint_edit(
12261283

12271284
let label = match args.edit_command {
12281285
BlueprintEditCommands::AddNexus { sled_id } => {
1286+
let sled_id = sled_id.to_sled_id(system.description())?;
12291287
builder
12301288
.sled_add_zone_nexus(sled_id)
12311289
.context("failed to add Nexus zone")?;
12321290
format!("added Nexus zone to sled {}", sled_id)
12331291
}
12341292
BlueprintEditCommands::AddCockroach { sled_id } => {
1293+
let sled_id = sled_id.to_sled_id(system.description())?;
12351294
builder
12361295
.sled_add_zone_cockroachdb(sled_id)
12371296
.context("failed to add CockroachDB zone")?;
12381297
format!("added CockroachDB zone to sled {}", sled_id)
12391298
}
12401299
BlueprintEditCommands::SetRemoveMupdateOverride { sled_id, value } => {
1300+
let sled_id = sled_id.to_sled_id(system.description())?;
12411301
builder
12421302
.sled_set_remove_mupdate_override(sled_id, value.into())
12431303
.context("failed to set remove_mupdate_override")?;
@@ -1344,15 +1404,17 @@ fn cmd_blueprint_edit(
13441404
BlueprintEditCommands::Debug {
13451405
command: BlueprintEditDebugCommands::RemoveSled { sled },
13461406
} => {
1347-
builder.debug_sled_remove(sled)?;
1348-
format!("debug: removed sled {sled} from blueprint")
1407+
let sled_id = sled.to_sled_id(system.description())?;
1408+
builder.debug_sled_remove(sled_id)?;
1409+
format!("debug: removed sled {sled_id} from blueprint")
13491410
}
13501411
BlueprintEditCommands::Debug {
13511412
command:
13521413
BlueprintEditDebugCommands::ForceSledGenerationBump { sled },
13531414
} => {
1354-
builder.debug_sled_force_generation_bump(sled)?;
1355-
format!("debug: forced sled {sled} generation bump")
1415+
let sled_id = sled.to_sled_id(system.description())?;
1416+
builder.debug_sled_force_generation_bump(sled_id)?;
1417+
format!("debug: forced sled {sled_id} generation bump")
13561418
}
13571419
};
13581420

dev-tools/reconfigurator-cli/tests/input/cmds-set-remove-mupdate-override.txt

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Load example system with 7 sleds:
22
#
3-
# sled 0: unset -> unset (unchanged)
4-
# sled 1: unset -> set
5-
# sled 2: set -> unset
6-
# sled 3: set -> set (unchanged)
7-
# sled 4: set -> set (changed)
8-
# sled 5: set -> set (unchanged) but change something else
9-
# sled 6: set -> sled removed
3+
# serial0: unset -> unset (unchanged)
4+
# serial1: unset -> set
5+
# serial2: set -> unset
6+
# serial3: set -> set (unchanged)
7+
# serial4: set -> set (changed)
8+
# serial5: set -> set (unchanged) but change something else
9+
# serial6: set -> sled removed
1010
#
1111
# We'll also add another sled below (new_sled_id) with
1212
# remove_mupdate_override set.
@@ -15,28 +15,29 @@
1515
# outputs minimal.
1616

1717
load-example --nsleds 7 --ndisks-per-sled 0 --no-zones
18+
sled-list
1819

1920
# Set the field on sleds 2-6 (0-indexed).
20-
blueprint-edit latest set-remove-mupdate-override 9a867dc9-d505-427f-9eff-cdb1d4d9bd73 00000000-0000-0000-0000-000000000000
21-
blueprint-edit latest set-remove-mupdate-override aff6c093-197d-42c5-ad80-9f10ba051a34 00000000-0000-0000-0000-000000000000
22-
blueprint-edit latest set-remove-mupdate-override b82ede02-399c-48c6-a1de-411df4fa49a7 00000000-0000-0000-0000-000000000000
23-
blueprint-edit latest set-remove-mupdate-override d81c6a84-79b8-4958-ae41-ea46c9b19763 00000000-0000-0000-0000-000000000000
24-
blueprint-edit latest set-remove-mupdate-override e96e226f-4ed9-4c01-91b9-69a9cd076c9e 00000000-0000-0000-0000-000000000000
21+
blueprint-edit latest set-remove-mupdate-override serial2 00000000-0000-0000-0000-000000000000
22+
blueprint-edit latest set-remove-mupdate-override serial3 00000000-0000-0000-0000-000000000000
23+
blueprint-edit latest set-remove-mupdate-override serial4 00000000-0000-0000-0000-000000000000
24+
blueprint-edit latest set-remove-mupdate-override serial5 00000000-0000-0000-0000-000000000000
25+
blueprint-edit latest set-remove-mupdate-override serial6 00000000-0000-0000-0000-000000000000
2526

2627
blueprint-show latest
2728

2829
# Now make another blueprint, starting by adding a new sled and removing sled 6.
2930
sled-add --ndisks 0
30-
blueprint-edit latest debug remove-sled e96e226f-4ed9-4c01-91b9-69a9cd076c9e
31-
sled-remove e96e226f-4ed9-4c01-91b9-69a9cd076c9e
31+
blueprint-edit latest debug remove-sled serial6
32+
sled-remove serial6
3233
inventory-generate
3334

3435
# Edit sleds 1, 2, 4, 5, and the new one.
35-
blueprint-edit latest set-remove-mupdate-override 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 ffffffff-ffff-ffff-ffff-ffffffffffff
36-
blueprint-edit latest set-remove-mupdate-override 9a867dc9-d505-427f-9eff-cdb1d4d9bd73 unset
37-
blueprint-edit latest set-remove-mupdate-override b82ede02-399c-48c6-a1de-411df4fa49a7 ffffffff-ffff-ffff-ffff-ffffffffffff
38-
blueprint-edit latest debug force-sled-generation-bump d81c6a84-79b8-4958-ae41-ea46c9b19763
39-
blueprint-edit latest set-remove-mupdate-override 00320471-945d-413c-85e7-03e091a70b3c ffffffff-ffff-ffff-ffff-ffffffffffff
36+
blueprint-edit latest set-remove-mupdate-override serial1 ffffffff-ffff-ffff-ffff-ffffffffffff
37+
blueprint-edit latest set-remove-mupdate-override serial2 unset
38+
blueprint-edit latest set-remove-mupdate-override serial4 ffffffff-ffff-ffff-ffff-ffffffffffff
39+
blueprint-edit latest debug force-sled-generation-bump serial5
40+
blueprint-edit latest set-remove-mupdate-override serial7 ffffffff-ffff-ffff-ffff-ffffffffffff
4041

4142
blueprint-diff 7f976e0d-d2a5-4eeb-9e82-c82bc2824aba latest
4243

dev-tools/reconfigurator-cli/tests/output/cmds-add-sled-no-disks-stdout

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ f45ba181-4b56-42cc-a762-874d90184a43 0 <REDACTED_TIMESTAMP>
2525

2626
> # Add a new sled with no disks.
2727
> sled-add --ndisks 0
28-
added sled 00320471-945d-413c-85e7-03e091a70b3c
28+
added sled 00320471-945d-413c-85e7-03e091a70b3c (serial: serial3)
2929

3030

3131
> # Generate a new inventory collection that includes that sled.

0 commit comments

Comments
 (0)