Skip to content

Commit 77b2156

Browse files
committed
Simplify OrderedComponent logic
1 parent 57f7154 commit 77b2156

File tree

3 files changed

+23
-101
lines changed

3 files changed

+23
-101
lines changed

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

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,28 +1929,32 @@ impl<'a> BlueprintBuilder<'a> {
19291929
let old_repo = self.input.old_repo();
19301930
let new_artifact = Self::zone_image_artifact(new_repo, zone_kind);
19311931
let old_artifact = Self::zone_image_artifact(old_repo, zone_kind);
1932-
if let Some(prev) = OrderedComponent::from(zone_kind).prev() {
1933-
if prev >= OrderedComponent::NonNexusOmicronZone
1934-
&& self.sled_ids_with_zones().any(|sled_id| {
1932+
match OrderedComponent::from(zone_kind) {
1933+
// Nexus can only be updated if all non-Nexus zones have been updated.
1934+
OrderedComponent::NexusZone => {
1935+
if self.sled_ids_with_zones().any(|sled_id| {
19351936
self.current_sled_zones(
19361937
sled_id,
19371938
BlueprintZoneDisposition::is_in_service,
19381939
)
1939-
.any(|z| {
1940-
let kind = z.zone_type.kind();
1941-
let old_artifact =
1942-
Self::zone_image_artifact(old_repo, kind);
1943-
OrderedComponent::from(kind) == prev
1944-
&& z.image_source == old_artifact
1940+
.filter(|z| {
1941+
OrderedComponent::from(z.zone_type.kind())
1942+
== OrderedComponent::NonNexusOmicronZone
19451943
})
1946-
})
1947-
{
1948-
old_artifact
1949-
} else {
1950-
new_artifact
1944+
.any(|z| z.image_source != new_artifact)
1945+
}) {
1946+
// Some dependent zone is not up-to-date.
1947+
old_artifact
1948+
} else {
1949+
// All dependent zones are up-to-date.
1950+
new_artifact
1951+
}
1952+
}
1953+
// It's always safe to use the new artifact for non-Nexus zones.
1954+
OrderedComponent::NonNexusOmicronZone => new_artifact,
1955+
OrderedComponent::HostOs | OrderedComponent::SpRot => {
1956+
unreachable!("can't get an OS or SP/RoT image from a zone")
19511957
}
1952-
} else {
1953-
new_artifact
19541958
}
19551959
}
19561960
}

nexus/reconfigurator/planning/src/planner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4924,7 +4924,7 @@ pub(crate) mod test {
49244924
.all(|(_, zone)| match zone.zone_type.kind() {
49254925
ZoneKind::Nexus => {
49264926
if zone.image_source == image_source {
4927-
comp = comp.next().unwrap();
4927+
comp = OrderedComponent::NexusZone;
49284928
true
49294929
} else {
49304930
zone.image_source

nexus/reconfigurator/planning/src/planner/update_sequence.rs

Lines changed: 2 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,50 +5,17 @@
55
//! Updatable components ordered by dependencies (RFD 565).
66
77
use nexus_sled_agent_shared::inventory::ZoneKind;
8-
use strum::{EnumIter, IntoEnumIterator as _};
98

109
/// Update sequence as defined by RFD 565 §6.
11-
#[derive(
12-
Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter, PartialOrd, Ord,
13-
)]
10+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
11+
#[allow(dead_code)]
1412
pub enum OrderedComponent {
1513
HostOs,
1614
SpRot,
1715
NonNexusOmicronZone,
1816
NexusZone,
1917
}
2018

21-
/// To implement the checks in RFD 565 §9, we need to go backwards
22-
/// (and mabye forwards) through the component ordering. The simple
23-
/// linear scans here are fine as long as `OrderedComponent` has only
24-
/// a few variants; if it starts getting large (e.g., programatically
25-
/// generated from `ls-apis`), we can switch to something faster.
26-
impl OrderedComponent {
27-
#[allow(dead_code)]
28-
pub fn next(&self) -> Option<Self> {
29-
let mut found = false;
30-
for comp in OrderedComponent::iter() {
31-
if found {
32-
return Some(comp);
33-
} else if comp == *self {
34-
found = true;
35-
}
36-
}
37-
None
38-
}
39-
40-
pub fn prev(&self) -> Option<Self> {
41-
let mut prev = None;
42-
for comp in OrderedComponent::iter() {
43-
if comp == *self {
44-
return prev;
45-
}
46-
prev = Some(comp);
47-
}
48-
prev
49-
}
50-
}
51-
5219
impl From<ZoneKind> for OrderedComponent {
5320
fn from(zone_kind: ZoneKind) -> Self {
5421
match zone_kind {
@@ -57,52 +24,3 @@ impl From<ZoneKind> for OrderedComponent {
5724
}
5825
}
5926
}
60-
61-
#[cfg(test)]
62-
mod test {
63-
use super::*;
64-
65-
#[test]
66-
fn ordered_component_next_prev() {
67-
// Exhaustive checks ok for a few variants, revisit if it grows.
68-
assert_eq!(OrderedComponent::HostOs.prev(), None);
69-
assert_eq!(
70-
OrderedComponent::HostOs.next(),
71-
Some(OrderedComponent::SpRot)
72-
);
73-
assert_eq!(
74-
OrderedComponent::SpRot.prev(),
75-
Some(OrderedComponent::HostOs)
76-
);
77-
assert_eq!(
78-
OrderedComponent::SpRot.next(),
79-
Some(OrderedComponent::NonNexusOmicronZone)
80-
);
81-
assert_eq!(
82-
OrderedComponent::NonNexusOmicronZone.prev(),
83-
Some(OrderedComponent::SpRot)
84-
);
85-
assert_eq!(
86-
OrderedComponent::NonNexusOmicronZone.next(),
87-
Some(OrderedComponent::NexusZone)
88-
);
89-
assert_eq!(
90-
OrderedComponent::NexusZone.prev(),
91-
Some(OrderedComponent::NonNexusOmicronZone)
92-
);
93-
assert_eq!(OrderedComponent::NexusZone.next(), None);
94-
assert!(OrderedComponent::HostOs < OrderedComponent::NexusZone);
95-
}
96-
97-
#[test]
98-
fn ordered_component_from_zone_kind() {
99-
assert!(matches!(
100-
OrderedComponent::from(ZoneKind::CruciblePantry),
101-
OrderedComponent::NonNexusOmicronZone
102-
));
103-
assert!(matches!(
104-
OrderedComponent::from(ZoneKind::Nexus),
105-
OrderedComponent::NexusZone
106-
));
107-
}
108-
}

0 commit comments

Comments
 (0)