Skip to content

Commit 58ee63b

Browse files
authored
[1/n] [reconfigurator-planning] move determination of add/update zones into a separate method (#8920)
I'd like to determine condition 4 of whether to perform updates (all deployment units are at known versions) by looking at the blueprint after noop conversions have been applied. We could either try and guess what would happen by looking at the noop info, or just move this determination to after noop updates have been applied. Also make the planning report store the reasons zone adds and updates are blocked, and print them as part of the planning report. There are no behavior changes in this PR.
1 parent 718ded7 commit 58ee63b

File tree

5 files changed

+129
-79
lines changed

5 files changed

+129
-79
lines changed

dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -505,9 +505,12 @@ planning report for blueprint a5a8f242-ffa5-473c-8efd-2acf2dc0b736:
505505
chicken switches:
506506
add zones with mupdate override: false
507507

508-
* waiting on MUPdate overrides
509-
* MUPdate overrides exist
510-
* zone updates waiting on MUPdate overrides
508+
* zone adds waiting on blockers
509+
* zone adds and updates are blocked:
510+
- current target release generation (2) is lower than minimum required by blueprint (3)
511+
- sleds have remove mupdate override set in blueprint: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6, d81c6a84-79b8-4958-ae41-ea46c9b19763
512+
- sleds have mupdate override errors: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c
513+
* zone updates waiting on zone add blockers
511514

512515

513516

@@ -880,9 +883,11 @@ planning report for blueprint 626487fa-7139-45ec-8416-902271fc730b:
880883
chicken switches:
881884
add zones with mupdate override: false
882885

883-
* waiting on MUPdate overrides
884-
* MUPdate overrides exist
885-
* zone updates waiting on MUPdate overrides
886+
* zone adds waiting on blockers
887+
* zone adds and updates are blocked:
888+
- sleds have remove mupdate override set in blueprint: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6, d81c6a84-79b8-4958-ae41-ea46c9b19763
889+
- sleds have mupdate override errors: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c
890+
* zone updates waiting on zone add blockers
886891

887892

888893
> blueprint-diff latest
@@ -1104,9 +1109,12 @@ chicken switches:
11041109
add zones with mupdate override: false
11051110

11061111
* noop converting 6/6 install-dataset zones to artifact store on sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6
1107-
* waiting on MUPdate overrides
1108-
* MUPdate overrides exist
1109-
* zone updates waiting on MUPdate overrides
1112+
* zone adds waiting on blockers
1113+
* zone adds and updates are blocked:
1114+
- current target release generation (3) is lower than minimum required by blueprint (4)
1115+
- sleds have remove mupdate override set in blueprint: d81c6a84-79b8-4958-ae41-ea46c9b19763
1116+
- sleds have mupdate override errors: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c
1117+
* zone updates waiting on zone add blockers
11101118

11111119

11121120

@@ -1393,9 +1401,11 @@ chicken switches:
13931401
add zones with mupdate override: false
13941402

13951403
* skipping noop zone image source check on sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6: all 6 zones are already from artifacts
1396-
* waiting on MUPdate overrides
1397-
* MUPdate overrides exist
1398-
* zone updates waiting on MUPdate overrides
1404+
* zone adds waiting on blockers
1405+
* zone adds and updates are blocked:
1406+
- current target release generation (3) is lower than minimum required by blueprint (4)
1407+
- sleds have mupdate override errors: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c
1408+
* zone updates waiting on zone add blockers
13991409

14001410

14011411
> blueprint-show latest
@@ -1568,9 +1578,11 @@ chicken switches:
15681578
add zones with mupdate override: false
15691579

15701580
* skipping noop zone image source check on sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6: all 6 zones are already from artifacts
1571-
* waiting on MUPdate overrides
1572-
* MUPdate overrides exist
1573-
* zone updates waiting on MUPdate overrides
1581+
* zone adds waiting on blockers
1582+
* zone adds and updates are blocked:
1583+
- current target release generation (3) is lower than minimum required by blueprint (4)
1584+
- sleds have mupdate override errors: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c
1585+
* zone updates waiting on zone add blockers
15741586

15751587

15761588

@@ -1811,9 +1823,10 @@ chicken switches:
18111823

18121824
* skipping noop zone image source check on sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6: all 6 zones are already from artifacts
18131825
* noop converting 6/6 install-dataset zones to artifact store on sled d81c6a84-79b8-4958-ae41-ea46c9b19763
1814-
* waiting on MUPdate overrides
1815-
* MUPdate overrides exist
1816-
* zone updates waiting on MUPdate overrides
1826+
* zone adds waiting on blockers
1827+
* zone adds and updates are blocked:
1828+
- sleds have mupdate override errors: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c
1829+
* zone updates waiting on zone add blockers
18171830

18181831

18191832
> blueprint-show latest
@@ -1987,9 +2000,10 @@ chicken switches:
19872000

19882001
* skipping noop zone image source check on sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6: all 6 zones are already from artifacts
19892002
* noop converting 6/6 install-dataset zones to artifact store on sled d81c6a84-79b8-4958-ae41-ea46c9b19763
1990-
* waiting on MUPdate overrides
1991-
* MUPdate overrides exist
1992-
* zone updates waiting on MUPdate overrides
2003+
* zone adds waiting on blockers
2004+
* zone adds and updates are blocked:
2005+
- sleds have mupdate override errors: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c
2006+
* zone updates waiting on zone add blockers
19932007

19942008

19952009

@@ -2962,9 +2976,11 @@ chicken switches:
29622976

29632977
* skipping noop zone image source check on sled c3bc4c6d-fdde-4fc4-8493-89d2a1e5ee6b: all 0 zones are already from artifacts
29642978
* skipping noop zone image source check on sled d81c6a84-79b8-4958-ae41-ea46c9b19763: all 6 zones are already from artifacts
2965-
* waiting on MUPdate overrides
2966-
* MUPdate overrides exist
2967-
* zone updates waiting on MUPdate overrides
2979+
* zone adds waiting on blockers
2980+
* zone adds and updates are blocked:
2981+
- current target release generation (4) is lower than minimum required by blueprint (5)
2982+
- sleds have remove mupdate override set in blueprint: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6
2983+
* zone updates waiting on zone add blockers
29682984

29692985

29702986
> blueprint-diff latest
@@ -3191,11 +3207,13 @@ generated blueprint 27e755bc-dc10-4647-853c-f89bb3a15a2c based on parent bluepri
31913207
planning report for blueprint 27e755bc-dc10-4647-853c-f89bb3a15a2c:
31923208
* skipping noop zone image source check on sled c3bc4c6d-fdde-4fc4-8493-89d2a1e5ee6b: all 0 zones are already from artifacts
31933209
* skipping noop zone image source check on sled d81c6a84-79b8-4958-ae41-ea46c9b19763: all 6 zones are already from artifacts
3194-
* MUPdate overrides exist
3195-
* adding zones despite MUPdate override, as specified by the `add_zones_with_mupdate_override` chicken switch
3210+
* zone adds and updates are blocked:
3211+
- current target release generation (4) is lower than minimum required by blueprint (5)
3212+
- sleds have remove mupdate override set in blueprint: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6
3213+
* adding zones despite being blocked, as specified by the `add_zones_with_mupdate_override` chicken switch
31963214
* discretionary zone placement waiting for NTP zones on sleds: c3bc4c6d-fdde-4fc4-8493-89d2a1e5ee6b
31973215
* missing NTP zone on sled c3bc4c6d-fdde-4fc4-8493-89d2a1e5ee6b
3198-
* zone updates waiting on MUPdate overrides
3216+
* zone updates waiting on zone add blockers
31993217

32003218

32013219
> blueprint-diff latest

dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,10 @@ chicken switches:
183183

184184
* noop converting 6/6 install-dataset zones to artifact store on sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6
185185
* noop converting 5/6 install-dataset zones to artifact store on sled aff6c093-197d-42c5-ad80-9f10ba051a34
186-
* waiting on MUPdate overrides
187-
* MUPdate overrides exist
188-
* zone updates waiting on MUPdate overrides
186+
* zone adds waiting on blockers
187+
* zone adds and updates are blocked:
188+
- sleds have remove mupdate override set in blueprint: d81c6a84-79b8-4958-ae41-ea46c9b19763
189+
* zone updates waiting on zone add blockers
189190

190191

191192

@@ -549,9 +550,10 @@ chicken switches:
549550

550551
* skipping noop zone image source check on sled 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6: all 6 zones are already from artifacts
551552
* noop converting 2/2 install-dataset zones to artifact store on sled e96e226f-4ed9-4c01-91b9-69a9cd076c9e
552-
* waiting on MUPdate overrides
553-
* MUPdate overrides exist
554-
* zone updates waiting on MUPdate overrides
553+
* zone adds waiting on blockers
554+
* zone adds and updates are blocked:
555+
- sleds have remove mupdate override set in blueprint: d81c6a84-79b8-4958-ae41-ea46c9b19763
556+
* zone updates waiting on zone add blockers
555557

556558

557559

nexus/reconfigurator/planning/src/planner.rs

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -174,40 +174,40 @@ impl<'a> Planner<'a> {
174174

175175
let mut noop_info =
176176
NoopConvertInfo::new(self.input, self.inventory, &self.blueprint)?;
177-
let plan_mupdate_override_res =
178-
self.do_plan_mupdate_override(&mut noop_info)?;
177+
let actions_by_sled = self.do_plan_mupdate_override(&mut noop_info)?;
179178

180179
// Log noop-convert results after do_plan_mupdate_override, because this
181180
// step might alter noop_info.
182181
noop_info.log_to(&self.log);
183182

184183
// Within `do_plan_noop_image_source`, we plan noop image sources on
185184
// sleds other than those currently affected by mupdate overrides. This
186-
// means that we don't have to wait for the `plan_mupdate_override_res`
187-
// result for that step.
185+
// means that we don't have to consider anything
186+
// `do_plan_mupdate_override` does for this step.
188187
let noop_image_source = self.do_plan_noop_image_source(noop_info)?;
189188

189+
let add_update_blocked_reasons =
190+
self.should_plan_add_or_update(&actions_by_sled)?;
191+
190192
// Only plan MGS-based updates updates if there are no outstanding
191193
// MUPdate overrides.
192-
let mgs_updates = if plan_mupdate_override_res.is_empty() {
194+
let mgs_updates = if add_update_blocked_reasons.is_empty() {
193195
self.do_plan_mgs_updates()?
194196
} else {
195197
PlanningMgsUpdatesStepReport::new(PendingMgsUpdates::new())
196198
};
197199

198200
// Likewise for zone additions, unless overridden with the chicken switch.
199-
let has_mupdate_override = !plan_mupdate_override_res.is_empty();
200201
let add_zones_with_mupdate_override =
201202
self.input.chicken_switches().add_zones_with_mupdate_override;
202-
let mut add =
203-
if !has_mupdate_override || add_zones_with_mupdate_override {
204-
self.do_plan_add(&mgs_updates)?
205-
} else {
206-
PlanningAddStepReport::waiting_on(
207-
ZoneAddWaitingOn::MupdateOverrides,
208-
)
209-
};
210-
add.has_mupdate_override = has_mupdate_override;
203+
let mut add = if add_update_blocked_reasons.is_empty()
204+
|| add_zones_with_mupdate_override
205+
{
206+
self.do_plan_add(&mgs_updates)?
207+
} else {
208+
PlanningAddStepReport::waiting_on(ZoneAddWaitingOn::Blockers)
209+
};
210+
add.add_update_blocked_reasons = add_update_blocked_reasons;
211211
add.add_zones_with_mupdate_override = add_zones_with_mupdate_override;
212212

213213
let zone_updates = if add.any_discretionary_zones_placed() {
@@ -223,10 +223,10 @@ impl<'a> Planner<'a> {
223223
PlanningZoneUpdatesStepReport::waiting_on(
224224
ZoneUpdatesWaitingOn::PendingMgsUpdates,
225225
)
226-
} else if !plan_mupdate_override_res.is_empty() {
227-
// ... or if there are pending MUPdate overrides.
226+
} else if !add.add_update_blocked_reasons.is_empty() {
227+
// ... or if there are pending zone add blockers.
228228
PlanningZoneUpdatesStepReport::waiting_on(
229-
ZoneUpdatesWaitingOn::MupdateOverrides,
229+
ZoneUpdatesWaitingOn::ZoneAddBlockers,
230230
)
231231
} else {
232232
self.do_plan_zone_updates(&mgs_updates)?
@@ -1528,10 +1528,12 @@ impl<'a> Planner<'a> {
15281528
Ok(report)
15291529
}
15301530

1531+
/// Perform planning for mupdate overrides, returning a map of sleds to
1532+
/// actions taken.
15311533
fn do_plan_mupdate_override(
15321534
&mut self,
15331535
noop_info: &mut NoopConvertInfo,
1534-
) -> Result<Vec<String>, Error> {
1536+
) -> Result<BTreeMap<SledUuid, EnsureMupdateOverrideAction>, Error> {
15351537
// For each sled, compare what's in the inventory to what's in the
15361538
// blueprint.
15371539
let mut actions_by_sled = BTreeMap::new();
@@ -1638,7 +1640,14 @@ impl<'a> Planner<'a> {
16381640
}
16391641
}
16401642

1641-
// Now we need to determine whether to also perform other actions like
1643+
Ok(actions_by_sled)
1644+
}
1645+
1646+
fn should_plan_add_or_update(
1647+
&self,
1648+
actions_by_sled: &BTreeMap<SledUuid, EnsureMupdateOverrideAction>,
1649+
) -> Result<Vec<String>, Error> {
1650+
// We need to determine whether to also perform other actions like
16421651
// updating or adding zones. We have to be careful here:
16431652
//
16441653
// * We may have moved existing zones with an Artifact source to using

nexus/types/src/deployment/planning_report.rs

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use super::PendingMgsUpdates;
1212
use super::PlannerChickenSwitches;
1313

1414
use daft::Diffable;
15+
use indent_write::fmt::IndentWriter;
1516
use omicron_common::policy::COCKROACHDB_REDUNDANCY;
1617
use omicron_uuid_kinds::BlueprintUuid;
1718
use omicron_uuid_kinds::MupdateOverrideUuid;
@@ -26,6 +27,7 @@ use serde::Serialize;
2627
use std::collections::BTreeMap;
2728
use std::collections::BTreeSet;
2829
use std::fmt;
30+
use std::fmt::Write;
2931

3032
/// A full blueprint planning report. Other than the blueprint ID, each
3133
/// field corresponds to a step in the update planner, i.e., a subroutine
@@ -531,14 +533,15 @@ pub struct PlanningAddSufficientZonesExist {
531533
)]
532534
#[serde(rename_all = "snake_case", tag = "type")]
533535
pub enum ZoneAddWaitingOn {
534-
/// Waiting on one or more MUPdate overrides to clear.
535-
MupdateOverrides,
536+
/// Waiting on one or more blockers (typically MUPdate-related reasons) to
537+
/// clear.
538+
Blockers,
536539
}
537540

538541
impl ZoneAddWaitingOn {
539542
pub fn as_str(&self) -> &'static str {
540543
match self {
541-
Self::MupdateOverrides => "MUPdate overrides",
544+
Self::Blockers => "blockers",
542545
}
543546
}
544547
}
@@ -550,10 +553,14 @@ pub struct PlanningAddStepReport {
550553
/// What are we waiting on to start zone additions?
551554
pub waiting_on: Option<ZoneAddWaitingOn>,
552555

553-
/// Are there any outstanding MUPdate overrides?
554-
pub has_mupdate_override: bool,
556+
/// Reasons why zone adds and any updates are blocked.
557+
///
558+
/// This is typically a list of MUPdate-related reasons.
559+
pub add_update_blocked_reasons: Vec<String>,
555560

556-
/// The value of the homonymous chicken switch.
561+
/// The value of the homonymous chicken switch. (What this really means is
562+
/// that zone adds happen despite being blocked by one or more
563+
/// MUPdate-related reasons.)
557564
pub add_zones_with_mupdate_override: bool,
558565

559566
pub sleds_without_ntp_zones_in_inventory: BTreeSet<SledUuid>,
@@ -580,7 +587,7 @@ impl PlanningAddStepReport {
580587
pub fn new() -> Self {
581588
Self {
582589
waiting_on: None,
583-
has_mupdate_override: true,
590+
add_update_blocked_reasons: Vec::new(),
584591
add_zones_with_mupdate_override: false,
585592
sleds_without_ntp_zones_in_inventory: BTreeSet::new(),
586593
sleds_without_zpools_for_ntp_zones: BTreeSet::new(),
@@ -602,6 +609,7 @@ impl PlanningAddStepReport {
602609

603610
pub fn is_empty(&self) -> bool {
604611
self.waiting_on.is_none()
612+
&& self.add_update_blocked_reasons.is_empty()
605613
&& self.sleds_without_ntp_zones_in_inventory.is_empty()
606614
&& self.sleds_without_zpools_for_ntp_zones.is_empty()
607615
&& self.sleds_waiting_for_ntp_zone.is_empty()
@@ -664,10 +672,10 @@ impl PlanningAddStepReport {
664672
}
665673

666674
impl fmt::Display for PlanningAddStepReport {
667-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
675+
fn fmt(&self, mut f: &mut fmt::Formatter) -> fmt::Result {
668676
let Self {
669677
waiting_on,
670-
has_mupdate_override,
678+
add_update_blocked_reasons,
671679
add_zones_with_mupdate_override,
672680
sleds_without_ntp_zones_in_inventory,
673681
sleds_without_zpools_for_ntp_zones,
@@ -681,17 +689,27 @@ impl fmt::Display for PlanningAddStepReport {
681689
} = self;
682690

683691
if let Some(waiting_on) = waiting_on {
684-
writeln!(f, "* waiting on {}", waiting_on.as_str())?;
692+
writeln!(f, "* zone adds waiting on {}", waiting_on.as_str())?;
685693
}
686694

687-
if *has_mupdate_override {
688-
writeln!(f, "* MUPdate overrides exist")?;
695+
if !add_update_blocked_reasons.is_empty() {
696+
// If zone adds are blocked on a set of reasons, zone updates are
697+
// blocked on the same reason. Make that clear by saying "zone adds
698+
// and updates are blocked" rather than just "zone adds are
699+
// blocked".
700+
writeln!(f, "* zone adds and updates are blocked:")?;
701+
for reason in add_update_blocked_reasons {
702+
let mut indent_writer =
703+
IndentWriter::new_skip_initial(" ", f);
704+
writeln!(indent_writer, " - {}", reason)?;
705+
f = indent_writer.into_inner();
706+
}
689707
}
690708

691709
if *add_zones_with_mupdate_override {
692710
writeln!(
693711
f,
694-
"* adding zones despite MUPdate override, \
712+
"* adding zones despite being blocked, \
695713
as specified by the `add_zones_with_mupdate_override` \
696714
chicken switch"
697715
)?;
@@ -958,8 +976,8 @@ pub enum ZoneUpdatesWaitingOn {
958976
/// Waiting on updates to RoT / SP / Host OS / etc.
959977
PendingMgsUpdates,
960978

961-
/// Waiting on one or more MUPdate overrides to clear.
962-
MupdateOverrides,
979+
/// Waiting on the same set of blockers zone adds are waiting on.
980+
ZoneAddBlockers,
963981
}
964982

965983
impl ZoneUpdatesWaitingOn {
@@ -969,7 +987,7 @@ impl ZoneUpdatesWaitingOn {
969987
Self::PendingMgsUpdates => {
970988
"pending MGS updates (RoT / SP / Host OS / etc.)"
971989
}
972-
Self::MupdateOverrides => "MUPdate overrides",
990+
Self::ZoneAddBlockers => "zone add blockers",
973991
}
974992
}
975993
}

0 commit comments

Comments
 (0)