@@ -53,7 +53,6 @@ use nexus_types::deployment::PlanningInput;
5353use nexus_types:: deployment:: SledFilter ;
5454use nexus_types:: deployment:: SledResources ;
5555use nexus_types:: deployment:: TufRepoContentsError ;
56- use nexus_types:: deployment:: ZpoolFilter ;
5756use nexus_types:: deployment:: ZpoolName ;
5857use nexus_types:: deployment:: blueprint_zone_type;
5958use nexus_types:: external_api:: views:: SledState ;
@@ -512,15 +511,15 @@ pub struct BlueprintBuilder<'a> {
512511 /// The ID that the completed blueprint will have
513512 new_blueprint_id : BlueprintUuid ,
514513
515- // These fields are used to allocate resources for sleds.
516- input : & ' a PlanningInput ,
517-
518514 // These fields will become part of the final blueprint. See the
519515 // corresponding fields in `Blueprint`.
520516 sled_editors : BTreeMap < SledUuid , SledEditor > ,
521517 cockroachdb_setting_preserve_downgrade : CockroachDbPreserveDowngrade ,
518+ cockroachdb_fingerprint : String ,
522519 target_release_minimum_generation : Generation ,
523520 nexus_generation : Generation ,
521+ internal_dns_version : Generation ,
522+ external_dns_version : Generation ,
524523
525524 creator : String ,
526525 operations : Vec < Operation > ,
@@ -624,17 +623,19 @@ impl<'a> BlueprintBuilder<'a> {
624623
625624 let editor = match state {
626625 SledState :: Active => {
627- let subnet = input
626+ let details = input
628627 . sled_lookup ( SledFilter :: Commissioned , * sled_id)
629628 . with_context ( || {
630629 format ! (
631630 "failed to find sled details for \
632631 active sled in parent blueprint {sled_id}"
633632 )
634- } ) ?
635- . resources
636- . subnet ;
637- SledEditor :: for_existing_active ( subnet, sled_cfg. clone ( ) )
633+ } ) ?;
634+ SledEditor :: for_existing_active (
635+ Arc :: new ( details. baseboard_id . clone ( ) ) ,
636+ details. resources . subnet ,
637+ sled_cfg. clone ( ) ,
638+ )
638639 }
639640 SledState :: Decommissioned => {
640641 SledEditor :: for_existing_decommissioned ( sled_cfg. clone ( ) )
@@ -652,6 +653,7 @@ impl<'a> BlueprintBuilder<'a> {
652653 for ( sled_id, details) in input. all_sleds ( SledFilter :: Commissioned ) {
653654 if let Entry :: Vacant ( slot) = sled_editors. entry ( sled_id) {
654655 slot. insert ( SledEditor :: for_new_active (
656+ Arc :: new ( details. baseboard_id . clone ( ) ) ,
655657 details. resources . subnet ,
656658 ) ) ;
657659 }
@@ -672,14 +674,19 @@ impl<'a> BlueprintBuilder<'a> {
672674 . clone ( ) ,
673675 oximeter_read_policy,
674676 new_blueprint_id : rng. next_blueprint ( ) ,
675- input,
676677 sled_editors,
677678 cockroachdb_setting_preserve_downgrade : parent_blueprint
678679 . cockroachdb_setting_preserve_downgrade ,
680+ cockroachdb_fingerprint : input
681+ . cockroachdb_settings ( )
682+ . state_fingerprint
683+ . clone ( ) ,
679684 pending_mgs_updates : parent_blueprint. pending_mgs_updates . clone ( ) ,
680685 target_release_minimum_generation : parent_blueprint
681686 . target_release_minimum_generation ,
682687 nexus_generation : parent_blueprint. nexus_generation ,
688+ internal_dns_version : input. internal_dns_version ( ) ,
689+ external_dns_version : input. external_dns_version ( ) ,
683690 creator : creator. to_owned ( ) ,
684691 operations : Vec :: new ( ) ,
685692 comments : Vec :: new ( ) ,
@@ -738,9 +745,9 @@ impl<'a> BlueprintBuilder<'a> {
738745 // multirack (either DNS will be on a wider subnet or we need to pick a
739746 // particular rack subnet here?).
740747 let any_sled_subnet = self
741- . input
742- . all_sled_resources ( SledFilter :: Commissioned )
743- . map ( | ( _sled_id , resources ) | resources . subnet )
748+ . sled_editors
749+ . values ( )
750+ . filter_map ( |editor| editor . subnet ( ) )
744751 . next ( )
745752 . ok_or ( Error :: RackSubnetUnknownNoSleds ) ?;
746753 let rack_subnet = ReservedRackSubnet :: from_subnet ( any_sled_subnet) ;
@@ -764,10 +771,6 @@ impl<'a> BlueprintBuilder<'a> {
764771 } ) )
765772 }
766773
767- pub fn planning_input ( & self ) -> & PlanningInput {
768- & self . input
769- }
770-
771774 /// Iterates over the list of sled IDs for which we have zones.
772775 ///
773776 /// This may include decommissioned sleds.
@@ -879,19 +882,14 @@ impl<'a> BlueprintBuilder<'a> {
879882 sleds,
880883 pending_mgs_updates : self . pending_mgs_updates ,
881884 parent_blueprint_id : Some ( self . parent_blueprint . id ) ,
882- internal_dns_version : self . input . internal_dns_version ( ) ,
883- external_dns_version : self . input . external_dns_version ( ) ,
885+ internal_dns_version : self . internal_dns_version ,
886+ external_dns_version : self . external_dns_version ,
884887 target_release_minimum_generation : self
885888 . target_release_minimum_generation ,
886889 nexus_generation : self . nexus_generation ,
887- cockroachdb_fingerprint : self
888- . input
889- . cockroachdb_settings ( )
890- . state_fingerprint
891- . clone ( ) ,
890+ cockroachdb_fingerprint : self . cockroachdb_fingerprint ,
892891 cockroachdb_setting_preserve_downgrade : self
893892 . cockroachdb_setting_preserve_downgrade ,
894-
895893 clickhouse_cluster_config : self . clickhouse_cluster_config ,
896894 oximeter_read_version : self . oximeter_read_policy . version ,
897895 oximeter_read_mode : self . oximeter_read_policy . mode ,
@@ -1315,14 +1313,16 @@ impl<'a> BlueprintBuilder<'a> {
13151313 "tried to ensure mupdate override for unknown sled {sled_id}"
13161314 ) )
13171315 } ) ?;
1316+ let baseboard_id = editor. baseboard_id ( ) . ok_or_else ( || {
1317+ // All commissioned sleds have baseboards; this should never fail.
1318+ Error :: Planner ( anyhow ! (
1319+ "tried to ensure mupdate override for \
1320+ decommissioned sled {sled_id}"
1321+ ) )
1322+ } ) ?;
13181323
13191324 // Also map the editor to the corresponding PendingMgsUpdates.
1320- let sled_details = self
1321- . input
1322- . sled_lookup ( SledFilter :: InService , sled_id)
1323- . map_err ( |error| Error :: Planner ( anyhow ! ( error) ) ) ?;
1324- let pending_mgs_update =
1325- self . pending_mgs_updates . entry ( & sled_details. baseboard_id ) ;
1325+ let pending_mgs_update = self . pending_mgs_updates . entry ( baseboard_id) ;
13261326 let noop_sled_info = noop_info. sled_info_mut ( sled_id) ?;
13271327
13281328 editor
@@ -1492,14 +1492,14 @@ impl<'a> BlueprintBuilder<'a> {
14921492 image_source : BlueprintZoneImageSource ,
14931493 ) -> Result < Ensure , Error > {
14941494 let pool_name = ZpoolName :: new_external ( zpool_id) ;
1495+ let editor = self . sled_editors . get ( & sled_id) . ok_or_else ( || {
1496+ Error :: Planner ( anyhow ! (
1497+ "tried to ensure crucible zone for unknown sled {sled_id}"
1498+ ) )
1499+ } ) ?;
14951500
14961501 // If this sled already has a Crucible zone on this pool, do nothing.
1497- let has_crucible_on_this_pool = {
1498- let editor = self . sled_editors . get ( & sled_id) . ok_or_else ( || {
1499- Error :: Planner ( anyhow ! (
1500- "tried to ensure crucible zone for unknown sled {sled_id}"
1501- ) )
1502- } ) ?;
1502+ let has_crucible_on_this_pool =
15031503 editor. zones ( BlueprintZoneDisposition :: is_in_service) . any ( |z| {
15041504 matches ! (
15051505 & z. zone_type,
@@ -1509,17 +1509,19 @@ impl<'a> BlueprintBuilder<'a> {
15091509 } )
15101510 if dataset. pool_name == pool_name
15111511 )
1512- } )
1513- } ;
1512+ } ) ;
15141513 if has_crucible_on_this_pool {
15151514 return Ok ( Ensure :: NotNeeded ) ;
15161515 }
15171516
1518- let sled_info = self . sled_resources ( sled_id) ?;
1519- if !sled_info. zpools . contains_key ( & zpool_id) {
1517+ // Double-check that our caller didn't pass a bad sled/zpool combo.
1518+ if !editor
1519+ . disks ( BlueprintPhysicalDiskDisposition :: is_in_service)
1520+ . any ( |disk| disk. pool_id == zpool_id)
1521+ {
15201522 return Err ( Error :: Planner ( anyhow ! (
15211523 "adding crucible zone for sled {:?}: \
1522- attempted to use unknown zpool {:?}",
1524+ attempted to use unknown zpool {:?}",
15231525 sled_id,
15241526 pool_name
15251527 ) ) ) ;
@@ -2114,17 +2116,12 @@ impl<'a> BlueprintBuilder<'a> {
21142116 ) )
21152117 } ) ?;
21162118
2117- // We'll check both the disks available to this sled per our current
2118- // blueprint and the list of all in-service zpools on this sled per our
2119- // planning input, and only pick zpools that are available in both.
2120- let current_sled_disks = editor
2119+ // Only choose from zpools that are in-service.
2120+ let in_service_zpools = editor
21212121 . disks ( BlueprintPhysicalDiskDisposition :: is_in_service)
21222122 . map ( |disk_config| disk_config. pool_id )
21232123 . collect :: < BTreeSet < _ > > ( ) ;
21242124
2125- let all_in_service_zpools =
2126- self . sled_resources ( sled_id) ?. all_zpools ( ZpoolFilter :: InService ) ;
2127-
21282125 // We refuse to choose a zpool for a zone of a given `zone_kind` if this
21292126 // sled already has a durable zone of that kind on the same zpool. Build
21302127 // up a set of invalid zpools for this sled/kind pair.
@@ -2142,31 +2139,14 @@ impl<'a> BlueprintBuilder<'a> {
21422139 skip_zpools. insert ( & zone_config. filesystem_pool ) ;
21432140 }
21442141
2145- for & zpool_id in all_in_service_zpools {
2142+ for zpool_id in in_service_zpools {
21462143 let zpool_name = ZpoolName :: new_external ( zpool_id) ;
2147- if !skip_zpools. contains ( & zpool_name)
2148- && current_sled_disks. contains ( & zpool_id)
2149- {
2144+ if !skip_zpools. contains ( & zpool_name) {
21502145 return Ok ( zpool_name) ;
21512146 }
21522147 }
2153- Err ( Error :: NoAvailableZpool { sled_id, kind : zone_kind } )
2154- }
21552148
2156- /// Returns the resources for a sled that hasn't been decommissioned.
2157- fn sled_resources (
2158- & self ,
2159- sled_id : SledUuid ,
2160- ) -> Result < & ' a SledResources , Error > {
2161- let details = self
2162- . input
2163- . sled_lookup ( SledFilter :: Commissioned , sled_id)
2164- . map_err ( |error| {
2165- Error :: Planner ( anyhow ! ( error) . context ( format ! (
2166- "for sled {sled_id}, error looking up resources"
2167- ) ) )
2168- } ) ?;
2169- Ok ( & details. resources )
2149+ Err ( Error :: NoAvailableZpool { sled_id, kind : zone_kind } )
21702150 }
21712151
21722152 /// Determine the number of desired external DNS zones by counting
0 commit comments