Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 11 additions & 56 deletions dev-tools/reconfigurator-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
//! developer REPL for driving blueprint planning

use anyhow::{Context, anyhow, bail};
use camino::{Utf8Path, Utf8PathBuf};
use camino::Utf8PathBuf;
use chrono::{DateTime, Utc};
use clap::{ArgAction, ValueEnum};
use clap::{Args, Parser, Subcommand};
Expand All @@ -20,7 +20,9 @@ use nexus_inventory::CollectionBuilder;
use nexus_reconfigurator_blippy::Blippy;
use nexus_reconfigurator_blippy::BlippyReportSortKey;
use nexus_reconfigurator_planning::blueprint_builder::BlueprintBuilder;
use nexus_reconfigurator_planning::example::ExampleSystemBuilder;
use nexus_reconfigurator_planning::example::{
ExampleSystemBuilder, extract_tuf_repo_description, tuf_assemble,
};
use nexus_reconfigurator_planning::planner::Planner;
use nexus_reconfigurator_planning::system::{
RotStateOverrides, SledBuilder, SledInventoryVisibility, SystemDescription,
Expand Down Expand Up @@ -48,8 +50,8 @@ use nexus_types::external_api::views::SledPolicy;
use nexus_types::external_api::views::SledProvisionPolicy;
use nexus_types::inventory::CollectionDisplayCliFilter;
use omicron_common::address::REPO_DEPOT_PORT;
use omicron_common::api::external::Generation;
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;
Expand All @@ -74,9 +76,6 @@ use tufaceous_artifact::ArtifactHash;
use tufaceous_artifact::ArtifactVersion;
use tufaceous_artifact::ArtifactVersionError;
use tufaceous_lib::assemble::ArtifactManifest;
use update_common::artifacts::{
ArtifactsWithPlan, ControlPlaneZonesMode, VerificationMode,
};

mod log_capture;

Expand Down Expand Up @@ -2752,32 +2751,6 @@ fn mupdate_source_to_description(
}
}

fn extract_tuf_repo_description(
log: &slog::Logger,
filename: &Utf8Path,
) -> anyhow::Result<TufRepoDescription> {
let file = std::fs::File::open(filename)
.with_context(|| format!("open {:?}", filename))?;
let buf = std::io::BufReader::new(file);
let rt =
tokio::runtime::Runtime::new().context("creating tokio runtime")?;
let repo_hash = ArtifactHash([0; 32]);
let artifacts_with_plan = rt.block_on(async {
ArtifactsWithPlan::from_zip(
buf,
None,
repo_hash,
ControlPlaneZonesMode::Split,
VerificationMode::BlindlyTrustAnything,
log,
)
.await
.with_context(|| format!("unpacking {:?}", filename))
})?;
let description = artifacts_with_plan.description().clone();
Ok(description)
}

