Skip to content

Commit a1d38ab

Browse files
authored
Blueprint PlanningInput: Fewer Options (#8470)
This gets rid of two `Option<_>`s in the planning input: * `TufRepoPolicy::description` changes from `Option<TufRepoDescription>` to non-optional `TargetReleaseDescription`. The latter is isomorphic to `Option`, but spells the `None` case as `TargetReleaseDescription::Initial`. * `PlanningInput::old_repo` is now a non-optional `TufRepoPolicy`. In the case where `tuf_repo` is "the initial policy" (i.e., `TargetReleaseDescription::Initial`, `old_repo` is _also_ set to the initial policy. In all other cases, it's "the previous policy".
1 parent 100c4b4 commit a1d38ab

File tree

15 files changed

+400
-174
lines changed

15 files changed

+400
-174
lines changed

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use nexus_reconfigurator_planning::system::{SledBuilder, SystemDescription};
2323
use nexus_reconfigurator_simulation::SimStateBuilder;
2424
use nexus_reconfigurator_simulation::Simulator;
2525
use nexus_reconfigurator_simulation::{BlueprintId, SimState};
26-
use nexus_types::deployment::OmicronZoneNic;
2726
use nexus_types::deployment::PlanningInput;
2827
use nexus_types::deployment::SledFilter;
2928
use nexus_types::deployment::execution;
@@ -35,6 +34,7 @@ use nexus_types::deployment::{
3534
BlueprintZoneImageSource, PendingMgsUpdateDetails,
3635
};
3736
use nexus_types::deployment::{BlueprintZoneImageVersion, PendingMgsUpdate};
37+
use nexus_types::deployment::{OmicronZoneNic, TargetReleaseDescription};
3838
use nexus_types::external_api::views::SledPolicy;
3939
use nexus_types::external_api::views::SledProvisionPolicy;
4040
use omicron_common::address::REPO_DEPOT_PORT;
@@ -1673,7 +1673,7 @@ fn cmd_show(sim: &mut ReconfiguratorSim) -> anyhow::Result<Option<String>> {
16731673

16741674
let target_release = state.system().description().target_release();
16751675
match target_release.description() {
1676-
Some(tuf_desc) => {
1676+
TargetReleaseDescription::TufRepo(tuf_desc) => {
16771677
swriteln!(
16781678
s,
16791679
"target release (generation {}): {} ({})",
@@ -1692,7 +1692,7 @@ fn cmd_show(sim: &mut ReconfiguratorSim) -> anyhow::Result<Option<String>> {
16921692
);
16931693
}
16941694
}
1695-
None => {
1695+
TargetReleaseDescription::Initial => {
16961696
swriteln!(
16971697
s,
16981698
"target release (generation {}): unset",
@@ -1759,10 +1759,9 @@ fn cmd_set(
17591759
})?;
17601760
let description = artifacts_with_plan.description().clone();
17611761
drop(artifacts_with_plan);
1762-
state
1763-
.system_mut()
1764-
.description_mut()
1765-
.set_target_release(Some(description));
1762+
state.system_mut().description_mut().set_target_release(
1763+
TargetReleaseDescription::TufRepo(description),
1764+
);
17661765
format!("set target release based on {}", filename)
17671766
}
17681767
};

dev-tools/reconfigurator-cli/tests/input/target-release.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,12 @@ blueprint-plan df06bb57-ad42-4431-9206-abff322896c7 b1bda47d-2c19-4fba-96e3-d9df
6161
blueprint-diff df06bb57-ad42-4431-9206-abff322896c7 7f976e0d-d2a5-4eeb-9e82-c82bc2824aba
6262

6363
# Finish updating the last sled and do one more planning run.
64-
# There should be nothing left to do.
64+
# This should update one control plane zone.
6565
sled-update-sp d81c6a84-79b8-4958-ae41-ea46c9b19763 --active 1.0.0
6666
inventory-generate
6767
blueprint-plan 7f976e0d-d2a5-4eeb-9e82-c82bc2824aba a71f7a73-35a6-45e8-acbe-f1c5925eed69
6868
blueprint-diff 7f976e0d-d2a5-4eeb-9e82-c82bc2824aba 9034c710-3e57-45f3-99e5-4316145e87ac
69+
70+
# We should continue walking through the update. We need to build out a
71+
# reconfigurator-cli subcommand to simulate updated zone image sources (just
72+
# like we have sled-update-sp for simulated SP updates).

dev-tools/reconfigurator-cli/tests/output/target-release-stdout

Lines changed: 95 additions & 8 deletions
Large diffs are not rendered by default.

nexus-sled-agent-shared/src/inventory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ impl ZoneKind {
10951095
ZoneKind::BoundaryNtp => "ntp",
10961096
ZoneKind::Clickhouse => "clickhouse",
10971097
ZoneKind::ClickhouseKeeper => "clickhouse_keeper",
1098-
ZoneKind::ClickhouseServer => "clickhouse",
1098+
ZoneKind::ClickhouseServer => "clickhouse_server",
10991099
ZoneKind::CockroachDb => "cockroachdb",
11001100
ZoneKind::Crucible => "crucible-zone",
11011101
ZoneKind::CruciblePantry => "crucible-pantry-zone",

nexus/reconfigurator/execution/src/dns.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1497,7 +1497,7 @@ mod test {
14971497
clickhouse_policy: None,
14981498
oximeter_read_policy: OximeterReadPolicy::new(1),
14991499
tuf_repo: TufRepoPolicy::initial(),
1500-
old_repo: None,
1500+
old_repo: TufRepoPolicy::initial(),
15011501
log,
15021502
}
15031503
.build()

nexus/reconfigurator/planning/src/blueprint_builder/builder.rs

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ use nexus_types::deployment::PendingMgsUpdates;
4545
use nexus_types::deployment::PlanningInput;
4646
use nexus_types::deployment::SledFilter;
4747
use nexus_types::deployment::SledResources;
48+
use nexus_types::deployment::TargetReleaseDescription;
49+
use nexus_types::deployment::TufRepoContentsError;
4850
use nexus_types::deployment::ZpoolFilter;
4951
use nexus_types::deployment::ZpoolName;
5052
use nexus_types::deployment::blueprint_zone_type;
@@ -56,7 +58,6 @@ use omicron_common::address::DNS_PORT;
5658
use omicron_common::address::NTP_PORT;
5759
use omicron_common::address::ReservedRackSubnet;
5860
use omicron_common::api::external::Generation;
59-
use omicron_common::api::external::TufRepoDescription;
6061
use omicron_common::api::external::Vni;
6162
use omicron_common::api::internal::shared::NetworkInterface;
6263
use omicron_common::api::internal::shared::NetworkInterfaceKind;
@@ -135,6 +136,8 @@ pub enum Error {
135136
expected: Generation,
136137
actual: Generation,
137138
},
139+
#[error(transparent)]
140+
TufRepoContentsError(#[from] TufRepoContentsError),
138141
}
139142

140143
/// Describes the result of an idempotent "ensure" operation
@@ -1179,7 +1182,7 @@ impl<'a> BlueprintBuilder<'a> {
11791182
gz_address: dns_subnet.gz_address(),
11801183
gz_address_index,
11811184
});
1182-
let image_source = self.zone_image_source(zone_type.kind());
1185+
let image_source = self.zone_image_source(zone_type.kind())?;
11831186

11841187
let zone = BlueprintZoneConfig {
11851188
disposition: BlueprintZoneDisposition::InService,
@@ -1232,7 +1235,7 @@ impl<'a> BlueprintBuilder<'a> {
12321235
dns_address,
12331236
nic,
12341237
});
1235-
let image_source = self.zone_image_source(zone_type.kind());
1238+
let image_source = self.zone_image_source(zone_type.kind())?;
12361239

12371240
let zone = BlueprintZoneConfig {
12381241
disposition: BlueprintZoneDisposition::InService,
@@ -1272,7 +1275,7 @@ impl<'a> BlueprintBuilder<'a> {
12721275
});
12731276
let filesystem_pool =
12741277
self.sled_select_zpool(sled_id, zone_type.kind())?;
1275-
let image_source = self.zone_image_source(zone_type.kind());
1278+
let image_source = self.zone_image_source(zone_type.kind())?;
12761279

12771280
let zone = BlueprintZoneConfig {
12781281
disposition: BlueprintZoneDisposition::InService,
@@ -1425,7 +1428,7 @@ impl<'a> BlueprintBuilder<'a> {
14251428
});
14261429
let filesystem_pool =
14271430
self.sled_select_zpool(sled_id, zone_type.kind())?;
1428-
let image_source = self.zone_image_source(zone_type.kind());
1431+
let image_source = self.zone_image_source(zone_type.kind())?;
14291432

14301433
let zone = BlueprintZoneConfig {
14311434
disposition: BlueprintZoneDisposition::InService,
@@ -1451,7 +1454,7 @@ impl<'a> BlueprintBuilder<'a> {
14511454
});
14521455
let filesystem_pool =
14531456
self.sled_select_zpool(sled_id, zone_type.kind())?;
1454-
let image_source = self.zone_image_source(zone_type.kind());
1457+
let image_source = self.zone_image_source(zone_type.kind())?;
14551458

14561459
let zone = BlueprintZoneConfig {
14571460
disposition: BlueprintZoneDisposition::InService,
@@ -1476,7 +1479,7 @@ impl<'a> BlueprintBuilder<'a> {
14761479
);
14771480
let filesystem_pool =
14781481
self.sled_select_zpool(sled_id, zone_type.kind())?;
1479-
let image_source = self.zone_image_source(zone_type.kind());
1482+
let image_source = self.zone_image_source(zone_type.kind())?;
14801483

14811484
let zone = BlueprintZoneConfig {
14821485
disposition: BlueprintZoneDisposition::InService,
@@ -1511,7 +1514,7 @@ impl<'a> BlueprintBuilder<'a> {
15111514
dataset: OmicronZoneDataset { pool_name },
15121515
});
15131516
let filesystem_pool = pool_name;
1514-
let image_source = self.zone_image_source(zone_type.kind());
1517+
let image_source = self.zone_image_source(zone_type.kind())?;
15151518

15161519
let zone = BlueprintZoneConfig {
15171520
disposition: BlueprintZoneDisposition::InService,
@@ -1538,7 +1541,7 @@ impl<'a> BlueprintBuilder<'a> {
15381541
address,
15391542
dataset: OmicronZoneDataset { pool_name },
15401543
});
1541-
let image_source = self.zone_image_source(zone_type.kind());
1544+
let image_source = self.zone_image_source(zone_type.kind())?;
15421545

15431546
let zone = BlueprintZoneConfig {
15441547
disposition: BlueprintZoneDisposition::InService,
@@ -1567,7 +1570,7 @@ impl<'a> BlueprintBuilder<'a> {
15671570
},
15681571
);
15691572
let filesystem_pool = pool_name;
1570-
let image_source = self.zone_image_source(zone_type.kind());
1573+
let image_source = self.zone_image_source(zone_type.kind())?;
15711574

15721575
let zone = BlueprintZoneConfig {
15731576
disposition: BlueprintZoneDisposition::InService,
@@ -1596,7 +1599,7 @@ impl<'a> BlueprintBuilder<'a> {
15961599
},
15971600
);
15981601
let filesystem_pool = pool_name;
1599-
let image_source = self.zone_image_source(zone_type.kind());
1602+
let image_source = self.zone_image_source(zone_type.kind())?;
16001603

16011604
let zone = BlueprintZoneConfig {
16021605
disposition: BlueprintZoneDisposition::InService,
@@ -1723,7 +1726,7 @@ impl<'a> BlueprintBuilder<'a> {
17231726
});
17241727
let filesystem_pool =
17251728
self.sled_select_zpool(sled_id, zone_type.kind())?;
1726-
let image_source = self.zone_image_source(zone_type.kind());
1729+
let image_source = self.zone_image_source(zone_type.kind())?;
17271730

17281731
self.sled_add_zone(
17291732
sled_id,
@@ -1981,39 +1984,22 @@ impl<'a> BlueprintBuilder<'a> {
19811984
self.pending_mgs_updates.remove(baseboard_id);
19821985
}
19831986

1984-
fn zone_image_artifact(
1985-
repo: Option<&TufRepoDescription>,
1986-
zone_kind: ZoneKind,
1987-
) -> BlueprintZoneImageSource {
1988-
repo.and_then(|repo| {
1989-
repo.artifacts
1990-
.iter()
1991-
.find(|artifact| {
1992-
zone_kind.is_control_plane_zone_artifact(&artifact.id)
1993-
})
1994-
.map(BlueprintZoneImageSource::from_available_artifact)
1995-
})
1996-
.unwrap_or(BlueprintZoneImageSource::InstallDataset)
1997-
}
1998-
19991987
/// Try to find an artifact in either the current or previous release repo
20001988
/// that contains an image for a zone of the given kind; see RFD 565 §9.
20011989
/// Defaults to the install dataset.
20021990
pub(crate) fn zone_image_source(
20031991
&self,
20041992
zone_kind: ZoneKind,
2005-
) -> BlueprintZoneImageSource {
1993+
) -> Result<BlueprintZoneImageSource, TufRepoContentsError> {
20061994
let new_repo = self.input.tuf_repo().description();
2007-
let old_repo =
2008-
self.input.old_repo().and_then(|repo| repo.description());
2009-
Self::zone_image_artifact(
2010-
if self.zone_is_ready_for_update(zone_kind, new_repo) {
2011-
new_repo
2012-
} else {
2013-
old_repo
2014-
},
2015-
zone_kind,
2016-
)
1995+
let old_repo = self.input.old_repo().description();
1996+
let repo_choice = if self.zone_is_ready_for_update(zone_kind, new_repo)
1997+
{
1998+
new_repo
1999+
} else {
2000+
old_repo
2001+
};
2002+
repo_choice.zone_image_source(zone_kind)
20172003
}
20182004

20192005
/// Return `true` iff a zone of the given kind is ready to be updated;
@@ -2022,7 +2008,7 @@ impl<'a> BlueprintBuilder<'a> {
20222008
fn zone_is_ready_for_update(
20232009
&self,
20242010
zone_kind: ZoneKind,
2025-
new_repo: Option<&TufRepoDescription>,
2011+
new_repo: &TargetReleaseDescription,
20262012
) -> bool {
20272013
match zone_kind {
20282014
ZoneKind::Nexus => {
@@ -2035,8 +2021,15 @@ impl<'a> BlueprintBuilder<'a> {
20352021
)
20362022
.filter(|z| z.zone_type.kind() != ZoneKind::Nexus)
20372023
.all(|z| {
2038-
z.image_source
2039-
== Self::zone_image_artifact(new_repo, z.kind())
2024+
// This comparison ignores any TUF repo contents errors
2025+
// from `zone_image_source`. This means we'll never be
2026+
// able to update Nexus if we can't tell if _other_ zone
2027+
// types aren't updated, which seems correct.
2028+
Some(&z.image_source)
2029+
== new_repo
2030+
.zone_image_source(z.kind())
2031+
.ok()
2032+
.as_ref()
20402033
})
20412034
})
20422035
}

0 commit comments

Comments
 (0)