Skip to content

Add desired host phase 2 contents to blueprint #8570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions dev-tools/omdb/tests/successes.out
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,14 @@ parent: <none>

sled: ..........<REDACTED_UUID>........... (active, config generation 2)

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents


physical disks:
-----------------------------------------------------------------
vendor model serial disposition
Expand Down Expand Up @@ -1492,6 +1500,14 @@ parent: <none>

sled: ..........<REDACTED_UUID>........... (active, config generation 2)

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents


physical disks:
----------------------------------------------------------------
vendor model serial disposition
Expand Down Expand Up @@ -1565,6 +1581,14 @@ parent: <none>

sled: ..........<REDACTED_UUID>........... (active, config generation 2)

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents


physical disks:
-----------------------------------------------------------------
vendor model serial disposition
Expand Down Expand Up @@ -1596,6 +1620,14 @@ parent: <none>

sled: ..........<REDACTED_UUID>........... (active, config generation 2)

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents


physical disks:
----------------------------------------------------------------
vendor model serial disposition
Expand Down
79 changes: 70 additions & 9 deletions dev-tools/reconfigurator-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,25 @@ use nexus_reconfigurator_simulation::{BlueprintId, CollectionId, SimState};
use nexus_reconfigurator_simulation::{SimStateBuilder, SimTufRepoSource};
use nexus_reconfigurator_simulation::{SimTufRepoDescription, Simulator};
use nexus_sled_agent_shared::inventory::ZoneKind;
use nexus_types::deployment::BlueprintHostPhase2DesiredContents;
use nexus_types::deployment::PlanningInput;
use nexus_types::deployment::SledFilter;
use nexus_types::deployment::execution;
use nexus_types::deployment::execution::blueprint_external_dns_config;
use nexus_types::deployment::execution::blueprint_internal_dns_config;
use nexus_types::deployment::{Blueprint, UnstableReconfiguratorState};
use nexus_types::deployment::{BlueprintArtifactVersion, PendingMgsUpdate};
use nexus_types::deployment::{BlueprintZoneDisposition, ExpectedVersion};
use nexus_types::deployment::{
BlueprintZoneImageSource, PendingMgsUpdateDetails,
};
use nexus_types::deployment::{BlueprintZoneImageVersion, PendingMgsUpdate};
use nexus_types::deployment::{OmicronZoneNic, TargetReleaseDescription};
use nexus_types::external_api::views::SledPolicy;
use nexus_types::external_api::views::SledProvisionPolicy;
use omicron_common::address::REPO_DEPOT_PORT;
use omicron_common::api::external::Name;
use omicron_common::api::external::{Generation, TufRepoDescription};
use omicron_common::disk::M2Slot;
use omicron_common::policy::NEXUS_REDUNDANCY;
use omicron_common::update::OmicronZoneManifestSource;
use omicron_repl_utils::run_repl_from_file;
Expand Down Expand Up @@ -573,6 +575,16 @@ enum BlueprintEditCommands {
#[command(subcommand)]
image_source: ImageSourceArgs,
},
/// set the desired host phase 2 image for an internal disk slot
SetHostPhase2 {
/// sled to set the field on
sled_id: SledOpt,
/// internal disk slot
#[clap(value_parser = parse_m2_slot)]
slot: M2Slot,
#[command(subcommand)]
phase_2_source: HostPhase2SourceArgs,
},
/// set the remove_mupdate_override field for a sled
SetRemoveMupdateOverride {
/// sled to set the field on
Expand Down Expand Up @@ -841,8 +853,8 @@ enum ImageSourceArgs {
InstallDataset,
/// the zone image comes from a specific TUF repo artifact
Artifact {
#[clap(value_parser = parse_blueprint_zone_image_version)]
version: BlueprintZoneImageVersion,
#[clap(value_parser = parse_blueprint_artifact_version)]
version: BlueprintArtifactVersion,
hash: ArtifactHash,
},
}
Expand Down Expand Up @@ -881,10 +893,10 @@ fn image_source_unwrap_or(
Ok(BlueprintZoneImageSource::InstallDataset) | Err(_) => (),
Ok(BlueprintZoneImageSource::Artifact { version, hash }) => {
let version = match version {
BlueprintZoneImageVersion::Available { version } => {
BlueprintArtifactVersion::Available { version } => {
version.to_string()
}
BlueprintZoneImageVersion::Unknown => {
BlueprintArtifactVersion::Unknown => {
"unknown".to_string()
}
};
Expand Down Expand Up @@ -914,19 +926,50 @@ impl From<ImageSourceArgs> for BlueprintZoneImageSource {
}
}

fn parse_blueprint_zone_image_version(
#[derive(Debug, Subcommand)]
enum HostPhase2SourceArgs {
/// keep the current phase 2 contents
CurrentContents,
/// the host phase 2 comes from a specific TUF repo artifact
Artifact {
#[clap(value_parser = parse_blueprint_artifact_version)]
version: BlueprintArtifactVersion,
hash: ArtifactHash,
},
}

impl From<HostPhase2SourceArgs> for BlueprintHostPhase2DesiredContents {
fn from(value: HostPhase2SourceArgs) -> Self {
match value {
HostPhase2SourceArgs::CurrentContents => Self::CurrentContents,
HostPhase2SourceArgs::Artifact { version, hash } => {
Self::Artifact { version, hash }
}
}
}
}

fn parse_blueprint_artifact_version(
version: &str,
) -> Result<BlueprintZoneImageVersion, ArtifactVersionError> {
) -> Result<BlueprintArtifactVersion, ArtifactVersionError> {
// Treat the literal string "unknown" as an unknown version.
if version == "unknown" {
return Ok(BlueprintZoneImageVersion::Unknown);
return Ok(BlueprintArtifactVersion::Unknown);
}

Ok(BlueprintZoneImageVersion::Available {
Ok(BlueprintArtifactVersion::Available {
version: version.parse::<ArtifactVersion>()?,
})
}

fn parse_m2_slot(slot: &str) -> anyhow::Result<M2Slot> {
match slot {
"A" | "a" | "0" => Ok(M2Slot::A),
"B" | "b" | "1" => Ok(M2Slot::B),
_ => bail!("invalid slot `{slot}` (expected `A` or `B`)"),
}
}

#[derive(Debug, Args)]
struct BlueprintArgs {
/// id of the blueprint, "latest", or "target"
Expand Down Expand Up @@ -1637,6 +1680,24 @@ fn cmd_blueprint_edit(
.context("failed to set image source")?;
rv
}
BlueprintEditCommands::SetHostPhase2 {
sled_id,
slot,
phase_2_source,
} => {
let sled_id = sled_id.to_sled_id(system.description())?;
let source =
BlueprintHostPhase2DesiredContents::from(phase_2_source);
let rv = format!(
"set sled {sled_id} host phase 2 slot {slot:?} source to \
{source}\n\
warn: no validation is done on the requested source"
);
builder
.sled_set_host_phase_2_slot(sled_id, slot, source)
.context("failed to set host phase 2 source")?;
rv
}
BlueprintEditCommands::ExpungeZone { zone_id } => {
let sled_id = sled_with_zone(&builder, &zone_id)?;
builder
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Load example system

load-example --nsleds 1

# Set slot A
blueprint-edit latest set-host-phase2 serial0 A artifact 1.0.0 3a9607047b03ccaab6d222249d890e93ca51b94ad631c7ca38be74cba60802ff
blueprint-diff latest

# Set slot B
blueprint-edit latest set-host-phase2 serial0 B artifact 2.0.0 044d45ad681b44e89c10e056cabdedf19fd8b1e54bc95e6622bcdd23f16bc8f2
blueprint-diff latest

blueprint-show latest

# Restore A to "current contents"
blueprint-edit latest set-host-phase2 serial0 A current-contents
blueprint-diff latest

# Restore B to "current contents"
blueprint-edit latest set-host-phase2 serial0 B current-contents
blueprint-diff latest

blueprint-show latest
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ parent: dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21

sled: 00320471-945d-413c-85e7-03e091a70b3c (active, config generation 1)

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents


physical disks:
-------------------------------------
vendor model serial disposition
Expand All @@ -80,6 +88,14 @@ parent: dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21

sled: 2b8f0cb3-0295-4b3c-bc58-4fe88b57112c (active, config generation 2)

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents


physical disks:
------------------------------------------------------------------------------------
vendor model serial disposition
Expand Down Expand Up @@ -134,6 +150,14 @@ parent: dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21

sled: 98e6b7c2-2efa-41ca-b20a-0a4d61102fe6 (active, config generation 2)

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents


physical disks:
------------------------------------------------------------------------------------
vendor model serial disposition
Expand Down Expand Up @@ -185,6 +209,14 @@ parent: dbcbd3d6-41ff-48ae-ac0b-1becc9b2fd21

sled: d81c6a84-79b8-4958-ae41-ea46c9b19763 (active, config generation 2)

host phase 2 contents:
------------------------
slot boot image source
------------------------
A current contents
B current contents


physical disks:
------------------------------------------------------------------------------------
vendor model serial disposition
Expand Down
Loading
Loading