From b2b01bfe879ffd61d5201b8be36e902eb43fe0c6 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Tue, 19 Aug 2025 01:12:41 +0000 Subject: [PATCH] Add Measurement Corpus artifact This will be installed for wicket via the installinator document. For now, the measurements are treated as a subset of the control plane installation procedure. This may change as we add reconfigurator support. --- Cargo.lock | 326 ++++++++++-------- Cargo.toml | 9 +- .../output/cmds-mupdate-update-flow-stdout | 12 +- .../output/cmds-noop-image-source-stdout | 6 +- .../tests/output/cmds-target-release-stdout | 9 +- dev-tools/releng/Cargo.toml | 1 + dev-tools/releng/src/hubris.rs | 32 ++ dev-tools/releng/src/tuf.rs | 41 +++ installinator-common/src/progress.rs | 23 +- installinator/src/artifact.rs | 26 ++ installinator/src/dispatch.rs | 99 +++++- installinator/src/write.rs | 100 +++++- .../src/mgs_updates/rot_bootloader.rs | 1 + .../planning/src/mgs_updates/sp.rs | 1 + openapi/installinator.json | 11 +- update-common/manifests/fake-non-semver.toml | 5 + update-common/manifests/fake.toml | 5 +- update-common/src/artifacts/update_plan.rs | 33 +- wicketd/src/installinator_progress.rs | 2 +- workspace-hack/Cargo.toml | 10 +- 20 files changed, 580 insertions(+), 172 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e7be7a6771..7d6ba0c60cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -740,7 +740,7 @@ dependencies = [ "bitflags 2.9.1", "cexpr", "clang-sys", - "itertools 0.13.0", + "itertools 0.12.1", "log", "prettyplease", "proc-macro2", @@ -783,9 +783,23 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitfield" -version = "0.14.0" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" +checksum = "62a3a774b2fcac1b726922b921ebba5e9fe36ad37659c822cf8ff2c1e0819892" +dependencies = [ + "bitfield-macros", +] + +[[package]] +name = "bitfield-macros" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52511b09931f7d5fe3a14f23adefbc23e5725b184013e96c8419febb61f14734" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] [[package]] name = "bitfield-struct" @@ -944,7 +958,7 @@ dependencies = [ "omicron-common", "omicron-uuid-kinds", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "sled-agent-types", "sled-hardware-types", @@ -962,7 +976,7 @@ dependencies = [ "progenitor 0.10.0", "regress", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "sled-hardware-types", @@ -1438,7 +1452,7 @@ dependencies = [ "omicron-workspace-hack", "oxide-tokio-rt", "ratatui", - "schemars", + "schemars 0.8.22", "serde_json", "slog", "slog-async", @@ -1459,7 +1473,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "openapi-manager-types", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", ] @@ -1474,7 +1488,7 @@ dependencies = [ "omicron-workspace-hack", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "slog", ] @@ -1489,7 +1503,7 @@ dependencies = [ "omicron-workspace-hack", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "slog", ] @@ -1504,7 +1518,7 @@ dependencies = [ "omicron-workspace-hack", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "slog", ] @@ -1535,7 +1549,7 @@ dependencies = [ "itertools 0.14.0", "omicron-common", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -1568,7 +1582,7 @@ dependencies = [ "camino", "clap", "derive_more 0.99.20", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "thiserror 1.0.69", @@ -1610,7 +1624,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "openapi-manager-types", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", ] @@ -1624,7 +1638,7 @@ dependencies = [ "omicron-workspace-hack", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "slog", ] @@ -1638,7 +1652,7 @@ dependencies = [ "omicron-common", "omicron-workspace-hack", "proptest", - "schemars", + "schemars 0.8.22", "serde", "test-strategy", "thiserror 2.0.12", @@ -1670,7 +1684,7 @@ dependencies = [ "oximeter 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "oxnet", "rand 0.9.2", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -1692,7 +1706,7 @@ dependencies = [ "oximeter 0.1.0 (git+https://github.com/oxidecomputer/omicron?branch=main)", "oxnet", "rand 0.8.5", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -1711,7 +1725,7 @@ source = "git+https://github.com/oxidecomputer/lldp#82fbc8c9747eb9f74dde0f92ae77 dependencies = [ "anyhow", "dpd-client 0.1.0 (git+https://github.com/oxidecomputer/dendrite)", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -2071,7 +2085,7 @@ dependencies = [ "percent-encoding", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", ] @@ -2083,7 +2097,7 @@ source = "git+https://github.com/oxidecomputer/crucible?rev=779775d5130ff7a4836f dependencies = [ "base64 0.22.1", "crucible-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "uuid", @@ -2100,7 +2114,7 @@ dependencies = [ "dropshot", "nix 0.29.0", "rustls-pemfile 1.0.4", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -2129,7 +2143,7 @@ dependencies = [ "percent-encoding", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "uuid", @@ -2484,6 +2498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -2629,7 +2644,7 @@ dependencies = [ "attest-data", "const-oid", "ed25519-dalek", - "env_logger 0.11.5", + "env_logger", "log", "p384", "pem-rfc7468", @@ -2794,7 +2809,7 @@ dependencies = [ "pretty-hex 0.4.1", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -2820,7 +2835,7 @@ dependencies = [ "internal-dns-types", "omicron-workspace-hack", "openapi-manager-types", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", ] @@ -2836,7 +2851,7 @@ dependencies = [ "omicron-workspace-hack", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "slog", ] @@ -2885,7 +2900,7 @@ dependencies = [ "progenitor 0.9.1", "regress", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -2909,7 +2924,7 @@ dependencies = [ "progenitor 0.9.1", "regress", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -2946,7 +2961,7 @@ dependencies = [ "percent-encoding", "rustls 0.22.4", "rustls-pemfile 2.2.0", - "schemars", + "schemars 0.8.22", "scopeguard", "semver 1.0.26", "serde", @@ -3196,23 +3211,14 @@ dependencies = [ "log", ] -[[package]] -name = "env_logger" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" -dependencies = [ - "is-terminal", - "log", - "termcolor", -] - [[package]] name = "env_logger" version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" dependencies = [ + "anstream", + "anstyle", "env_filter", "log", ] @@ -3240,7 +3246,7 @@ dependencies = [ "dropshot", "omicron-uuid-kinds", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "thiserror 2.0.12", @@ -3669,7 +3675,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "openapi-manager-types", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "uuid", @@ -3716,7 +3722,7 @@ dependencies = [ "progenitor 0.10.0", "rand 0.9.2", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -3821,7 +3827,7 @@ dependencies = [ "omicron-common", "omicron-uuid-kinds", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "thiserror 2.0.12", "tufaceous-artifact", @@ -4812,7 +4818,7 @@ dependencies = [ "derive-where", "omicron-workspace-hack", "proptest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "test-strategy", @@ -4831,7 +4837,7 @@ dependencies = [ "hashbrown 0.15.4", "ref-cast", "rustc-hash 2.1.1", - "schemars", + "schemars 0.8.22", "serde", "serde_json", ] @@ -4926,7 +4932,7 @@ dependencies = [ "oxlog", "oxnet", "regress", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -4965,6 +4971,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] @@ -5141,7 +5148,7 @@ dependencies = [ "omicron-common", "omicron-uuid-kinds", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "slog", "tufaceous-artifact", @@ -5159,7 +5166,7 @@ dependencies = [ "progenitor 0.10.0", "regress", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -5177,7 +5184,7 @@ dependencies = [ "omicron-common", "omicron-workspace-hack", "proptest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "serde_with", @@ -5255,7 +5262,7 @@ dependencies = [ "omicron-common", "omicron-uuid-kinds", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "serde_json", ] @@ -5320,7 +5327,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf370abdafd54d13e54a620e8c3e1145f28e46cc9d704bc6d94414559df41763" dependencies = [ - "schemars", + "schemars 0.8.22", "serde", ] @@ -5846,7 +5853,7 @@ dependencies = [ "progenitor 0.9.1", "protocol", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -5894,7 +5901,7 @@ dependencies = [ [[package]] name = "lpc55_areas" version = "0.2.5" -source = "git+https://github.com/oxidecomputer/lpc55_support#17d04af60b3a4fd82c77b1a33ca5370943cd25d9" +source = "git+https://github.com/oxidecomputer/lpc55_support#b507bc6d5dbebabc1d4c9b1ea3c8f24afd68fcae" dependencies = [ "bitfield", "clap", @@ -5905,13 +5912,13 @@ dependencies = [ [[package]] name = "lpc55_sign" version = "0.3.4" -source = "git+https://github.com/oxidecomputer/lpc55_support#17d04af60b3a4fd82c77b1a33ca5370943cd25d9" +source = "git+https://github.com/oxidecomputer/lpc55_support#b507bc6d5dbebabc1d4c9b1ea3c8f24afd68fcae" dependencies = [ "byteorder", "const-oid", "crc-any", "der", - "env_logger 0.10.2", + "env_logger", "hex", "log", "lpc55_areas", @@ -5922,9 +5929,9 @@ dependencies = [ "serde", "serde-hex", "sha2", - "thiserror 1.0.69", + "thiserror 2.0.12", "x509-cert", - "zerocopy 0.6.6", + "zerocopy 0.8.26", ] [[package]] @@ -6067,7 +6074,7 @@ dependencies = [ "percent-encoding", "progenitor 0.9.1", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -6234,7 +6241,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a17d82edb1c8a6c20c238747ae7aae9181133e766bc92cd2556fdd764407d0d1" dependencies = [ "proptest", - "schemars", + "schemars 0.8.22", "serde", "uuid", ] @@ -6312,7 +6319,7 @@ dependencies = [ "progenitor 0.10.0", "regress", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -6332,7 +6339,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "pretty_assertions", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "serde_with", @@ -6433,7 +6440,7 @@ dependencies = [ "rand 0.9.2", "ref-cast", "regex", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -6517,7 +6524,7 @@ dependencies = [ "ref-cast", "regex", "rustls 0.22.4", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -6590,7 +6597,7 @@ dependencies = [ "omicron-common", "omicron-uuid-kinds", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "uuid", ] @@ -7002,7 +7009,7 @@ dependencies = [ "omicron-passwords", "omicron-uuid-kinds", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "sled-hardware-types", @@ -7137,7 +7144,7 @@ dependencies = [ "parse-display", "proptest", "regex", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -7251,7 +7258,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "openapi-manager-types", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", ] @@ -7264,7 +7271,7 @@ dependencies = [ "omicron-workspace-hack", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "slog", ] @@ -7277,7 +7284,7 @@ dependencies = [ "omicron-common", "omicron-workspace-hack", "proptest", - "schemars", + "schemars 0.8.22", "serde", "test-strategy", "thiserror 2.0.12", @@ -7550,7 +7557,7 @@ dependencies = [ "oxide-tokio-rt", "oximeter-db", "oximeter-test-utils", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -7594,7 +7601,7 @@ dependencies = [ "pq-sys", "proptest", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -7663,7 +7670,7 @@ dependencies = [ "rand 0.9.2", "regress", "reqwest", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_human_bytes", @@ -7773,7 +7780,7 @@ dependencies = [ "oximeter 0.1.0", "oximeter-instruments", "oximeter-producer", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "signal-hook", @@ -7975,7 +7982,7 @@ dependencies = [ "rustls 0.22.4", "rustls-pemfile 2.2.0", "samael", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -8036,7 +8043,7 @@ dependencies = [ "pq-sys", "proptest", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -8189,7 +8196,7 @@ dependencies = [ "omicron-workspace-hack", "rand 0.9.2", "rust-argon2", - "schemars", + "schemars 0.8.22", "secrecy 0.10.3", "serde", "serde_with", @@ -8256,6 +8263,7 @@ dependencies = [ "omicron-pins", "omicron-workspace-hack", "omicron-zone-package", + "rats-corim", "reqwest", "semver 1.0.26", "serde", @@ -8397,7 +8405,7 @@ dependencies = [ "repo-depot-api", "repo-depot-client", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_human_bytes", "serde_json", @@ -8490,7 +8498,7 @@ dependencies = [ "newtype-uuid", "paste", "proptest", - "schemars", + "schemars 0.8.22", ] [[package]] @@ -8531,6 +8539,7 @@ dependencies = [ "ed25519-dalek", "either", "elliptic-curve", + "env_logger", "ff", "flate2", "foldhash", @@ -8561,7 +8570,6 @@ dependencies = [ "ipnetwork", "itertools 0.10.5", "itertools 0.12.1", - "itertools 0.13.0", "lalrpop-util", "lazy_static", "libc", @@ -8604,11 +8612,12 @@ dependencies = [ "rustix 1.0.7", "rustls 0.23.19", "rustls-webpki 0.102.8", - "schemars", + "schemars 0.8.22", "scopeguard", "semver 1.0.26", "serde", "serde_json", + "serde_with", "sha1", "sha2", "similar", @@ -9014,7 +9023,7 @@ dependencies = [ "omicron-common", "omicron-workspace-hack", "openapi-manager-types", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "uuid", @@ -9065,7 +9074,7 @@ dependencies = [ "qorb", "rand 0.9.2", "reqwest", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -9130,7 +9139,7 @@ dependencies = [ "regex", "reqwest", "rustyline", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -9166,7 +9175,7 @@ dependencies = [ "omicron-workspace-hack", "oximeter 0.1.0", "rand 0.9.2", - "schemars", + "schemars 0.8.22", "serde", "slog", "slog-async", @@ -9212,7 +9221,7 @@ dependencies = [ "omicron-test-utils", "omicron-workspace-hack", "oximeter 0.1.0", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -9236,7 +9245,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "schemars", + "schemars 0.8.22", "serde", "slog-error-chain", "syn 2.0.104", @@ -9257,7 +9266,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "schemars", + "schemars 0.8.22", "serde", "slog-error-chain", "syn 2.0.104", @@ -9323,7 +9332,7 @@ dependencies = [ "rand_distr", "regex", "rstest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "strum 0.27.2", @@ -9345,7 +9354,7 @@ dependencies = [ "omicron-workspace-hack", "parse-display", "regex", - "schemars", + "schemars 0.8.22", "serde", "strum 0.26.3", "thiserror 1.0.69", @@ -9375,7 +9384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8200429754152e6379fbb1dd06eea90156c3b67591f6e31d08e787d010ef0168" dependencies = [ "ipnetwork", - "schemars", + "schemars 0.8.22", "serde", "serde_json", ] @@ -9390,7 +9399,7 @@ dependencies = [ "num", "omicron-workspace-hack", "oximeter-types 0.1.0", - "schemars", + "schemars 0.8.22", "serde", ] @@ -10336,7 +10345,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "syn 2.0.104", @@ -10358,7 +10367,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "syn 2.0.104", @@ -10380,7 +10389,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "syn 2.0.104", @@ -10399,7 +10408,7 @@ dependencies = [ "proc-macro2", "progenitor-impl 0.8.0", "quote", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "serde_tokenstream", @@ -10417,7 +10426,7 @@ dependencies = [ "proc-macro2", "progenitor-impl 0.9.1", "quote", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "serde_tokenstream", @@ -10435,7 +10444,7 @@ dependencies = [ "proc-macro2", "progenitor-impl 0.10.0", "quote", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "serde_tokenstream", @@ -10457,7 +10466,7 @@ dependencies = [ "propolis_api_types", "rand 0.8.5", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -10478,7 +10487,7 @@ dependencies = [ "progenitor 0.8.0", "rand 0.8.5", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -10505,7 +10514,7 @@ dependencies = [ "propolis_types", "rand 0.8.5", "reqwest", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -10539,7 +10548,7 @@ source = "git+https://github.com/oxidecomputer/propolis?rev=23b06c2f452a97fac1dc dependencies = [ "crucible-client-types", "propolis_types", - "schemars", + "schemars 0.8.22", "serde", "thiserror 1.0.69", "uuid", @@ -10550,7 +10559,7 @@ name = "propolis_types" version = "0.0.0" source = "git+https://github.com/oxidecomputer/propolis?rev=23b06c2f452a97fac1dc12561d8451ce876d7c5a#23b06c2f452a97fac1dc12561d8451ce876d7c5a" dependencies = [ - "schemars", + "schemars 0.8.22", "serde", ] @@ -10580,7 +10589,7 @@ version = "0.1.0" source = "git+https://github.com/oxidecomputer/lldp#82fbc8c9747eb9f74dde0f92ae77ec67f65652c4" dependencies = [ "anyhow", - "schemars", + "schemars 0.8.22", "serde", "thiserror 1.0.69", ] @@ -10849,6 +10858,21 @@ dependencies = [ "unicode-width 0.2.0", ] +[[package]] +name = "rats-corim" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/rats-corim.git?branch=main#f0d5d5168d3d31487a56df32c676b0c6240bcc6b" +dependencies = [ + "ciborium", + "ciborium-io", + "clap", + "hex", + "serde", + "serde_with", + "strum 0.26.3", + "thiserror 2.0.12", +] + [[package]] name = "rayon" version = "1.10.0" @@ -11097,7 +11121,7 @@ version = "0.1.0" dependencies = [ "dropshot", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", "tufaceous-artifact", ] @@ -11109,7 +11133,7 @@ dependencies = [ "omicron-workspace-hack", "progenitor 0.10.0", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "slog", ] @@ -11725,6 +11749,30 @@ dependencies = [ "uuid", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "schemars_derive" version = "0.8.22" @@ -12076,6 +12124,10 @@ dependencies = [ "base64 0.22.1", "chrono", "hex", + "indexmap 1.9.3", + "indexmap 2.10.0", + "schemars 0.9.0", + "schemars 1.0.4", "serde", "serde_derive", "serde_json", @@ -12297,7 +12349,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "openapi-manager-types", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "sled-agent-types", @@ -12323,7 +12375,7 @@ dependencies = [ "propolis-client 0.1.0 (git+https://github.com/oxidecomputer/propolis?rev=23b06c2f452a97fac1dc12561d8451ce876d7c5a)", "regress", "reqwest", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "sled-agent-types", @@ -12361,7 +12413,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "proptest", - "schemars", + "schemars 0.8.22", "scopeguard", "serde", "serde_json", @@ -12400,7 +12452,7 @@ dependencies = [ "oxnet", "propolis-client 0.1.0 (git+https://github.com/oxidecomputer/propolis?rev=23b06c2f452a97fac1dc12561d8451ce876d7c5a)", "rcgen", - "schemars", + "schemars 0.8.22", "serde", "serde_human_bytes", "serde_json", @@ -12483,7 +12535,7 @@ dependencies = [ "parallel-task-set", "rand 0.9.2", "regex", - "schemars", + "schemars 0.8.22", "serde", "sled-storage", "slog", @@ -12512,7 +12564,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "rand 0.9.2", - "schemars", + "schemars 0.8.22", "serde", "sled-hardware-types", "slog", @@ -12531,7 +12583,7 @@ dependencies = [ "macaddr", "omicron-common", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "serde", ] @@ -12556,7 +12608,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "rand 0.9.2", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "sled-hardware", @@ -12993,7 +13045,7 @@ dependencies = [ "lazy_static", "newtype_derive", "petgraph 0.6.5", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "slog", @@ -14099,7 +14151,7 @@ dependencies = [ "hubpack", "itertools 0.14.0", "nix 0.29.0", - "schemars", + "schemars 0.8.22", "serde", "slog", "slog-async", @@ -14123,7 +14175,7 @@ dependencies = [ "hubpack", "itertools 0.14.0", "nix 0.29.0", - "schemars", + "schemars 0.8.22", "serde", "slog", "slog-async", @@ -14142,7 +14194,7 @@ name = "transceiver-decode" version = "0.1.0" source = "git+https://github.com/oxidecomputer/transceiver-control?branch=main#f3cb309c2bd2c03423467fd93992e9033ae3133c" dependencies = [ - "schemars", + "schemars 0.8.22", "serde", "static_assertions", "thiserror 2.0.12", @@ -14154,7 +14206,7 @@ name = "transceiver-decode" version = "0.1.0" source = "git+https://github.com/oxidecomputer/transceiver-control#4aac6125a8e6cefbb71d9f8a3d1fe6704207d476" dependencies = [ - "schemars", + "schemars 0.8.22", "serde", "static_assertions", "thiserror 2.0.12", @@ -14169,7 +14221,7 @@ dependencies = [ "bitflags 2.9.1", "clap", "hubpack", - "schemars", + "schemars 0.8.22", "serde", "thiserror 2.0.12", ] @@ -14182,7 +14234,7 @@ dependencies = [ "bitflags 2.9.1", "clap", "hubpack", - "schemars", + "schemars 0.8.22", "serde", "thiserror 2.0.12", ] @@ -14267,7 +14319,7 @@ dependencies = [ [[package]] name = "tufaceous" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/tufaceous?branch=main#57832718056c6585b4cddb4f3ebc04b9a07c7bd7" +source = "git+https://github.com/oxidecomputer/tufaceous?branch=measurement_corpus_take_2#7dcff8601c81039f9b717722267daff19bbe1ff3" dependencies = [ "anyhow", "camino", @@ -14288,12 +14340,12 @@ dependencies = [ [[package]] name = "tufaceous-artifact" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/tufaceous?branch=main#57832718056c6585b4cddb4f3ebc04b9a07c7bd7" +source = "git+https://github.com/oxidecomputer/tufaceous?branch=measurement_corpus_take_2#7dcff8601c81039f9b717722267daff19bbe1ff3" dependencies = [ "daft", "hex", "proptest", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_human_bytes", @@ -14305,7 +14357,7 @@ dependencies = [ [[package]] name = "tufaceous-brand-metadata" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/tufaceous?branch=main#57832718056c6585b4cddb4f3ebc04b9a07c7bd7" +source = "git+https://github.com/oxidecomputer/tufaceous?branch=measurement_corpus_take_2#7dcff8601c81039f9b717722267daff19bbe1ff3" dependencies = [ "semver 1.0.26", "serde", @@ -14317,7 +14369,7 @@ dependencies = [ [[package]] name = "tufaceous-lib" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/tufaceous?branch=main#57832718056c6585b4cddb4f3ebc04b9a07c7bd7" +source = "git+https://github.com/oxidecomputer/tufaceous?branch=measurement_corpus_take_2#7dcff8601c81039f9b717722267daff19bbe1ff3" dependencies = [ "anyhow", "async-trait", @@ -14483,7 +14535,7 @@ dependencies = [ "proc-macro2", "quote", "regress", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -14503,7 +14555,7 @@ dependencies = [ "proc-macro2", "quote", "regress", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -14523,7 +14575,7 @@ dependencies = [ "proc-macro2", "quote", "regress", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -14540,7 +14592,7 @@ checksum = "785e2cdcef0df8160fdd762ed548a637aaec1e83704fdbc14da0df66013ee8d0" dependencies = [ "proc-macro2", "quote", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -14557,7 +14609,7 @@ checksum = "68b5780d745920ed73c5b7447496a9b5c42ed2681a9b70859377aec423ecf02b" dependencies = [ "proc-macro2", "quote", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -14574,7 +14626,7 @@ checksum = "0ff5799be156e4f635c348c6051d165e1c59997827155133351a8c4d333d9841" dependencies = [ "proc-macro2", "quote", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -14774,7 +14826,7 @@ dependencies = [ "omicron-workspace-hack", "owo-colors", "petgraph 0.8.2", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "serde_with", @@ -15253,7 +15305,7 @@ dependencies = [ "omicron-workspace-hack", "owo-colors", "oxnet", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "sha2", @@ -15343,7 +15395,7 @@ dependencies = [ "oxnet", "rand 0.9.2", "reqwest", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", @@ -15388,7 +15440,7 @@ dependencies = [ "omicron-passwords", "omicron-uuid-kinds", "omicron-workspace-hack", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "sled-hardware-types", @@ -15409,7 +15461,7 @@ dependencies = [ "progenitor 0.10.0", "regress", "reqwest", - "schemars", + "schemars 0.8.22", "semver 1.0.26", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index d880996bdc1..fe63b68b560 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -653,6 +653,7 @@ rand_distr = "0.5.1" rand_seeder = "0.4.0" range-requests = { path = "range-requests" } ratatui = "0.29.0" +rats-corim = { git = "https://github.com/oxidecomputer/rats-corim.git", branch = "main" } rayon = "1.10" rcgen = "0.12.1" reconfigurator-cli = { path = "dev-tools/reconfigurator-cli" } @@ -753,10 +754,10 @@ toml_edit = "0.22.27" tough = { version = "0.20.0", features = [ "http" ] } transceiver-controller = { git = "https://github.com/oxidecomputer/transceiver-control", features = [ "api-traits" ] } trybuild = "1.0.106" -tufaceous = { git = "https://github.com/oxidecomputer/tufaceous", branch = "main" } -tufaceous-artifact = { git = "https://github.com/oxidecomputer/tufaceous", branch = "main", features = ["proptest", "schemars"] } -tufaceous-brand-metadata = { git = "https://github.com/oxidecomputer/tufaceous", branch = "main" } -tufaceous-lib = { git = "https://github.com/oxidecomputer/tufaceous", branch = "main" } +tufaceous = { git = "https://github.com/oxidecomputer/tufaceous", branch = "measurement_corpus_take_2" } +tufaceous-artifact = { git = "https://github.com/oxidecomputer/tufaceous", branch = "measurement_corpus_take_2", features = ["proptest", "schemars"] } +tufaceous-brand-metadata = { git = "https://github.com/oxidecomputer/tufaceous", branch = "measurement_corpus_take_2" } +tufaceous-lib = { git = "https://github.com/oxidecomputer/tufaceous", branch = "measurement_corpus_take_2" } tui-tree-widget = "0.23.1" typed-rng = { path = "typed-rng" } typify = "0.3.0" diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout index 74cedfee3f1..e1e763fbc0c 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-mupdate-update-flow-stdout @@ -36,6 +36,7 @@ INFO added artifact, name: internal-dns, kind: zone, version: 1.0.0, hash: ffbf1 INFO added artifact, name: ntp, kind: zone, version: 1.0.0, hash: 67593d686ed04a1709f93972b71f4ebc148a9362120f65d239943e814a9a7439, length: 1681 INFO added artifact, name: nexus, kind: zone, version: 1.0.0, hash: 0e32b4a3e5d3668bb1d6a16fb06b74dc60b973fa479dcee0aae3adbb52bf1388, length: 1682 INFO added artifact, name: oximeter, kind: zone, version: 1.0.0, hash: 048d8fe8cdef5b175aad714d0f148aa80ce36c9114ac15ce9d02ed3d37877a77, length: 1682 +INFO added artifact, name: fake-corpus, kind: measurement_corpus, version: 1.0.0, hash: 8a0e23157bae655fceec7376926c9758efee6511c7b7ff8355bbb49545a2257f, length: 1048576 INFO added artifact, name: fake-psc-sp, kind: psc_sp, version: 1.0.0, hash: 89245fe2ac7e6a2ac8dfa4e7d6891a6e6df95e4141395c07c64026778f6d76d7, length: 721 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_a, version: 1.0.0, hash: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d, length: 775 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_b, version: 1.0.0, hash: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d, length: 775 @@ -44,7 +45,7 @@ INFO added artifact, name: fake-switch-sp, kind: switch_sp, version: 1.0.0, hash INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_a, version: 1.0.0, hash: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342, length: 774 INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_b, version: 1.0.0, hash: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342, length: 774 INFO added artifact, name: fake-switch-rot-bootloader, kind: switch_rot_bootloader, version: 1.0.0, hash: 70836d170abd5621f95bb4225987b27b3d3dd6168e73cd60e44309bdfeb94e98, length: 804 -INFO added artifact, name: installinator_document, kind: installinator_document, version: 1.0.0, hash: c6ae866031d1183094c92cde9d9d1fd5f18356abc81a842ce31471b473fd5582, length: 367 +INFO added artifact, name: installinator_document, kind: installinator_document, version: 1.0.0, hash: 8df658e79a02d2d45a652f257ab01f5afe758290ab8fafcfb86f5433aa57d5d7, length: 526 set target release based on repo-1.0.0.zip @@ -747,6 +748,7 @@ INFO added artifact, name: internal-dns, kind: zone, version: 1.0.0, hash: ffbf1 INFO added artifact, name: ntp, kind: zone, version: 1.0.0, hash: 67593d686ed04a1709f93972b71f4ebc148a9362120f65d239943e814a9a7439, length: 1681 INFO added artifact, name: nexus, kind: zone, version: 1.0.0, hash: 0e32b4a3e5d3668bb1d6a16fb06b74dc60b973fa479dcee0aae3adbb52bf1388, length: 1682 INFO added artifact, name: oximeter, kind: zone, version: 1.0.0, hash: 048d8fe8cdef5b175aad714d0f148aa80ce36c9114ac15ce9d02ed3d37877a77, length: 1682 +INFO added artifact, name: fake-corpus, kind: measurement_corpus, version: 1.0.0, hash: 8a0e23157bae655fceec7376926c9758efee6511c7b7ff8355bbb49545a2257f, length: 1048576 INFO added artifact, name: fake-psc-sp, kind: psc_sp, version: 1.0.0, hash: 89245fe2ac7e6a2ac8dfa4e7d6891a6e6df95e4141395c07c64026778f6d76d7, length: 721 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_a, version: 1.0.0, hash: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d, length: 775 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_b, version: 1.0.0, hash: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d, length: 775 @@ -755,7 +757,7 @@ INFO added artifact, name: fake-switch-sp, kind: switch_sp, version: 1.0.0, hash INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_a, version: 1.0.0, hash: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342, length: 774 INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_b, version: 1.0.0, hash: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342, length: 774 INFO added artifact, name: fake-switch-rot-bootloader, kind: switch_rot_bootloader, version: 1.0.0, hash: 70836d170abd5621f95bb4225987b27b3d3dd6168e73cd60e44309bdfeb94e98, length: 804 -INFO added artifact, name: installinator_document, kind: installinator_document, version: 1.0.0, hash: c6ae866031d1183094c92cde9d9d1fd5f18356abc81a842ce31471b473fd5582, length: 367 +INFO added artifact, name: installinator_document, kind: installinator_document, version: 1.0.0, hash: 8df658e79a02d2d45a652f257ab01f5afe758290ab8fafcfb86f5433aa57d5d7, length: 526 set target release based on repo-1.0.0.zip @@ -856,6 +858,7 @@ INFO added artifact, name: internal-dns, kind: zone, version: 2.0.0, hash: de306 INFO added artifact, name: ntp, kind: zone, version: 2.0.0, hash: d76e26198daed69cdae04490d7477f8c842e0dbe37d463eac0d0a8d3fb803095, length: 1682 INFO added artifact, name: nexus, kind: zone, version: 2.0.0, hash: e9b7035f41848a987a798c15ac424cc91dd662b1af0920d58d8aa1ebad7467b6, length: 1683 INFO added artifact, name: oximeter, kind: zone, version: 2.0.0, hash: 9f4bc56a15d5fd943fdac94309994b8fd73aa2be1ec61faf44bfcf2356c9dc23, length: 1683 +INFO added artifact, name: fake-corpus, kind: measurement_corpus, version: 2.0.0, hash: a1a34c0ca4776c27d67a2a50b231acc96ccbc2645f5e8dd8c2bc27f0eab49855, length: 1048576 INFO added artifact, name: fake-psc-sp, kind: psc_sp, version: 2.0.0, hash: fe18e9b745f899f71dc9a718311d97c33f79eb579de09990b0cd2032574d9430, length: 729 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_a, version: 2.0.0, hash: be3fa620485936ebd70160b79d74f8f5709d9388c1add9b7e0fa7d283943e6a8, length: 776 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_b, version: 2.0.0, hash: be3fa620485936ebd70160b79d74f8f5709d9388c1add9b7e0fa7d283943e6a8, length: 776 @@ -864,7 +867,7 @@ INFO added artifact, name: fake-switch-sp, kind: switch_sp, version: 2.0.0, hash INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_a, version: 2.0.0, hash: ad32d98232043a39d076b5b90b506fad406767e0ce1298507e1733bc4e576740, length: 791 INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_b, version: 2.0.0, hash: ad32d98232043a39d076b5b90b506fad406767e0ce1298507e1733bc4e576740, length: 791 INFO added artifact, name: fake-switch-rot-bootloader, kind: switch_rot_bootloader, version: non-semver-2, hash: ceae102fa428d81aa6c5d9e1c742fb9ca1091ce5b2797ed0bb14615cf678d342, length: 811 -INFO added artifact, name: installinator_document, kind: installinator_document, version: 2.0.0, hash: 065b2b7cde09474c9a1bcf98a8f9c93129f617e074404c6aa76164f440a5627f, length: 367 +INFO added artifact, name: installinator_document, kind: installinator_document, version: 2.0.0, hash: 807b3413bb761e86b13aad178d618497893dbb720f069cea86f8fed735d028c8, length: 526 sled d81c6a84-79b8-4958-ae41-ea46c9b19763: install dataset updated: from repo at repo-2.0.0.zip (system version 2.0.0) > sled-set serial2 mupdate-override 1c0ce176-6dc8-4a90-adea-d4a8000751da @@ -1384,6 +1387,7 @@ INFO added artifact, name: internal-dns, kind: zone, version: 2.0.0, hash: de306 INFO added artifact, name: ntp, kind: zone, version: 2.0.0, hash: d76e26198daed69cdae04490d7477f8c842e0dbe37d463eac0d0a8d3fb803095, length: 1682 INFO added artifact, name: nexus, kind: zone, version: 2.0.0, hash: e9b7035f41848a987a798c15ac424cc91dd662b1af0920d58d8aa1ebad7467b6, length: 1683 INFO added artifact, name: oximeter, kind: zone, version: 2.0.0, hash: 9f4bc56a15d5fd943fdac94309994b8fd73aa2be1ec61faf44bfcf2356c9dc23, length: 1683 +INFO added artifact, name: fake-corpus, kind: measurement_corpus, version: 2.0.0, hash: a1a34c0ca4776c27d67a2a50b231acc96ccbc2645f5e8dd8c2bc27f0eab49855, length: 1048576 INFO added artifact, name: fake-psc-sp, kind: psc_sp, version: 2.0.0, hash: fe18e9b745f899f71dc9a718311d97c33f79eb579de09990b0cd2032574d9430, length: 729 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_a, version: 2.0.0, hash: be3fa620485936ebd70160b79d74f8f5709d9388c1add9b7e0fa7d283943e6a8, length: 776 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_b, version: 2.0.0, hash: be3fa620485936ebd70160b79d74f8f5709d9388c1add9b7e0fa7d283943e6a8, length: 776 @@ -1392,7 +1396,7 @@ INFO added artifact, name: fake-switch-sp, kind: switch_sp, version: 2.0.0, hash INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_a, version: 2.0.0, hash: ad32d98232043a39d076b5b90b506fad406767e0ce1298507e1733bc4e576740, length: 791 INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_b, version: 2.0.0, hash: ad32d98232043a39d076b5b90b506fad406767e0ce1298507e1733bc4e576740, length: 791 INFO added artifact, name: fake-switch-rot-bootloader, kind: switch_rot_bootloader, version: non-semver-2, hash: ceae102fa428d81aa6c5d9e1c742fb9ca1091ce5b2797ed0bb14615cf678d342, length: 811 -INFO added artifact, name: installinator_document, kind: installinator_document, version: 2.0.0, hash: 065b2b7cde09474c9a1bcf98a8f9c93129f617e074404c6aa76164f440a5627f, length: 367 +INFO added artifact, name: installinator_document, kind: installinator_document, version: 2.0.0, hash: 807b3413bb761e86b13aad178d618497893dbb720f069cea86f8fed735d028c8, length: 526 set target release based on repo-2.0.0.zip > blueprint-plan latest latest diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout index 35ab76aa8c8..a801b0d5bc9 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-noop-image-source-stdout @@ -58,6 +58,7 @@ INFO added artifact, name: internal-dns, kind: zone, version: 1.0.0, hash: ffbf1 INFO added artifact, name: ntp, kind: zone, version: 1.0.0, hash: 67593d686ed04a1709f93972b71f4ebc148a9362120f65d239943e814a9a7439, length: 1681 INFO added artifact, name: nexus, kind: zone, version: 1.0.0, hash: 0e32b4a3e5d3668bb1d6a16fb06b74dc60b973fa479dcee0aae3adbb52bf1388, length: 1682 INFO added artifact, name: oximeter, kind: zone, version: 1.0.0, hash: 048d8fe8cdef5b175aad714d0f148aa80ce36c9114ac15ce9d02ed3d37877a77, length: 1682 +INFO added artifact, name: fake-corpus, kind: measurement_corpus, version: 1.0.0, hash: 8a0e23157bae655fceec7376926c9758efee6511c7b7ff8355bbb49545a2257f, length: 1048576 INFO added artifact, name: fake-psc-sp, kind: psc_sp, version: 1.0.0, hash: 89245fe2ac7e6a2ac8dfa4e7d6891a6e6df95e4141395c07c64026778f6d76d7, length: 721 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_a, version: 1.0.0, hash: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d, length: 775 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_b, version: 1.0.0, hash: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d, length: 775 @@ -66,7 +67,7 @@ INFO added artifact, name: fake-switch-sp, kind: switch_sp, version: 1.0.0, hash INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_a, version: 1.0.0, hash: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342, length: 774 INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_b, version: 1.0.0, hash: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342, length: 774 INFO added artifact, name: fake-switch-rot-bootloader, kind: switch_rot_bootloader, version: 1.0.0, hash: 70836d170abd5621f95bb4225987b27b3d3dd6168e73cd60e44309bdfeb94e98, length: 804 -INFO added artifact, name: installinator_document, kind: installinator_document, version: 1.0.0, hash: c6ae866031d1183094c92cde9d9d1fd5f18356abc81a842ce31471b473fd5582, length: 367 +INFO added artifact, name: installinator_document, kind: installinator_document, version: 1.0.0, hash: 8df658e79a02d2d45a652f257ab01f5afe758290ab8fafcfb86f5433aa57d5d7, length: 526 set target release based on repo-1.0.0.zip @@ -123,6 +124,7 @@ INFO added artifact, name: internal-dns, kind: zone, version: 2.0.0, hash: de306 INFO added artifact, name: ntp, kind: zone, version: 2.0.0, hash: d76e26198daed69cdae04490d7477f8c842e0dbe37d463eac0d0a8d3fb803095, length: 1682 INFO added artifact, name: nexus, kind: zone, version: 2.0.0, hash: e9b7035f41848a987a798c15ac424cc91dd662b1af0920d58d8aa1ebad7467b6, length: 1683 INFO added artifact, name: oximeter, kind: zone, version: 2.0.0, hash: 9f4bc56a15d5fd943fdac94309994b8fd73aa2be1ec61faf44bfcf2356c9dc23, length: 1683 +INFO added artifact, name: fake-corpus, kind: measurement_corpus, version: 2.0.0, hash: a1a34c0ca4776c27d67a2a50b231acc96ccbc2645f5e8dd8c2bc27f0eab49855, length: 1048576 INFO added artifact, name: fake-psc-sp, kind: psc_sp, version: 2.0.0, hash: fe18e9b745f899f71dc9a718311d97c33f79eb579de09990b0cd2032574d9430, length: 729 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_a, version: 2.0.0, hash: be3fa620485936ebd70160b79d74f8f5709d9388c1add9b7e0fa7d283943e6a8, length: 776 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_b, version: 2.0.0, hash: be3fa620485936ebd70160b79d74f8f5709d9388c1add9b7e0fa7d283943e6a8, length: 776 @@ -131,7 +133,7 @@ INFO added artifact, name: fake-switch-sp, kind: switch_sp, version: 2.0.0, hash INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_a, version: 2.0.0, hash: ad32d98232043a39d076b5b90b506fad406767e0ce1298507e1733bc4e576740, length: 791 INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_b, version: 2.0.0, hash: ad32d98232043a39d076b5b90b506fad406767e0ce1298507e1733bc4e576740, length: 791 INFO added artifact, name: fake-switch-rot-bootloader, kind: switch_rot_bootloader, version: non-semver-2, hash: ceae102fa428d81aa6c5d9e1c742fb9ca1091ce5b2797ed0bb14615cf678d342, length: 811 -INFO added artifact, name: installinator_document, kind: installinator_document, version: 2.0.0, hash: 065b2b7cde09474c9a1bcf98a8f9c93129f617e074404c6aa76164f440a5627f, length: 367 +INFO added artifact, name: installinator_document, kind: installinator_document, version: 2.0.0, hash: 807b3413bb761e86b13aad178d618497893dbb720f069cea86f8fed735d028c8, length: 526 sled b82ede02-399c-48c6-a1de-411df4fa49a7: install dataset updated: from repo at repo-2.0.0.zip (system version 2.0.0) diff --git a/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout b/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout index bdfc47b82b1..39b7a2f0b57 100644 --- a/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout +++ b/dev-tools/reconfigurator-cli/tests/output/cmds-target-release-stdout @@ -51,6 +51,7 @@ INFO added artifact, name: internal-dns, kind: zone, version: 1.0.0, hash: ffbf1 INFO added artifact, name: ntp, kind: zone, version: 1.0.0, hash: 67593d686ed04a1709f93972b71f4ebc148a9362120f65d239943e814a9a7439, length: 1681 INFO added artifact, name: nexus, kind: zone, version: 1.0.0, hash: 0e32b4a3e5d3668bb1d6a16fb06b74dc60b973fa479dcee0aae3adbb52bf1388, length: 1682 INFO added artifact, name: oximeter, kind: zone, version: 1.0.0, hash: 048d8fe8cdef5b175aad714d0f148aa80ce36c9114ac15ce9d02ed3d37877a77, length: 1682 +INFO added artifact, name: fake-corpus, kind: measurement_corpus, version: 1.0.0, hash: 8a0e23157bae655fceec7376926c9758efee6511c7b7ff8355bbb49545a2257f, length: 1048576 INFO added artifact, name: fake-psc-sp, kind: psc_sp, version: 1.0.0, hash: 89245fe2ac7e6a2ac8dfa4e7d6891a6e6df95e4141395c07c64026778f6d76d7, length: 721 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_a, version: 1.0.0, hash: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d, length: 775 INFO added artifact, name: fake-psc-rot, kind: psc_rot_image_b, version: 1.0.0, hash: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d, length: 775 @@ -59,7 +60,7 @@ INFO added artifact, name: fake-switch-sp, kind: switch_sp, version: 1.0.0, hash INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_a, version: 1.0.0, hash: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342, length: 774 INFO added artifact, name: fake-switch-rot, kind: switch_rot_image_b, version: 1.0.0, hash: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342, length: 774 INFO added artifact, name: fake-switch-rot-bootloader, kind: switch_rot_bootloader, version: 1.0.0, hash: 70836d170abd5621f95bb4225987b27b3d3dd6168e73cd60e44309bdfeb94e98, length: 804 -INFO added artifact, name: installinator_document, kind: installinator_document, version: 1.0.0, hash: c6ae866031d1183094c92cde9d9d1fd5f18356abc81a842ce31471b473fd5582, length: 367 +INFO added artifact, name: installinator_document, kind: installinator_document, version: 1.0.0, hash: 8df658e79a02d2d45a652f257ab01f5afe758290ab8fafcfb86f5433aa57d5d7, length: 526 set target release based on repo-1.0.0.zip @@ -90,6 +91,7 @@ target release (generation 2): 1.0.0 (system-update-v1.0.0.zip) artifact: 67593d686ed04a1709f93972b71f4ebc148a9362120f65d239943e814a9a7439 zone (ntp version 1.0.0) artifact: 0e32b4a3e5d3668bb1d6a16fb06b74dc60b973fa479dcee0aae3adbb52bf1388 zone (nexus version 1.0.0) artifact: 048d8fe8cdef5b175aad714d0f148aa80ce36c9114ac15ce9d02ed3d37877a77 zone (oximeter version 1.0.0) + artifact: 8a0e23157bae655fceec7376926c9758efee6511c7b7ff8355bbb49545a2257f measurement_corpus (fake-corpus version 1.0.0) artifact: 89245fe2ac7e6a2ac8dfa4e7d6891a6e6df95e4141395c07c64026778f6d76d7 psc_sp (fake-psc-sp version 1.0.0) artifact: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d psc_rot_image_a (fake-psc-rot version 1.0.0) artifact: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d psc_rot_image_b (fake-psc-rot version 1.0.0) @@ -98,7 +100,7 @@ target release (generation 2): 1.0.0 (system-update-v1.0.0.zip) artifact: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342 switch_rot_image_a (fake-switch-rot version 1.0.0) artifact: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342 switch_rot_image_b (fake-switch-rot version 1.0.0) artifact: 70836d170abd5621f95bb4225987b27b3d3dd6168e73cd60e44309bdfeb94e98 switch_rot_bootloader (fake-switch-rot-bootloader version 1.0.0) - artifact: c6ae866031d1183094c92cde9d9d1fd5f18356abc81a842ce31471b473fd5582 installinator_document (installinator_document version 1.0.0) + artifact: 8df658e79a02d2d45a652f257ab01f5afe758290ab8fafcfb86f5433aa57d5d7 installinator_document (installinator_document version 1.0.0) chicken switches: add zones with mupdate override: false @@ -168,6 +170,7 @@ target release (generation 2): 1.0.0 (system-update-v1.0.0.zip) artifact: 67593d686ed04a1709f93972b71f4ebc148a9362120f65d239943e814a9a7439 zone (ntp version 1.0.0) artifact: 0e32b4a3e5d3668bb1d6a16fb06b74dc60b973fa479dcee0aae3adbb52bf1388 zone (nexus version 1.0.0) artifact: 048d8fe8cdef5b175aad714d0f148aa80ce36c9114ac15ce9d02ed3d37877a77 zone (oximeter version 1.0.0) + artifact: 8a0e23157bae655fceec7376926c9758efee6511c7b7ff8355bbb49545a2257f measurement_corpus (fake-corpus version 1.0.0) artifact: 89245fe2ac7e6a2ac8dfa4e7d6891a6e6df95e4141395c07c64026778f6d76d7 psc_sp (fake-psc-sp version 1.0.0) artifact: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d psc_rot_image_a (fake-psc-rot version 1.0.0) artifact: 5d8ea834dd6d42d386f1eb8a2c5f6e99b697c9958bb4ab8edf63e56003e25d8d psc_rot_image_b (fake-psc-rot version 1.0.0) @@ -176,7 +179,7 @@ target release (generation 2): 1.0.0 (system-update-v1.0.0.zip) artifact: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342 switch_rot_image_a (fake-switch-rot version 1.0.0) artifact: 32307d6d75c9707e8499ba4a4d379f99c0358237b6e190ff6a8024b470f62342 switch_rot_image_b (fake-switch-rot version 1.0.0) artifact: 70836d170abd5621f95bb4225987b27b3d3dd6168e73cd60e44309bdfeb94e98 switch_rot_bootloader (fake-switch-rot-bootloader version 1.0.0) - artifact: c6ae866031d1183094c92cde9d9d1fd5f18356abc81a842ce31471b473fd5582 installinator_document (installinator_document version 1.0.0) + artifact: 8df658e79a02d2d45a652f257ab01f5afe758290ab8fafcfb86f5433aa57d5d7 installinator_document (installinator_document version 1.0.0) chicken switches: add zones with mupdate override: false diff --git a/dev-tools/releng/Cargo.toml b/dev-tools/releng/Cargo.toml index b1f19fda813..9f2ff2adfce 100644 --- a/dev-tools/releng/Cargo.toml +++ b/dev-tools/releng/Cargo.toml @@ -17,6 +17,7 @@ hex.workspace = true omicron-pins.workspace = true omicron-workspace-hack.workspace = true omicron-zone-package.workspace = true +rats-corim.workspace = true reqwest.workspace = true semver.workspace = true serde.workspace = true diff --git a/dev-tools/releng/src/hubris.rs b/dev-tools/releng/src/hubris.rs index c44a01dec3b..56a37e728c3 100644 --- a/dev-tools/releng/src/hubris.rs +++ b/dev-tools/releng/src/hubris.rs @@ -38,6 +38,19 @@ pub(crate) async fn fetch_hubris_artifacts( fs::create_dir_all(&output_dir).await?; + // We need to remove our old downloaded corpus to make sure nothing else + // gets added to the repo unexpectedly. This should only really be a + // issue with local builds + if std::fs::exists(&output_dir.join("measurement_corpus")) + .context("failed to check `measurement_corpus`")? + { + std::fs::remove_dir_all(&output_dir.join("measurement_corpus")) + .context("failed to remove `measurement_corpus")?; + } + fs::create_dir_all(&output_dir.join("measurement_corpus")) + .await + .context("Failed to create `measurement_corpus`")?; + // This could be parallelized with FuturesUnordered but in practice this // takes less time than OS builds. @@ -106,6 +119,22 @@ pub(crate) async fn fetch_hubris_artifacts( } } } + if let Some(corpus) = hash_manifest.corpus { + let hash = match corpus { + Source::File(file) => file.hash, + _ => anyhow::bail!( + "Unexpected file type: should be a single file, not an RoT" + ), + }; + let data = + fetch_hash(&logger, base_url, &client, &hash).await?; + fs::write( + output_dir.join("measurement_corpus").join(hash), + data, + ) + .await + .context("failed to write file {hash}")?; + } } } @@ -160,6 +189,9 @@ async fn fetch_hash( struct Manifest { #[serde(rename = "artifact")] artifacts: HashMap>, + // Add a default for backwards compatibility + #[serde(rename = "measurement_corpus")] + corpus: Option, } #[derive(Deserialize)] diff --git a/dev-tools/releng/src/tuf.rs b/dev-tools/releng/src/tuf.rs index 2b568c35dd1..6a69bed8b2a 100644 --- a/dev-tools/releng/src/tuf.rs +++ b/dev-tools/releng/src/tuf.rs @@ -76,6 +76,46 @@ pub(crate) async fn build_tuf_repo( } } + let mut measurement_corpus = vec![]; + + for entry in std::fs::read_dir( + output_dir.join("hubris-staging").join("measurement_corpus"), + ) + .context("failed to read `hubris-staging/measurement_corpus")? + { + let entry = entry?; + + let corim = rats_corim::Corim::from_file(entry.path())?; + + measurement_corpus.push(DeserializedArtifactData { + name: format!("staging-{}", corim.id), + version: ArtifactVersion::new(corim.get_version()?.clone())?, + source: DeserializedArtifactSource::File { + path: Utf8PathBuf::from_path_buf(entry.path()).unwrap(), + }, + }); + } + + for entry in std::fs::read_dir( + output_dir.join("hubris-production").join("measurement_corpus"), + ) + .context("failed to read `hubris-production/measurement_corpus")? + { + let entry = entry?; + let corim = rats_corim::Corim::from_file(entry.path())?; + measurement_corpus.push(DeserializedArtifactData { + name: format!("production-{}", corim.id), + version: ArtifactVersion::new(corim.get_version()?.clone())?, + source: DeserializedArtifactSource::File { + path: Utf8PathBuf::from_path_buf(entry.path()).unwrap(), + }, + }); + } + + manifest + .artifacts + .insert(KnownArtifactKind::MeasurementCorpus, measurement_corpus); + // Add the OS images. manifest.artifacts.insert( KnownArtifactKind::Host, @@ -115,6 +155,7 @@ pub(crate) async fn build_tuf_repo( .join(format!("{}.tar.gz", package)), }); } + manifest.artifacts.insert( KnownArtifactKind::ControlPlane, vec![DeserializedArtifactData { diff --git a/installinator-common/src/progress.rs b/installinator-common/src/progress.rs index 43188b321e4..8c551f49ceb 100644 --- a/installinator-common/src/progress.rs +++ b/installinator-common/src/progress.rs @@ -52,10 +52,13 @@ pub enum InstallinatorComponent { /// The control plane component. ControlPlane, - /// A component that means "both the host and the control plane", used for - /// writes for now. It is possible that this component will go away in the - /// future. - Both, + /// The measurement corpus component + MeasurementCorpus, + + /// A component that means "all possible components (host phase 2, control + /// plane, and measurements)", used for writes for now. It is possible + /// that this component will go away in the future. + All, /// Future variants that might be unknown. #[serde(other, deserialize_with = "deserialize_ignore_any")] @@ -194,6 +197,9 @@ pub enum WriteComponent { /// The control plane component. ControlPlane, + /// The measurement corpus + MeasurementCorpus, + /// Future variants that might be unknown. #[serde(other, deserialize_with = "deserialize_ignore_any")] Unknown, @@ -205,6 +211,7 @@ impl fmt::Display for WriteComponent { Self::HostPhase2 => f.write_str("host phase 2"), Self::ControlPlane => f.write_str("control plane"), Self::Unknown => f.write_str("unknown"), + Self::MeasurementCorpus => f.write_str("measurement corpus"), } } } @@ -254,6 +261,8 @@ pub enum WriteError { #[source] error: Box>, }, + #[error("error creating directory: {error}")] + CreateDirError { error: std::io::Error }, } impl From> for WriteError { @@ -303,6 +312,12 @@ pub enum ControlPlaneZonesStepId { /// Writing the zone manifest. ZoneManifest, + /// Writing the measurement corpus. + Measurement { name: String }, + + /// Ensure the measurement directory exists + CreateMeasurementDir, + /// Syncing writes to disk. Fsync, diff --git a/installinator/src/artifact.rs b/installinator/src/artifact.rs index 405159ebabc..059fa60e504 100644 --- a/installinator/src/artifact.rs +++ b/installinator/src/artifact.rs @@ -111,11 +111,23 @@ pub(crate) enum LookupIdKind { Hashes { host_phase_2: ArtifactHash, control_plane: ArtifactHash }, } +#[derive(Clone, Debug)] +pub(crate) struct MeasurementArtifact { + pub(crate) hash: ArtifactHash, + pub(crate) name: String, +} + +pub(crate) struct MeasurementArtifactHashId { + pub(crate) hash: ArtifactHashId, + pub(crate) name: String, +} + /// The host phase 2 and control plane hashes to download. #[derive(Clone, Debug)] pub(crate) struct ArtifactsToDownload { pub(crate) host_phase_2: ArtifactHash, pub(crate) control_plane: ArtifactHash, + pub(crate) measurement_corpus: Vec, } impl ArtifactsToDownload { @@ -132,6 +144,20 @@ impl ArtifactsToDownload { hash: self.control_plane, } } + + pub(crate) fn measurement_corpus(&self) -> Vec { + self.measurement_corpus + .clone() + .into_iter() + .map(|x| MeasurementArtifactHashId { + name: x.name, + hash: ArtifactHashId { + kind: KnownArtifactKind::MeasurementCorpus.into(), + hash: x.hash, + }, + }) + .collect() + } } #[derive(Debug)] diff --git a/installinator/src/dispatch.rs b/installinator/src/dispatch.rs index b3e1dca7c4b..4e44db7e7d2 100644 --- a/installinator/src/dispatch.rs +++ b/installinator/src/dispatch.rs @@ -24,8 +24,10 @@ use tufaceous_lib::ControlPlaneZoneImages; use update_engine::StepResult; use crate::{ - ArtifactWriter, WriteDestination, - artifact::{ArtifactIdOpts, ArtifactsToDownload, LookupIdKind}, + ArtifactWriter, MeasurementToWrite, WriteDestination, + artifact::{ + ArtifactIdOpts, ArtifactsToDownload, LookupIdKind, MeasurementArtifact, + }, fetch::{FetchArtifactBackend, FetchedArtifact, HttpFetchBackend}, peers::DiscoveryMechanism, reporter::{HttpProgressBackend, ProgressReporter, ReportProgressBackend}, @@ -270,6 +272,7 @@ impl InstallOpts { // host phase 2 and control plane hashes. let mut host_phase_2_hash = None; let mut control_plane_hash = None; + let mut measurement_corpus = vec![]; for artifact in &json.artifacts { match artifact.kind { InstallinatorArtifactKind::HostPhase2 => { @@ -279,6 +282,9 @@ impl InstallOpts { control_plane_hash = Some(artifact.hash); } + InstallinatorArtifactKind::MeasurementCorpus => { + measurement_corpus.push(MeasurementArtifact { name: artifact.name.clone(), hash: artifact.hash }); + }, } } @@ -303,6 +309,8 @@ impl InstallOpts { ); } + // TODO eventually make the measurement corpus required + StepSuccess::new(ArtifactsToDownload { host_phase_2: host_phase_2_hash.expect( "host phase 2 is Some, checked above", @@ -310,6 +318,7 @@ impl InstallOpts { control_plane: control_plane_hash.expect( "control plane is Some, checked above", ), + measurement_corpus, }) .into() }, @@ -320,6 +329,8 @@ impl InstallOpts { StepHandle::ready(ArtifactsToDownload { host_phase_2, control_plane, + // We only support measurement corpus in the installinator document + measurement_corpus: vec![], }) } } @@ -327,6 +338,7 @@ impl InstallOpts { let to_download_2 = to_download.clone(); let to_download_3 = to_download_2.clone(); + let to_download_corpus = to_download_3.clone(); let host_phase_2_artifact = engine .new_step( InstallinatorComponent::HostPhase2, @@ -402,11 +414,76 @@ impl InstallOpts { ) .register(); + struct MidCorpus { + name: String, + artifact: FetchedArtifact, + } + let measurement_corpus = + engine + .new_step( + InstallinatorComponent::MeasurementCorpus, + InstallinatorStepId::Download, + "Downloading all measurements", + async move |cx| { + let to_download = + to_download_corpus.into_value(cx.token()).await; + let all_corpus = to_download.measurement_corpus(); + + let mut all = vec![]; + for c in all_corpus { + cx.with_nested_engine(|engine| { + let result = engine.new_step( + InstallinatorComponent::MeasurementCorpus, + InstallinatorStepId::Download, + format!( + "Downloading single measurement {}", + c.hash.hash + ), + async move |cx2| { + let control_plane_artifact = + fetch_artifact( + &cx2, &c.hash, discovery, log, + ) + .await?; + + // Check that the sha256 of the data we got from wicket + // matches the data we asked for. We do not retry this for + // the same reasons described above when checking the + // downloaded host phase 2 artifact. + check_downloaded_artifact_hash( + "measurement corpus", + control_plane_artifact.artifact.clone(), + c.hash.hash, + ) + .await?; + + let address = + control_plane_artifact.peer.address(); + + StepSuccess::new(MidCorpus { name: c.name, artifact: control_plane_artifact}) + .with_metadata( + InstallinatorCompletionMetadata::Download { + address, + }, + ) + .into() + }, + ).register(); + all.push(result); + Ok(()) + }) + .await?; + } + StepSuccess::new(all).into() + }, + ) + .register(); + let destination = if self.install_on_gimlet { let log = log.clone(); engine .new_step( - InstallinatorComponent::Both, + InstallinatorComponent::All, InstallinatorStepId::Scan, "Scanning hardware to find M.2 disks", async move |cx| scan_hardware_with_retries(&cx, &log).await, @@ -448,9 +525,9 @@ impl InstallOpts { engine .new_step( - InstallinatorComponent::Both, + InstallinatorComponent::All, InstallinatorStepId::Write, - "Writing host and control plane artifacts", + "Writing host, control plane, and measurement artifacts", async move |cx| { let destination = destination.into_value(cx.token()).await; let to_download = @@ -461,6 +538,17 @@ impl InstallOpts { host_phase_2_artifact.into_value(cx.token()).await; let control_plane_zones = control_plane_zones.into_value(cx.token()).await; + let measurement_corpus = + measurement_corpus.into_value(cx.token()).await; + + let mut all_corpus = vec![]; + for c in measurement_corpus { + let result = c.into_value(cx.token()).await; + all_corpus.push(MeasurementToWrite { + artifact: result.artifact.artifact, + name: result.name, + }); + } let mut writer = ArtifactWriter::new( lookup_id.update_id, @@ -468,6 +556,7 @@ impl InstallOpts { &host_phase_2_artifact.artifact, &control_plane_id, &control_plane_zones, + &all_corpus, destination, ); diff --git a/installinator/src/write.rs b/installinator/src/write.rs index 525cd111026..6566d679d1e 100644 --- a/installinator/src/write.rs +++ b/installinator/src/write.rs @@ -60,6 +60,9 @@ struct ArtifactDestination { // Zpool containing `control_plane_dir`, if we're on a real gimlet. control_plane_zpool: Option, + + // Directory in which we save the measurements + measurement_dir: Utf8PathBuf, } impl ArtifactDestination { @@ -69,11 +72,17 @@ impl ArtifactDestination { std::fs::create_dir_all(&control_plane_dir) .with_context(|| format!("error creating directories at {dir}"))?; + // for now we store the measurements within the install data set + let measurement_dir = control_plane_dir.join("measurements"); + std::fs::create_dir_all(&measurement_dir) + .with_context(|| format!("error creating directories at {dir}"))?; + Ok(Self { host_phase_2: dir.join(HOST_PHASE_2_FILE_NAME), clean_control_plane_dir: false, control_plane_dir, control_plane_zpool: None, + measurement_dir, }) } } @@ -141,6 +150,9 @@ impl WriteDestination { sled_storage::dataset::INSTALL_DATASET, ); + let measurement_dir = + control_plane_dir.join("measurements"); + match drives.entry(slot) { Entry::Vacant(entry) => { entry.insert(ArtifactDestination { @@ -148,6 +160,7 @@ impl WriteDestination { clean_control_plane_dir: true, control_plane_dir, control_plane_zpool: Some(zpool_name), + measurement_dir, }); } Entry::Occupied(_) => { @@ -214,6 +227,9 @@ impl<'a> ArtifactWriter<'a> { host_phase_2_data: &'a BufList, control_plane_id: &'a ArtifactHashId, control_plane_zones: &'a ControlPlaneZoneImages, + + measurement_corpus: &'a Vec, + destination: WriteDestination, ) -> Self { let drives = destination @@ -239,6 +255,7 @@ impl<'a> ArtifactWriter<'a> { control_plane_zones, mupdate_id, mupdate_override_uuid, + measurement_corpus, }, } } @@ -334,7 +351,8 @@ impl<'a> ArtifactWriter<'a> { *progress = DriveWriteProgress::ControlPlaneFailed; } - WriteComponent::Unknown => { + WriteComponent::Unknown + | WriteComponent::MeasurementCorpus => { unreachable!( "we should never generate an unknown component" ) @@ -546,6 +564,8 @@ struct ArtifactsToWrite<'a> { control_plane_zones: &'a ControlPlaneZoneImages, mupdate_id: MupdateUuid, mupdate_override_uuid: MupdateOverrideUuid, + + measurement_corpus: &'a Vec, } impl ArtifactsToWrite<'_> { @@ -590,9 +610,11 @@ impl ArtifactsToWrite<'_> { slot, clean_output_directory: destinations.clean_control_plane_dir, output_directory: &destinations.control_plane_dir, + measurement_directory: &destinations.measurement_dir, zones: self.control_plane_zones, host_phase_2_id: self.host_phase_2_id, control_plane_id: self.control_plane_id, + measurement_corpus: self.measurement_corpus, mupdate_id: self.mupdate_id, mupdate_override_uuid: self.mupdate_override_uuid, }; @@ -623,13 +645,20 @@ impl ArtifactsToWrite<'_> { } } +pub(crate) struct MeasurementToWrite { + pub(crate) name: String, + pub(crate) artifact: BufList, +} + struct ControlPlaneZoneWriteContext<'a> { slot: M2Slot, clean_output_directory: bool, output_directory: &'a Utf8Path, + measurement_directory: &'a Utf8Path, zones: &'a ControlPlaneZoneImages, host_phase_2_id: &'a ArtifactHashId, control_plane_id: &'a ArtifactHashId, + measurement_corpus: &'a Vec, mupdate_id: MupdateUuid, mupdate_override_uuid: MupdateOverrideUuid, } @@ -777,6 +806,54 @@ impl ControlPlaneZoneWriteContext<'_> { .register(); } + engine + .new_step( + WriteComponent::ControlPlane, + ControlPlaneZonesStepId::CreateMeasurementDir, + "Creating measurement directory".to_string(), + async move |_cx| { + if !std::fs::exists(self.measurement_directory) + .map_err(|error| WriteError::CreateDirError { error })? + { + std::fs::create_dir(self.measurement_directory) + .map_err(|error| WriteError::CreateDirError { + error, + })?; + } + StepSuccess::new(()).into() + }, + ) + .register(); + + // This might make sense to move to a separate step once reconfigurator + // work is complete. For now, just treat this as another step in the + // control plane + for data in self.measurement_corpus { + let name = data.name.clone(); + let out_path = self.measurement_directory.join(&name); + transport = engine + .new_step( + WriteComponent::MeasurementCorpus, + ControlPlaneZonesStepId::Measurement { name: name.clone() }, + format!("Writing measurement {name}"), + async move |cx| { + let transport = transport.into_value(cx.token()).await; + write_artifact_impl( + WriteComponent::MeasurementCorpus, + slot, + data.artifact.clone(), + &out_path, + transport, + &cx, + ) + .await?; + + StepSuccess::new(transport).into() + }, + ) + .register(); + } + // `fsync()` the directory to ensure the directory entries for all the // files we just created are written to disk. let output_directory = self.output_directory.to_path_buf(); @@ -1127,10 +1204,12 @@ mod tests { data1: Vec>, #[strategy(prop::collection::vec(prop::collection::vec(any::(), 0..8192), 0..16))] data2: Vec>, + #[strategy(prop::collection::vec(prop::collection::vec(any::(), 0..8192), 0..16))] + data3: Vec>, #[strategy(WriteOps::strategy())] write_ops: WriteOps, ) { with_test_runtime(async move { - proptest_write_artifact_impl(data1, data2, write_ops) + proptest_write_artifact_impl(data1, data2, data3, write_ops) .await .expect("test failed"); }) @@ -1209,6 +1288,7 @@ mod tests { async fn proptest_write_artifact_impl( data1: Vec>, data2: Vec>, + data3: Vec>, write_ops: WriteOps, ) -> Result<()> { let logctx = test_setup_log("test_write_artifact"); @@ -1224,6 +1304,9 @@ mod tests { let mut artifact_control_plane: BufList = data2.into_iter().map(Bytes::from).collect(); + let artifact_measurement_corpus: BufList = + data3.into_iter().map(Bytes::from).collect(); + let host_id = ArtifactHashId { kind: ArtifactKind::HOST_PHASE_2, hash: { @@ -1265,6 +1348,9 @@ mod tests { // Create a `WriteDestination` that points to our tempdir paths. let mut drives = BTreeMap::new(); + let control_plane_dir = tempdir_path; + + let measurement_dir = control_plane_dir.join("measurements"); // TODO This only tests writing to a single drive; we should expand this // test (or maybe write a different one, given how long this one already // is?) that checks writing to both drives. @@ -1273,7 +1359,8 @@ mod tests { ArtifactDestination { host_phase_2: destination_host.clone(), clean_control_plane_dir: false, - control_plane_dir: tempdir_path.into(), + control_plane_dir: control_plane_dir.into(), + measurement_dir, control_plane_zpool: None, }, ); @@ -1289,12 +1376,17 @@ mod tests { )], }; + let all_corpus = vec![MeasurementToWrite { + artifact: artifact_measurement_corpus, + name: "blah".to_string(), + }]; let mut writer = ArtifactWriter::new( MupdateUuid::new_v4(), &host_id, &artifact_host, &control_plane_id, &control_plane_zone_images, + &all_corpus, destination, ); @@ -1302,7 +1394,7 @@ mod tests { let log = logctx.log.clone(); engine .new_step( - InstallinatorComponent::Both, + InstallinatorComponent::All, InstallinatorStepId::Write, "Writing", async move |cx| { diff --git a/nexus/reconfigurator/planning/src/mgs_updates/rot_bootloader.rs b/nexus/reconfigurator/planning/src/mgs_updates/rot_bootloader.rs index a82484ae6ba..af51d7033cf 100644 --- a/nexus/reconfigurator/planning/src/mgs_updates/rot_bootloader.rs +++ b/nexus/reconfigurator/planning/src/mgs_updates/rot_bootloader.rs @@ -145,6 +145,7 @@ pub fn try_make_update_rot_bootloader( | KnownArtifactKind::Trampoline | KnownArtifactKind::ControlPlane | KnownArtifactKind::Zone + | KnownArtifactKind::MeasurementCorpus | KnownArtifactKind::PscRot | KnownArtifactKind::SwitchRot | KnownArtifactKind::GimletSp diff --git a/nexus/reconfigurator/planning/src/mgs_updates/sp.rs b/nexus/reconfigurator/planning/src/mgs_updates/sp.rs index 94de2ee1b8a..7e1bffb865f 100644 --- a/nexus/reconfigurator/planning/src/mgs_updates/sp.rs +++ b/nexus/reconfigurator/planning/src/mgs_updates/sp.rs @@ -122,6 +122,7 @@ pub fn try_make_update_sp( | KnownArtifactKind::InstallinatorDocument | KnownArtifactKind::ControlPlane | KnownArtifactKind::Zone + | KnownArtifactKind::MeasurementCorpus | KnownArtifactKind::PscRot | KnownArtifactKind::SwitchRot | KnownArtifactKind::GimletRotBootloader diff --git a/openapi/installinator.json b/openapi/installinator.json index 65ec7f40017..b9a33a0646d 100644 --- a/openapi/installinator.json +++ b/openapi/installinator.json @@ -298,10 +298,17 @@ ] }, { - "description": "A component that means \"both the host and the control plane\", used for writes for now. It is possible that this component will go away in the future.", + "description": "The measurement corpus component", "type": "string", "enum": [ - "both" + "measurement_corpus" + ] + }, + { + "description": "A component that means \"all possible components (host phase 2, control plane, and measurements)\", used for writes for now. It is possible that this component will go away in the future.", + "type": "string", + "enum": [ + "all" ] }, { diff --git a/update-common/manifests/fake-non-semver.toml b/update-common/manifests/fake-non-semver.toml index 367e14a207c..75746383935 100644 --- a/update-common/manifests/fake-non-semver.toml +++ b/update-common/manifests/fake-non-semver.toml @@ -94,3 +94,8 @@ source = { kind = "fake", size = "1MiB" } name = "fake-switch-rot-bootloader" version = "non-semver-2" source = { kind = "fake", size = "1MiB" } + +[[artifact.measurement_corpus]] +name = "fake-corpus" +version = "2.0.0" +source = { kind = "fake", size = "1MiB" } diff --git a/update-common/manifests/fake.toml b/update-common/manifests/fake.toml index edf1e3f6b5f..571b7f70036 100644 --- a/update-common/manifests/fake.toml +++ b/update-common/manifests/fake.toml @@ -93,4 +93,7 @@ name = "fake-switch-rot-bootloader" version = "1.0.0" source = { kind = "fake", size = "1MiB" } - +[[artifact.measurement_corpus]] +name = "fake-corpus" +version = "1.0.0" +source = { kind = "fake", size = "1MiB" } diff --git a/update-common/src/artifacts/update_plan.rs b/update-common/src/artifacts/update_plan.rs index 3c539d9782c..62f713e5534 100644 --- a/update-common/src/artifacts/update_plan.rs +++ b/update-common/src/artifacts/update_plan.rs @@ -275,7 +275,7 @@ impl<'a> UpdatePlanBuilder<'a> { ) .await } - KnownArtifactKind::Zone => { + KnownArtifactKind::Zone | KnownArtifactKind::MeasurementCorpus => { // We don't currently support repos with already split-out // zones. self.add_unknown_artifact(artifact_id, artifact_hash, stream) @@ -302,6 +302,7 @@ impl<'a> UpdatePlanBuilder<'a> { | KnownArtifactKind::InstallinatorDocument | KnownArtifactKind::ControlPlane | KnownArtifactKind::Zone + | KnownArtifactKind::MeasurementCorpus | KnownArtifactKind::PscRot | KnownArtifactKind::SwitchRot | KnownArtifactKind::GimletRotBootloader @@ -398,6 +399,7 @@ impl<'a> UpdatePlanBuilder<'a> { | KnownArtifactKind::InstallinatorDocument | KnownArtifactKind::ControlPlane | KnownArtifactKind::Zone + | KnownArtifactKind::MeasurementCorpus | KnownArtifactKind::PscRot | KnownArtifactKind::SwitchRot | KnownArtifactKind::GimletSp @@ -505,6 +507,7 @@ impl<'a> UpdatePlanBuilder<'a> { | KnownArtifactKind::InstallinatorDocument | KnownArtifactKind::ControlPlane | KnownArtifactKind::Zone + | KnownArtifactKind::MeasurementCorpus | KnownArtifactKind::PscSp | KnownArtifactKind::SwitchSp | KnownArtifactKind::GimletRotBootloader @@ -1993,6 +1996,30 @@ mod tests { .unwrap(); } + // The measurement corpus can be random bytes + // If we do further testing we should use a fake CoRIM + let measurement_corpus_data = make_random_bytes(); + let measurement_corpus_hash = + ArtifactHash(Sha256::digest(&measurement_corpus_data).into()); + { + let kind = KnownArtifactKind::MeasurementCorpus; + let id = ArtifactId { + name: format!("{kind:?}"), + version: ARTIFACT_VERSION_0, + kind: kind.into(), + }; + plan_builder + .add_artifact( + id, + measurement_corpus_hash, + futures::stream::iter([Ok(Bytes::from( + measurement_corpus_data, + ))]), + ) + .await + .unwrap(); + } + // For each SP image, we'll insert two artifacts: these should end up in // the update plan's SP image maps keyed by their "board". Normally the // board is read from the archive itself via hubtools; we'll inject a @@ -2179,6 +2206,10 @@ mod tests { hash_ids[0].hash ); } + KnownArtifactKind::MeasurementCorpus => { + assert_eq!(hash_ids.len(), 1); + assert_eq!(measurement_corpus_hash, hash_ids[0].hash); + } // These are special (we import their inner parts) and we'll // check them below. KnownArtifactKind::Host diff --git a/wicketd/src/installinator_progress.rs b/wicketd/src/installinator_progress.rs index 51160140869..588e2a979de 100644 --- a/wicketd/src/installinator_progress.rs +++ b/wicketd/src/installinator_progress.rs @@ -363,7 +363,7 @@ mod tests { last_step: StepInfoWithMetadata { info: StepInfo { id: InstallinatorStepId::Write, - component: InstallinatorComponent::Both, + component: InstallinatorComponent::All, description: "Fake step".into(), index: 0, component_index: 0, diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index 2d974fcc6cb..c8375e01e5e 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -48,6 +48,7 @@ ecdsa = { version = "0.16.9", features = ["pem", "signing", "std", "verifying"] ed25519-dalek = { version = "2.1.1", features = ["digest", "pkcs8", "rand_core"] } either = { version = "1.15.0", features = ["use_std"] } elliptic-curve = { version = "0.13.8", features = ["ecdh", "hazmat", "pem", "std"] } +env_logger = { version = "0.11.5", default-features = false, features = ["auto-color"] } ff = { version = "0.13.0", default-features = false, features = ["alloc"] } flate2 = { version = "1.1.2", features = ["zlib-rs"] } foldhash = { version = "0.1.5" } @@ -73,7 +74,7 @@ indexmap = { version = "2.10.0", features = ["serde"] } inout = { version = "0.1.3", default-features = false, features = ["std"] } ipnet = { version = "2.11.0", features = ["serde"] } ipnetwork = { version = "0.21.1", features = ["schemars", "serde"] } -itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13.0" } +itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } lalrpop-util = { version = "0.19.12" } lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] } libc = { version = "0.2.174", features = ["extra_traits"] } @@ -117,6 +118,7 @@ scopeguard = { version = "1.2.0" } semver = { version = "1.0.26", features = ["serde"] } serde = { version = "1.0.219", features = ["alloc", "derive", "rc"] } serde_json = { version = "1.0.142", features = ["raw_value", "unbounded_depth"] } +serde_with = { version = "3.14.0" } sha1 = { version = "0.10.6", features = ["oid"] } sha2 = { version = "0.10.9", features = ["oid"] } similar = { version = "2.7.0", features = ["bytes", "inline", "unicode"] } @@ -185,6 +187,7 @@ ecdsa = { version = "0.16.9", features = ["pem", "signing", "std", "verifying"] ed25519-dalek = { version = "2.1.1", features = ["digest", "pkcs8", "rand_core"] } either = { version = "1.15.0", features = ["use_std"] } elliptic-curve = { version = "0.13.8", features = ["ecdh", "hazmat", "pem", "std"] } +env_logger = { version = "0.11.5", default-features = false, features = ["auto-color"] } ff = { version = "0.13.0", default-features = false, features = ["alloc"] } flate2 = { version = "1.1.2", features = ["zlib-rs"] } foldhash = { version = "0.1.5" } @@ -210,7 +213,7 @@ indexmap = { version = "2.10.0", features = ["serde"] } inout = { version = "0.1.3", default-features = false, features = ["std"] } ipnet = { version = "2.11.0", features = ["serde"] } ipnetwork = { version = "0.21.1", features = ["schemars", "serde"] } -itertools-594e8ee84c453af0 = { package = "itertools", version = "0.13.0" } +itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } lalrpop-util = { version = "0.19.12" } lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] } libc = { version = "0.2.174", features = ["extra_traits"] } @@ -254,6 +257,7 @@ scopeguard = { version = "1.2.0" } semver = { version = "1.0.26", features = ["serde"] } serde = { version = "1.0.219", features = ["alloc", "derive", "rc"] } serde_json = { version = "1.0.142", features = ["raw_value", "unbounded_depth"] } +serde_with = { version = "3.14.0" } sha1 = { version = "0.10.6", features = ["oid"] } sha2 = { version = "0.10.9", features = ["oid"] } similar = { version = "2.7.0", features = ["bytes", "inline", "unicode"] } @@ -363,7 +367,6 @@ dof = { version = "0.3.0", default-features = false, features = ["des"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } hyper-rustls = { version = "0.27.7", features = ["http2", "ring", "webpki-tokio"] } hyper-util = { version = "0.1.16", features = ["full"] } -itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } itertools-93f6ce9d446188ac = { package = "itertools", version = "0.10.5" } mio = { version = "1.0.2", features = ["net", "os-ext"] } rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38.37", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } @@ -379,7 +382,6 @@ dof = { version = "0.3.0", default-features = false, features = ["des"] } getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3.1", default-features = false, features = ["std"] } hyper-rustls = { version = "0.27.7", features = ["http2", "ring", "webpki-tokio"] } hyper-util = { version = "0.1.16", features = ["full"] } -itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } itertools-93f6ce9d446188ac = { package = "itertools", version = "0.10.5" } mio = { version = "1.0.2", features = ["net", "os-ext"] } rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38.37", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] }