fn cmd_tuf_assemble(
sim: &ReconfiguratorSim,
args: TufAssembleArgs,
Expand Down Expand Up @@ -2808,30 +2781,12 @@ fn cmd_tuf_assemble(
Utf8PathBuf::from(format!("repo-{}.zip", manifest.system_version))
};

if output_path.exists() {
bail!("output path `{output_path}` already exists");
}

// Just use a fixed key for now.
//
// In the future we may want to test changing the TUF key.
let mut tufaceous_args = vec![
"tufaceous",
"--key",
DEFAULT_TUFACEOUS_KEY,
"assemble",
manifest_path.as_str(),
output_path.as_str(),
];
if args.allow_non_semver {
tufaceous_args.push("--allow-non-semver");
}
let args = tufaceous::Args::try_parse_from(tufaceous_args)
.expect("args are valid so this shouldn't fail");
let rt =
tokio::runtime::Runtime::new().context("creating tokio runtime")?;
rt.block_on(async move { args.exec(&sim.log).await })
.context("error executing tufaceous assemble")?;
tuf_assemble(
&sim.log,
&manifest_path,
&output_path,
args.allow_non_semver,
)?;

let rv = format!(
"created {} for system version {}",
Expand Down
104 changes: 73 additions & 31 deletions nexus-sled-agent-shared/src/inventory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,40 +223,52 @@ impl ConfigReconcilerInventory {
datasets,
orphaned_datasets: IdOrdMap::new(),
zones,
boot_partitions: {
BootPartitionContents {
boot_disk: Ok(M2Slot::A),
slot_a: Ok(BootPartitionDetails {
header: BootImageHeader {
flags: 0,
data_size: 1000,
image_size: 1000,
target_size: 1000,
sha256: [0; 32],
image_name: "fake from debug_assume_success()"
.to_string(),
},
artifact_hash: ArtifactHash([0x0a; 32]),
artifact_size: 1000,
}),
slot_b: Ok(BootPartitionDetails {
header: BootImageHeader {
flags: 0,
data_size: 1000,
image_size: 1000,
target_size: 1000,
sha256: [1; 32],
image_name: "fake from debug_assume_success()"
.to_string(),
},
artifact_hash: ArtifactHash([0x0b; 32]),
artifact_size: 1000,
}),
}
},
boot_partitions: BootPartitionContents::debug_assume_success(),
remove_mupdate_override,
}
}

/// Given a sled config, update an existing reconciler result to simulate an
/// output that sled-agent could have emitted if reconciliation succeeded.
///
/// This method should only be used by tests and dev tools; real code should
/// look at the actual `last_reconciliation` value from the parent
/// [`Inventory`].
pub fn debug_update_assume_success(&mut self, config: OmicronSledConfig) {
let external_disks = config
.disks
.iter()
.map(|d| (d.id, ConfigReconcilerInventoryResult::Ok))
.collect();
let datasets = config
.datasets
.iter()
.map(|d| (d.id, ConfigReconcilerInventoryResult::Ok))
.collect();
let zones = config
.zones
.iter()
.map(|z| (z.id, ConfigReconcilerInventoryResult::Ok))
.collect();
let remove_mupdate_override =
config.remove_mupdate_override.map(|_| {
RemoveMupdateOverrideInventory {
boot_disk_result: Ok(
RemoveMupdateOverrideBootSuccessInventory::Removed,
),
non_boot_message: "mupdate override successfully removed \
on non-boot disks"
.to_owned(),
}
});

self.last_reconciled_config = config;
self.external_disks = external_disks;
self.datasets = datasets;
self.orphaned_datasets = IdOrdMap::new();
self.zones = zones;
self.remove_mupdate_override = remove_mupdate_override;
}
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, JsonSchema, Serialize)]
Expand Down Expand Up @@ -286,6 +298,36 @@ impl BootPartitionContents {
M2Slot::B => &self.slot_b,
}
}

pub fn debug_assume_success() -> Self {
Self {
boot_disk: Ok(M2Slot::A),
slot_a: Ok(BootPartitionDetails {
header: BootImageHeader {
flags: 0,
data_size: 1000,
image_size: 1000,
target_size: 1000,
sha256: [0; 32],
image_name: "fake from debug_assume_success()".to_string(),
},
artifact_hash: ArtifactHash([0x0a; 32]),
artifact_size: 1000,
}),
slot_b: Ok(BootPartitionDetails {
header: BootImageHeader {
flags: 0,
data_size: 1000,
image_size: 1000,
target_size: 1000,
sha256: [1; 32],
image_name: "fake from debug_assume_success()".to_string(),
},
artifact_hash: ArtifactHash([0x0b; 32]),
artifact_size: 1000,
}),
}
}
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, JsonSchema, Serialize)]
Expand Down
7 changes: 7 additions & 0 deletions nexus/reconfigurator/planning/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ workspace = true

[dependencies]
anyhow.workspace = true
camino.workspace = true
camino-tempfile.workspace = true
clap.workspace = true
clickhouse-admin-types.workspace = true
cockroach-admin-types.workspace = true
chrono.workspace = true
Expand Down Expand Up @@ -41,8 +44,12 @@ static_assertions.workspace = true
strum.workspace = true
swrite.workspace = true
thiserror.workspace = true
tokio.workspace = true
tufaceous.workspace = true
tufaceous-artifact.workspace = true
tufaceous-lib.workspace = true
typed-rng.workspace = true
update-common.workspace = true
uuid.workspace = true

omicron-workspace-hack.workspace = true
Expand Down
Loading
Loading