@@ -337,6 +337,10 @@ struct SledAddArgs {
337
337
/// number of disks or pools
338
338
#[ clap( short = 'd' , long, visible_alias = "npools" , default_value_t = SledBuilder :: DEFAULT_NPOOLS ) ]
339
339
ndisks : u8 ,
340
+
341
+ /// The policy for the sled.
342
+ #[ clap( long, value_enum, default_value_t = SledPolicyOpt :: InService ) ]
343
+ policy : SledPolicyOpt ,
340
344
}
341
345
342
346
#[ derive( Debug , Args ) ]
@@ -847,6 +851,44 @@ struct LoadExampleArgs {
847
851
/// Do not create entries for disks in the blueprint.
848
852
#[ clap( long) ]
849
853
no_disks_in_blueprint : bool ,
854
+
855
+ /// Set a 0-indexed sled's policy
856
+ #[ clap( long, value_name = "INDEX:POLICY" ) ]
857
+ sled_policy : Vec < LoadExampleSledPolicy > ,
858
+ }
859
+
860
+ #[ derive( Clone , Debug ) ]
861
+ struct LoadExampleSledPolicy {
862
+ /// The index of the sled to set the policy for.
863
+ index : usize ,
864
+
865
+ /// The policy to set.
866
+ policy : SledPolicy ,
867
+ }
868
+
869
+ impl FromStr for LoadExampleSledPolicy {
870
+ type Err = anyhow:: Error ;
871
+
872
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
873
+ let ( index, policy) = s
874
+ . split_once ( ':' )
875
+ . context ( "invalid format, expected <index>:<policy>" ) ?;
876
+ let index = index. parse ( ) . with_context ( || {
877
+ format ! ( "error parsing sled index `{index}` as a usize" )
878
+ } ) ?;
879
+ let policy = SledPolicyOpt :: from_str (
880
+ policy, /* ignore_case */ false ,
881
+ )
882
+ . map_err ( |_message| {
883
+ // _message is just something like "invalid variant: <value>".
884
+ // We choose to use our own message instead.
885
+ anyhow ! (
886
+ "invalid sled policy `{policy}` (possible values: {})" ,
887
+ SledPolicyOpt :: value_variants( ) . iter( ) . join( ", " ) ,
888
+ )
889
+ } ) ?;
890
+ Ok ( LoadExampleSledPolicy { index, policy : policy. into ( ) } )
891
+ }
850
892
}
851
893
852
894
#[ derive( Debug , Args ) ]
@@ -954,7 +996,10 @@ fn cmd_sled_add(
954
996
) -> anyhow:: Result < Option < String > > {
955
997
let mut state = sim. current_state ( ) . to_mut ( ) ;
956
998
let sled_id = add. sled_id . unwrap_or_else ( || state. rng_mut ( ) . next_sled_id ( ) ) ;
957
- let new_sled = SledBuilder :: new ( ) . id ( sled_id) . npools ( add. ndisks ) ;
999
+ let new_sled = SledBuilder :: new ( )
1000
+ . id ( sled_id)
1001
+ . npools ( add. ndisks )
1002
+ . policy ( add. policy . into ( ) ) ;
958
1003
let system = state. system_mut ( ) ;
959
1004
system. description_mut ( ) . sled ( new_sled) ?;
960
1005
// Figure out what serial number this sled was assigned.
@@ -1008,7 +1053,7 @@ fn cmd_sled_show(
1008
1053
let sled = planning_input. sled_lookup ( args. filter , sled_id) ?;
1009
1054
let sled_resources = & sled. resources ;
1010
1055
let mut s = String :: new ( ) ;
1011
- swriteln ! ( s, "sled {}" , sled_id) ;
1056
+ swriteln ! ( s, "sled {} ({}, {}) " , sled_id, sled . policy , sled . state ) ;
1012
1057
swriteln ! ( s, "serial {}" , sled. baseboard_id. serial_number) ;
1013
1058
swriteln ! ( s, "subnet {}" , sled_resources. subnet. net( ) ) ;
1014
1059
swriteln ! ( s, "SP active version: {:?}" , sp_active_version) ;
@@ -2006,21 +2051,26 @@ fn cmd_load_example(
2006
2051
} ;
2007
2052
let rng = state. rng_mut ( ) . next_example_rng ( ) ;
2008
2053
2009
- let ( example, blueprint) =
2010
- ExampleSystemBuilder :: new_with_rng ( & sim. log , rng)
2011
- . nsleds ( args. nsleds )
2012
- . ndisks_per_sled ( args. ndisks_per_sled )
2013
- . nexus_count (
2014
- state
2015
- . config_mut ( )
2016
- . num_nexus ( )
2017
- . map_or ( NEXUS_REDUNDANCY , |n| n. into ( ) ) ,
2018
- )
2019
- . external_dns_count ( 3 )
2020
- . context ( "invalid external DNS zone count" ) ?
2021
- . create_zones ( !args. no_zones )
2022
- . create_disks_in_blueprint ( !args. no_disks_in_blueprint )
2023
- . build ( ) ;
2054
+ let mut builder = ExampleSystemBuilder :: new_with_rng ( & sim. log , rng)
2055
+ . nsleds ( args. nsleds )
2056
+ . ndisks_per_sled ( args. ndisks_per_sled )
2057
+ . nexus_count (
2058
+ state
2059
+ . config_mut ( )
2060
+ . num_nexus ( )
2061
+ . map_or ( NEXUS_REDUNDANCY , |n| n. into ( ) ) ,
2062
+ )
2063
+ . external_dns_count ( 3 )
2064
+ . context ( "invalid external DNS zone count" ) ?
2065
+ . create_zones ( !args. no_zones )
2066
+ . create_disks_in_blueprint ( !args. no_disks_in_blueprint ) ;
2067
+ for sled_policy in args. sled_policy {
2068
+ builder = builder
2069
+ . with_sled_policy ( sled_policy. index , sled_policy. policy )
2070
+ . context ( "setting sled policy" ) ?;
2071
+ }
2072
+
2073
+ let ( example, blueprint) = builder. build ( ) ;
2024
2074
2025
2075
// Generate the internal and external DNS configs based on the blueprint.
2026
2076
let sleds_by_id = make_sleds_by_id ( & example. system ) ?;
0 commit comments