Skip to content

Commit f8410bf

Browse files
authored
Make UnstableReconfiguratorState::target_blueprint non-optional (#9423)
`UnstableReconfiguratorState`s constructed from real systems always supplied a target blueprint, because real systems are required to always have one. We'd kept this as optional to allow for `reconfigurator-cli`'s simulated system to not have a blueprint at all, but I'd like to make other changes related to the `PlanningInput` that trip over this difference. This PR addresses the simulator side by having it claim to have a blueprint with the nil ID and containing nothing any time it's asked for the current list of blueprints or current target blueprint and one hasn't otherwise been set (i.e., by loading an example system or an existing serialized state).
1 parent 1cf6458 commit f8410bf

File tree

9 files changed

+178
-95
lines changed

9 files changed

+178
-95
lines changed

dev-tools/omdb/src/bin/omdb/reconfigurator.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,7 @@ async fn cmd_reconfigurator_archive(
202202
// successfully archived some blueprints before hitting this error. We
203203
// attempt to notice this and log a message for the operator in this
204204
// case.
205-
let target_blueprint_id = saved_state
206-
.target_blueprint
207-
.context(
208-
"system has no current target blueprint: \
209-
cannot remove non-target blueprints",
210-
)?
211-
.target_id;
212-
205+
let target_blueprint_id = saved_state.target_blueprint.target_id;
213206
let mut ndeleted = 0;
214207

215208
eprintln!("removing saved, non-target blueprints ...");

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2121,12 +2121,12 @@ fn cmd_blueprint_list(
21212121
let mut rows = state.system().all_blueprints().collect::<Vec<_>>();
21222122
rows.sort_unstable_by_key(|blueprint| blueprint.time_created);
21232123
let rows = rows.into_iter().map(|blueprint| {
2124-
let (is_target, enabled) = match target_blueprint {
2125-
Some(t) if t.target_id == blueprint.id => {
2126-
let enabled = if t.enabled { "yes" } else { "no" };
2127-
("*", enabled)
2128-
}
2129-
_ => ("", ""),
2124+
let (is_target, enabled) = if target_blueprint.target_id == blueprint.id
2125+
{
2126+
let enabled = if target_blueprint.enabled { "yes" } else { "no" };
2127+
("*", enabled)
2128+
} else {
2129+
("", "")
21302130
};
21312131
BlueprintRow {
21322132
is_target,

dev-tools/reconfigurator-cli/tests/output/cmds-stdout

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ ID SERIAL NZPOOLS SUBNET
1111
ID NERRORS TIME_DONE
1212

1313
> blueprint-list
14-
T ENA ID PARENT TIME_CREATED
14+
T ENA ID PARENT TIME_CREATED
15+
* no 00000000-0000-0000-0000-000000000000 <none> <REDACTED_TIMESTAMP>
1516

1617

1718
> sled-show dde1c0e2-b10d-4621-b420-f179f7a7a00a
@@ -863,14 +864,12 @@ wiped system
863864

864865
> load state.json
865866
loaded data from "state.json"
866-
warnings:
867-
could not determine active Nexus generation from serialized state: no target blueprint set (using default of 1)
868867
result:
869868
system:
870869
using collection 6e066695-94bc-4250-bd63-fd799c166cc1 as source of sled inventory data
871870
loaded sleds: 04ef3330-c682-4a08-8def-fcc4bef31bcd, 90c1102a-b9f5-4d88-92a2-60d54a2d98cc, dde1c0e2-b10d-4621-b420-f179f7a7a00a
872871
loaded collections: 6e066695-94bc-4250-bd63-fd799c166cc1
873-
loaded blueprints: (none)
872+
loaded blueprints: 00000000-0000-0000-0000-000000000000
874873
loaded external IP policy: ExternalIpPolicy { service_pool_ipv4_ranges: [Ipv4Range { first: 192.0.2.2, last: 192.0.2.20 }], service_pool_ipv6_ranges: [], external_dns_ips: {} }
875874
loaded internal DNS generations: (none)
876875
loaded external DNS generations: (none)

nexus/reconfigurator/preparation/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ pub async fn reconfigurator_state_load(
582582
Ok(UnstableReconfiguratorState {
583583
planning_input,
584584
collections,
585-
target_blueprint: Some(target_blueprint),
585+
target_blueprint,
586586
blueprints,
587587
internal_dns,
588588
external_dns,

nexus/reconfigurator/simulation/src/config.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl SimConfigBuilder {
166166
external_dns_zone_names: Vec<String>,
167167
silo_names: Vec<Name>,
168168
active_nexus_zones: &BTreeSet<OmicronZoneUuid>,
169-
target_blueprint: Option<&BlueprintTarget>,
169+
target_blueprint: &BlueprintTarget,
170170
all_blueprints: &[Blueprint],
171171
res: &mut LoadSerializedResultBuilder,
172172
) -> LoadSerializedConfigResult {
@@ -301,7 +301,7 @@ impl SimConfigBuilderInner {
301301
external_dns_zone_names: Vec<String>,
302302
silo_names: Vec<Name>,
303303
active_nexus_zones: &BTreeSet<OmicronZoneUuid>,
304-
target_blueprint: Option<&BlueprintTarget>,
304+
target_blueprint: &BlueprintTarget,
305305
all_blueprints: &[Blueprint],
306306
res: &mut LoadSerializedResultBuilder,
307307
) -> LoadSerializedConfigResult {
@@ -403,12 +403,17 @@ impl SimConfigBuilderInner {
403403

404404
fn determine_active_nexus_generation(
405405
active_nexus_zones: &BTreeSet<OmicronZoneUuid>,
406-
target_blueprint: Option<&BlueprintTarget>,
406+
target_blueprint: &BlueprintTarget,
407407
all_blueprints: &[Blueprint],
408408
) -> Result<Generation, String> {
409-
let Some(target_blueprint) = target_blueprint else {
410-
return Err("no target blueprint set".to_string());
411-
};
409+
// Real systems always have at least one active Nexus zone, but our
410+
// simulated system has some cases where we have none at all. We'll never be
411+
// able to find the generation matching an empty set, but because this is a
412+
// weird edge case that only applies to simulation, it's also fine to
413+
// default to "the initial generation".
414+
if active_nexus_zones.is_empty() {
415+
return Ok(Generation::new());
416+
}
412417

413418
let Some(blueprint) =
414419
all_blueprints.iter().find(|bp| bp.id == target_blueprint.target_id)

nexus/reconfigurator/simulation/src/errors.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,6 @@ impl KeyError {
105105
Self { id: ObjectId::Collection(id) }
106106
}
107107

108-
pub(crate) fn blueprint(id: BlueprintId) -> Self {
109-
Self { id: ObjectId::Blueprint(id) }
110-
}
111-
112108
pub(crate) fn resolved_collection(id: ResolvedCollectionId) -> Self {
113109
Self { id: ObjectId::ResolvedCollection(id) }
114110
}

nexus/reconfigurator/simulation/src/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl SimStateBuilder {
237237
state.external_dns_zone_names.clone(),
238238
state.silo_names.clone(),
239239
state.planning_input.active_nexus_zones(),
240-
state.target_blueprint.as_ref(),
240+
&state.target_blueprint,
241241
&state.blueprints,
242242
&mut res,
243243
);

0 commit comments

Comments
 (0)