Skip to content

Commit c16f14f

Browse files
authored
[sled-agent] Don't bounce zones if their config changes only by an identical image_source (#8514)
Prior to this PR, any change to the `OmicronZoneConfig` of an already-running zone resulted in that zone being shut down and restarted. With this PR, we allow a single kind of change that does not restart the zone. If the `image_source` swaps from `InstallDataset` to `Artifact { hash }` (or vice versa) _and_ the hash of this zone in the install dataset exactly matches the `Artifact { hash }`, we don't need to do anything: we're already running the exact zone as desired, just started from a different place. Fixes #8463. Makes #8510 slightly worse; yet another `ZoneKind::make_a_string()` method. (This one is at least guaranteed-by-test to be an extension of an existing one. I don't feel a lot better about that though.) I'll test this on a racklette before merging; will put notes below once I do. But I think this is contained enough that it can be reviewed before that's done.
1 parent 435c65d commit c16f14f

File tree

6 files changed

+539
-25
lines changed

6 files changed

+539
-25
lines changed

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

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -961,14 +961,17 @@ impl OmicronZoneType {
961961
///
962962
/// # String representations of this type
963963
///
964-
/// There are no fewer than five string representations for this type, all
964+
/// There are no fewer than six string representations for this type, all
965965
/// slightly different from each other.
966966
///
967967
/// 1. [`Self::zone_prefix`]: Used to construct zone names.
968968
/// 2. [`Self::service_prefix`]: Used to construct SMF service names.
969969
/// 3. [`Self::name_prefix`]: Used to construct `Name` instances.
970970
/// 4. [`Self::report_str`]: Used for reporting and testing.
971-
/// 5. [`Self::artifact_name`]: Used to match TUF artifact names.
971+
/// 5. [`Self::artifact_id_name`]: Used to match TUF artifact IDs.
972+
/// 6. [`Self::artifact_in_install_dataset`]: Used to match zone image tarballs
973+
/// in the install dataset. (This method is equivalent to appending `.tar.gz`
974+
/// to the result of [`Self::zone_prefix`].)
972975
///
973976
/// There is no `Display` impl to ensure that users explicitly choose the
974977
/// representation they want. (Please play close attention to this! The
@@ -978,7 +981,7 @@ impl OmicronZoneType {
978981
/// ## Adding new representations
979982
///
980983
/// If you have a new use case for a string representation, please reuse one of
981-
/// the four representations if at all possible. If you must add a new one,
984+
/// the six representations if at all possible. If you must add a new one,
982985
/// please add it here rather than doing something ad-hoc in the calling code
983986
/// so it's more legible.
984987
#[derive(
@@ -1024,6 +1027,30 @@ impl ZoneKind {
10241027
}
10251028
}
10261029

1030+
/// Return a string that identifies **zone image filenames** in the install
1031+
/// dataset.
1032+
///
1033+
/// This method is exactly equivalent to `format!("{}.tar.gz",
1034+
/// self.zone_prefix())`, but returns `&'static str`s. A unit test ensures
1035+
/// they stay consistent.
1036+
pub fn artifact_in_install_dataset(self) -> &'static str {
1037+
match self {
1038+
// BoundaryNtp and InternalNtp both use "ntp".
1039+
ZoneKind::BoundaryNtp | ZoneKind::InternalNtp => "ntp.tar.gz",
1040+
ZoneKind::Clickhouse => "clickhouse.tar.gz",
1041+
ZoneKind::ClickhouseKeeper => "clickhouse_keeper.tar.gz",
1042+
ZoneKind::ClickhouseServer => "clickhouse_server.tar.gz",
1043+
// Note "cockroachdb" for historical reasons.
1044+
ZoneKind::CockroachDb => "cockroachdb.tar.gz",
1045+
ZoneKind::Crucible => "crucible.tar.gz",
1046+
ZoneKind::CruciblePantry => "crucible_pantry.tar.gz",
1047+
ZoneKind::ExternalDns => "external_dns.tar.gz",
1048+
ZoneKind::InternalDns => "internal_dns.tar.gz",
1049+
ZoneKind::Nexus => "nexus.tar.gz",
1050+
ZoneKind::Oximeter => "oximeter.tar.gz",
1051+
}
1052+
}
1053+
10271054
/// Return a string that is used to construct **SMF service names**. This
10281055
/// string is guaranteed to be stable over time.
10291056
pub fn service_prefix(self) -> &'static str {
@@ -1090,7 +1117,12 @@ impl ZoneKind {
10901117

10911118
/// Return a string used as an artifact name for control-plane zones.
10921119
/// This is **not guaranteed** to be stable.
1093-
pub fn artifact_name(self) -> &'static str {
1120+
///
1121+
/// These strings match the `ArtifactId::name`s Nexus constructs when
1122+
/// unpacking the composite control-plane artifact in a TUF repo. Currently,
1123+
/// these are chosen by reading the `pkg` value of the `oxide.json` object
1124+
/// inside each zone image tarball.
1125+
pub fn artifact_id_name(self) -> &'static str {
10941126
match self {
10951127
ZoneKind::BoundaryNtp => "ntp",
10961128
ZoneKind::Clickhouse => "clickhouse",
@@ -1118,7 +1150,7 @@ impl ZoneKind {
11181150
.to_known()
11191151
.map(|kind| matches!(kind, KnownArtifactKind::Zone))
11201152
.unwrap_or(false)
1121-
&& artifact_id.name == self.artifact_name()
1153+
&& artifact_id.name == self.artifact_id_name()
11221154
}
11231155
}
11241156

@@ -1194,6 +1226,18 @@ mod tests {
11941226
});
11951227
}
11961228
}
1229+
1230+
#[test]
1231+
fn test_zone_prefix_matches_artifact_in_install_dataset() {
1232+
for zone_kind in ZoneKind::iter() {
1233+
let zone_prefix = zone_kind.zone_prefix();
1234+
let expected_artifact = format!("{zone_prefix}.tar.gz");
1235+
assert_eq!(
1236+
expected_artifact,
1237+
zone_kind.artifact_in_install_dataset()
1238+
);
1239+
}
1240+
}
11971241
}
11981242

11991243
// Used for schemars to be able to be used with camino:

nexus/reconfigurator/planning/src/planner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4871,7 +4871,7 @@ pub(crate) mod test {
48714871
($kind: ident, $version: expr) => {
48724872
TufArtifactMeta {
48734873
id: ArtifactId {
4874-
name: ZoneKind::$kind.artifact_name().to_string(),
4874+
name: ZoneKind::$kind.artifact_id_name().to_string(),
48754875
version: $version,
48764876
kind: ArtifactKind::from_known(KnownArtifactKind::Zone),
48774877
},

0 commit comments

Comments
 (0)