Skip to content

Commit 90c578a

Browse files
authored
[21/n] reconfigurator-cli] add tuf-assemble command for TUF repo generation (#8469)
I need the ability to generate TUF repos for upcoming tests, and adapting the `target-release.txt` test seemed like the easiest way to do it. This also means that we no longer need to handle that test through a custom wrapper -- the standard `test-scripts.rs` test harness works well for it now. This is a standalone PR that can land independently of the rest.
1 parent cbae98c commit 90c578a

File tree

8 files changed

+103
-54
lines changed

8 files changed

+103
-54
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev-tools/reconfigurator-cli/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ slog.workspace = true
4242
swrite.workspace = true
4343
tabled.workspace = true
4444
tokio.workspace = true
45+
toml.workspace = true
46+
tufaceous.workspace = true
4547
tufaceous-artifact.workspace = true
48+
tufaceous-lib.workspace = true
4649
update-common.workspace = true
4750
uuid.workspace = true
4851
omicron-workspace-hack.workspace = true
@@ -59,7 +62,6 @@ omicron-test-utils.workspace = true
5962
serde.workspace = true
6063
subprocess.workspace = true
6164
tokio.workspace = true
62-
tufaceous.workspace = true
6365

6466
# Disable doc builds by default for our binaries to work around issue
6567
# rust-lang/cargo#8373. These docs would not be very useful anyway.

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

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,19 @@ use tabled::Tabled;
6060
use tufaceous_artifact::ArtifactHash;
6161
use tufaceous_artifact::ArtifactVersion;
6262
use tufaceous_artifact::ArtifactVersionError;
63+
use tufaceous_lib::assemble::ArtifactManifest;
6364
use update_common::artifacts::{ArtifactsWithPlan, ControlPlaneZonesMode};
6465

6566
mod log_capture;
6667

68+
/// The default key for TUF repository generation.
69+
///
70+
/// This was randomly generated through a tufaceous invocation.
71+
pub static DEFAULT_TUFACEOUS_KEY: &str = "ed25519:\
72+
MFECAQEwBQYDK2VwBCIEIJ9CnAhwk8PPt1x8icu\
73+
z9c12PdfCRHJpoUkuqJmIZ8GbgSEAbNGMpsHK5_w32\
74+
qwYdZH_BeVssmKzQlFsnPuaiHx2hy0=";
75+
6776
/// REPL state
6877
#[derive(Debug)]
6978
struct ReconfiguratorSim {
@@ -228,6 +237,7 @@ fn process_command(
228237
Commands::BlueprintSave(args) => cmd_blueprint_save(sim, args),
229238
Commands::Show => cmd_show(sim),
230239
Commands::Set(args) => cmd_set(sim, args),
240+
Commands::TufAssemble(args) => cmd_tuf_assemble(sim, args),
231241
Commands::Load(args) => cmd_load(sim, args),
232242
Commands::LoadExample(args) => cmd_load_example(sim, args),
233243
Commands::FileContents(args) => cmd_file_contents(args),
@@ -303,6 +313,9 @@ enum Commands {
303313
#[command(subcommand)]
304314
Set(SetArgs),
305315

316+
/// use tufaceous to generate a repo from a manifest
317+
TufAssemble(TufAssembleArgs),
318+
306319
/// save state to a file
307320
Save(SaveArgs),
308321
/// load state from a file
@@ -735,6 +748,20 @@ enum SetArgs {
735748
},
736749
}
737750

751+
#[derive(Debug, Args)]
752+
struct TufAssembleArgs {
753+
/// The tufaceous manifest path (relative to this crate's root)
754+
manifest_path: Utf8PathBuf,
755+
756+
#[clap(
757+
long,
758+
// Use help here rather than a doc comment because rustdoc doesn't like
759+
// `<` and `>` in help messages.
760+
help = "The path to the output [default: repo-<system-version>.zip]"
761+
)]
762+
output: Option<Utf8PathBuf>,
763+
}
764+
738765
#[derive(Debug, Args)]
739766
struct LoadArgs {
740767
/// input file
@@ -1770,6 +1797,60 @@ fn cmd_set(
17701797
Ok(Some(rv))
17711798
}
17721799

1800+
fn cmd_tuf_assemble(
1801+
sim: &ReconfiguratorSim,
1802+
args: TufAssembleArgs,
1803+
) -> anyhow::Result<Option<String>> {
1804+
let manifest_path = if args.manifest_path.is_absolute() {
1805+
args.manifest_path.clone()
1806+
} else {
1807+
// Use CARGO_MANIFEST_DIR to resolve relative paths.
1808+
let dir = std::env::var("CARGO_MANIFEST_DIR").context(
1809+
"CARGO_MANIFEST_DIR not set in environment \
1810+
(are you running with `cargo run`?)",
1811+
)?;
1812+
let mut dir = Utf8PathBuf::from(dir);
1813+
dir.push(&args.manifest_path);
1814+
dir
1815+
};
1816+
1817+
// Obtain the system version from the manifest.
1818+
let manifest =
1819+
ArtifactManifest::from_path(&manifest_path).with_context(|| {
1820+
format!("error parsing manifest from `{manifest_path}`")
1821+
})?;
1822+
1823+
let output_path = if let Some(output_path) = &args.output {
1824+
output_path.clone()
1825+
} else {
1826+
// This is relative to the current directory.
1827+
Utf8PathBuf::from(format!("repo-{}.zip", manifest.system_version))
1828+
};
1829+
1830+
// Just use a fixed key for now.
1831+
//
1832+
// In the future we may want to test changing the TUF key.
1833+
let args = tufaceous::Args::try_parse_from([
1834+
"tufaceous",
1835+
"--key",
1836+
DEFAULT_TUFACEOUS_KEY,
1837+
"assemble",
1838+
manifest_path.as_str(),
1839+
output_path.as_str(),
1840+
])
1841+
.expect("args are valid so this shouldn't fail");
1842+
let rt =
1843+
tokio::runtime::Runtime::new().context("creating tokio runtime")?;
1844+
rt.block_on(async move { args.exec(&sim.log).await })
1845+
.context("error executing tufaceous assemble")?;
1846+
1847+
let rv = format!(
1848+
"created {} for system version {}",
1849+
output_path, manifest.system_version,
1850+
);
1851+
Ok(Some(rv))
1852+
}
1853+
17731854
fn read_file(
17741855
input_path: &camino::Utf8Path,
17751856
) -> anyhow::Result<UnstableReconfiguratorState> {

dev-tools/reconfigurator-cli/tests/common/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub fn script_with_cwd(
5757
// However, it's necessary to redact paths from generated log entries.
5858
let stdout_text = Redactor::default()
5959
.uuids(false)
60+
.field("assembling repository in", ".*")
6061
.field("extracting uploaded archive to", ".*")
6162
.field("created directory to store extracted artifacts, path:", ".*")
6263
.do_redact(&stdout_text);

dev-tools/reconfigurator-cli/tests/input/target-release.txt renamed to dev-tools/reconfigurator-cli/tests/input/cmds-target-release.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ load-example --nsleds 3 --ndisks-per-sled 3
44
# Print the default target release
55
show
66

7-
# Load a target release from a fake file.
8-
# This file was generated by the test runner in a temporary directory that this
9-
# invocation of `reconfigurator-cli` is running out of as its working directory.
7+
# Create a TUF repository from a fake manifest. (The output TUF repo is
8+
# written to a temporary directory that this invocation of `reconfigurator-cli`
9+
# is running out of as its working directory.)
10+
tuf-assemble ../../update-common/manifests/fake.toml
11+
12+
# Load the target release from the assembled TUF repository.
1013
set target-release repo-1.0.0.zip
1114

1215
# Print the default target release again.

dev-tools/reconfigurator-cli/tests/output/target-release-stdout renamed to dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,16 @@ target release (generation 1): unset
1717

1818

1919

20-
> # Load a target release from a fake file.
21-
> # This file was generated by the test runner in a temporary directory that this
22-
> # invocation of `reconfigurator-cli` is running out of as its working directory.
20+
> # Create a TUF repository from a fake manifest. (The output TUF repo is
21+
> # written to a temporary directory that this invocation of `reconfigurator-cli`
22+
> # is running out of as its working directory.)
23+
> tuf-assemble ../../update-common/manifests/fake.toml
24+
INFO assembling repository in <ASSEMBLING_REPOSITORY_IN_REDACTED>
25+
INFO artifacts assembled and archived to `repo-1.0.0.zip`, component: OmicronRepoAssembler
26+
created repo-1.0.0.zip for system version 1.0.0
27+
28+
29+
> # Load the target release from the assembled TUF repository.
2330
> set target-release repo-1.0.0.zip
2431
INFO extracting uploaded archive to <EXTRACTING_UPLOADED_ARCHIVE_TO_REDACTED>
2532
INFO created directory to store extracted artifacts, path: <CREATED_DIRECTORY_TO_STORE_EXTRACTED_ARTIFACTS_PATH_REDACTED>

dev-tools/reconfigurator-cli/tests/test-custom.rs

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)