@@ -51,6 +51,7 @@ use omicron_uuid_kinds::SledUuid;
51
51
use omicron_uuid_kinds:: VnicUuid ;
52
52
use omicron_uuid_kinds:: { BlueprintUuid , MupdateOverrideUuid } ;
53
53
use std:: borrow:: Cow ;
54
+ use std:: convert:: Infallible ;
54
55
use std:: fmt:: { self , Write } ;
55
56
use std:: io:: IsTerminal ;
56
57
use std:: num:: ParseIntError ;
@@ -341,7 +342,7 @@ struct SledAddArgs {
341
342
#[ derive( Debug , Args ) ]
342
343
struct SledArgs {
343
344
/// id of the sled
344
- sled_id : SledUuid ,
345
+ sled_id : SledOpt ,
345
346
346
347
/// Filter to match sled ID against
347
348
#[ clap( short = 'F' , long, value_enum, default_value_t = SledFilter :: Commissioned ) ]
@@ -351,7 +352,7 @@ struct SledArgs {
351
352
#[ derive( Debug , Args ) ]
352
353
struct SledSetPolicyArgs {
353
354
/// id of the sled
354
- sled_id : SledUuid ,
355
+ sled_id : SledOpt ,
355
356
356
357
/// The policy to set for the sled
357
358
#[ clap( value_enum) ]
@@ -392,7 +393,7 @@ impl From<SledPolicyOpt> for SledPolicy {
392
393
#[ derive( Debug , Args ) ]
393
394
struct SledUpdateSpArgs {
394
395
/// id of the sled
395
- sled_id : SledUuid ,
396
+ sled_id : SledOpt ,
396
397
397
398
/// sets the version reported for the SP active slot
398
399
#[ clap( long, required_unless_present_any = & [ "inactive" ] ) ]
@@ -406,7 +407,7 @@ struct SledUpdateSpArgs {
406
407
#[ derive( Debug , Args ) ]
407
408
struct SledRemoveArgs {
408
409
/// id of the sled
409
- sled_id : SledUuid ,
410
+ sled_id : SledOpt ,
410
411
}
411
412
412
413
#[ derive( Debug , Args ) ]
@@ -452,10 +453,10 @@ enum BlueprintEditCommands {
452
453
/// add a Nexus instance to a particular sled
453
454
AddNexus {
454
455
/// sled on which to deploy the new instance
455
- sled_id : SledUuid ,
456
+ sled_id : SledOpt ,
456
457
} ,
457
458
/// add a CockroachDB instance to a particular sled
458
- AddCockroach { sled_id : SledUuid } ,
459
+ AddCockroach { sled_id : SledOpt } ,
459
460
/// set the image source for a zone
460
461
SetZoneImage {
461
462
/// id of zone whose image to set
@@ -466,7 +467,7 @@ enum BlueprintEditCommands {
466
467
/// set the remove_mupdate_override field for a sled
467
468
SetRemoveMupdateOverride {
468
469
/// sled to set the field on
469
- sled_id : SledUuid ,
470
+ sled_id : SledOpt ,
470
471
471
472
/// the UUID to set the field to, or "unset"
472
473
value : MupdateOverrideUuidOpt ,
@@ -521,17 +522,66 @@ enum BlueprintEditDebugCommands {
521
522
/// the sled from the blueprint.
522
523
RemoveSled {
523
524
/// the sled to remove
524
- sled : SledUuid ,
525
+ sled : SledOpt ,
525
526
} ,
526
527
527
528
/// Bump a sled's generation number, even if nothing else about the sled has
528
529
/// changed.
529
530
ForceSledGenerationBump {
530
531
/// the sled to bump the sled-agent generation number of
531
- sled : SledUuid ,
532
+ sled : SledOpt ,
532
533
} ,
533
534
}
534
535
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
+
535
585
#[ derive( Clone , Debug ) ]
536
586
enum BlueprintIdOpt {
537
587
/// use the target blueprint
@@ -905,23 +955,33 @@ fn cmd_sled_add(
905
955
let mut state = sim. current_state ( ) . to_mut ( ) ;
906
956
let sled_id = add. sled_id . unwrap_or_else ( || state. rng_mut ( ) . next_sled_id ( ) ) ;
907
957
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
+ } ;
909
969
sim. commit_and_bump (
910
- format ! ( "reconfigurator-cli sled-add: {sled_id}" ) ,
970
+ format ! ( "reconfigurator-cli sled-add: {sled_id} (serial: {serial}) " ) ,
911
971
state,
912
972
) ;
913
973
914
- Ok ( Some ( format ! ( "added sled {}" , sled_id) ) )
974
+ Ok ( Some ( format ! ( "added sled {} (serial: {}) " , sled_id, serial ) ) )
915
975
}
916
976
917
977
fn cmd_sled_remove (
918
978
sim : & mut ReconfiguratorSim ,
919
979
args : SledRemoveArgs ,
920
980
) -> anyhow:: Result < Option < String > > {
921
981
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
925
985
. description_mut ( )
926
986
. sled_remove ( sled_id)
927
987
. context ( "failed to remove sled" ) ?;
@@ -938,7 +998,7 @@ fn cmd_sled_show(
938
998
) -> anyhow:: Result < Option < String > > {
939
999
let state = sim. current_state ( ) ;
940
1000
let description = state. system ( ) . description ( ) ;
941
- let sled_id = args. sled_id ;
1001
+ let sled_id = args. sled_id . to_sled_id ( description ) ? ;
942
1002
let sp_active_version = description. sled_sp_active_version ( sled_id) ?;
943
1003
let sp_inactive_version = description. sled_sp_inactive_version ( sled_id) ?;
944
1004
let planning_input = description
@@ -966,18 +1026,17 @@ fn cmd_sled_set_policy(
966
1026
args : SledSetPolicyArgs ,
967
1027
) -> anyhow:: Result < Option < String > > {
968
1028
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 ( ) ) ?;
973
1032
sim. commit_and_bump (
974
1033
format ! (
975
1034
"reconfigurator-cli sled-set-policy: {} to {}" ,
976
- args . sled_id, args. policy,
1035
+ sled_id, args. policy,
977
1036
) ,
978
1037
state,
979
1038
) ;
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) ) )
981
1040
}
982
1041
983
1042
fn cmd_sled_update_sp (
@@ -998,26 +1057,24 @@ fn cmd_sled_update_sp(
998
1057
) ;
999
1058
1000
1059
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,
1003
1064
args. active ,
1004
1065
args. inactive ,
1005
1066
) ?;
1006
1067
1007
1068
sim. commit_and_bump (
1008
1069
format ! (
1009
1070
"reconfigurator-cli sled-update-sp: {}: {}" ,
1010
- args . sled_id,
1071
+ sled_id,
1011
1072
labels. join( ", " ) ,
1012
1073
) ,
1013
1074
state,
1014
1075
) ;
1015
1076
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( ", " ) ) ) )
1021
1078
}
1022
1079
1023
1080
fn cmd_inventory_list (
@@ -1226,18 +1283,21 @@ fn cmd_blueprint_edit(
1226
1283
1227
1284
let label = match args. edit_command {
1228
1285
BlueprintEditCommands :: AddNexus { sled_id } => {
1286
+ let sled_id = sled_id. to_sled_id ( system. description ( ) ) ?;
1229
1287
builder
1230
1288
. sled_add_zone_nexus ( sled_id)
1231
1289
. context ( "failed to add Nexus zone" ) ?;
1232
1290
format ! ( "added Nexus zone to sled {}" , sled_id)
1233
1291
}
1234
1292
BlueprintEditCommands :: AddCockroach { sled_id } => {
1293
+ let sled_id = sled_id. to_sled_id ( system. description ( ) ) ?;
1235
1294
builder
1236
1295
. sled_add_zone_cockroachdb ( sled_id)
1237
1296
. context ( "failed to add CockroachDB zone" ) ?;
1238
1297
format ! ( "added CockroachDB zone to sled {}" , sled_id)
1239
1298
}
1240
1299
BlueprintEditCommands :: SetRemoveMupdateOverride { sled_id, value } => {
1300
+ let sled_id = sled_id. to_sled_id ( system. description ( ) ) ?;
1241
1301
builder
1242
1302
. sled_set_remove_mupdate_override ( sled_id, value. into ( ) )
1243
1303
. context ( "failed to set remove_mupdate_override" ) ?;
@@ -1344,15 +1404,17 @@ fn cmd_blueprint_edit(
1344
1404
BlueprintEditCommands :: Debug {
1345
1405
command : BlueprintEditDebugCommands :: RemoveSled { sled } ,
1346
1406
} => {
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" )
1349
1410
}
1350
1411
BlueprintEditCommands :: Debug {
1351
1412
command :
1352
1413
BlueprintEditDebugCommands :: ForceSledGenerationBump { sled } ,
1353
1414
} => {
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" )
1356
1418
}
1357
1419
} ;
1358
1420
0 commit comments