diff --git a/.cargo/config.toml b/.cargo/config.toml index 4be537e5e..274ead2b4 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -6,4 +6,6 @@ xtask = "run --package xtask --" # # Once https://github.com/rust-lang/cargo/issues/12115 makes it to our # toolchain, we'll be able to put this in the `Cargo.toml` manifest instead. -rustflags = ["-Wclippy::unused-async"] +# +# Also enable the `tokio-unstable` config for `tokio-dtrace` probes. +rustflags = ["-Wclippy::unused-async", "--cfg", "tokio_unstable"] diff --git a/.github/buildomat/jobs/build-release.sh b/.github/buildomat/jobs/build-release.sh index 887ad25d4..a99d2fafb 100644 --- a/.github/buildomat/jobs/build-release.sh +++ b/.github/buildomat/jobs/build-release.sh @@ -67,6 +67,9 @@ pfexec coreadm -i /tmp/core.%f.%p \ -e log \ -e proc-setid \ -e global-setid + +banner prerequisites +ptime -m ./tools/install_builder_prerequisites.sh -y banner rbuild ptime -m cargo build --verbose --release --all-features diff --git a/.github/buildomat/jobs/build.sh b/.github/buildomat/jobs/build.sh index 56638309a..a1724334f 100644 --- a/.github/buildomat/jobs/build.sh +++ b/.github/buildomat/jobs/build.sh @@ -27,6 +27,9 @@ pfexec coreadm -i /tmp/core.%f.%p \ -e proc-setid \ -e global-setid +banner prerequisites +ptime -m ./tools/install_builder_prerequisites.sh -y + banner build ptime -m cargo build --verbose --all-features diff --git a/Cargo.lock b/Cargo.lock index b42ff7fad..cb56c92f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,15 +98,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android_system_properties" @@ -174,7 +168,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "api_identity" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "omicron-workspace-hack", "proc-macro2", @@ -293,6 +287,30 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "aws-lc-rs" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +dependencies = [ + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "backoff" version = "0.4.0" @@ -340,10 +358,20 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bcs" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b6598a2f5d564fb7855dc6b06fd1c38cff5a72bd8b863a4d021938497b440a" +dependencies = [ + "serde", + "thiserror 1.0.69", +] + [[package]] name = "bhyve_api" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis?rev=6b5f2af796a3ea57405721407ab70520a93ec73f#6b5f2af796a3ea57405721407ab70520a93ec73f" +source = "git+https://github.com/oxidecomputer/propolis?rev=827e6615bfebfd94d41504dcd1517a0f22e3166a#827e6615bfebfd94d41504dcd1517a0f22e3166a" dependencies = [ "bhyve_api_sys", "libc", @@ -353,7 +381,7 @@ dependencies = [ [[package]] name = "bhyve_api_sys" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/propolis?rev=6b5f2af796a3ea57405721407ab70520a93ec73f#6b5f2af796a3ea57405721407ab70520a93ec73f" +source = "git+https://github.com/oxidecomputer/propolis?rev=827e6615bfebfd94d41504dcd1517a0f22e3166a#827e6615bfebfd94d41504dcd1517a0f22e3166a" dependencies = [ "libc", "strum 0.26.3", @@ -368,6 +396,29 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.9.4", + "cexpr", + "clang-sys", + "itertools 0.10.5", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.106", + "which 4.4.2", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -391,9 +442,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" dependencies = [ "serde", ] @@ -460,7 +511,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0" dependencies = [ "once_cell", - "proc-macro-crate 2.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.106", @@ -474,7 +525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata", + "regex-automata 0.4.11", "serde", ] @@ -517,6 +568,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bytecount" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" + [[package]] name = "byteorder" version = "1.5.0" @@ -543,9 +600,9 @@ dependencies = [ [[package]] name = "camino-tempfile" -version = "1.1.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb905055fa81e4d427f919b2cd0d76a998267de7d225ea767a1894743a5263c2" +checksum = "64308c4c82a5c38679945ddf88738dc1483dcc563bbb5780755ae9f8497d2b20" dependencies = [ "camino", "tempfile", @@ -589,12 +646,23 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" dependencies = [ + "find-msvc-tools", "jobserver", "libc", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", ] [[package]] @@ -617,17 +685,27 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.0", +] + +[[package]] +name = "chrono-tz" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" +dependencies = [ + "chrono", + "phf 0.12.1", + "serde", ] [[package]] @@ -640,6 +718,17 @@ dependencies = [ "inout", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.40" @@ -690,14 +779,14 @@ dependencies = [ "nix", "terminfo", "thiserror 2.0.16", - "which", + "which 8.0.0", "windows-sys 0.59.0", ] [[package]] name = "clickhouse-admin-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "atomicwrites", @@ -716,6 +805,22 @@ dependencies = [ "slog", ] +[[package]] +name = "clickward" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/clickward?rev=e3d9a1c35cf3cd04f9cb2e997b0ad88324d30737#e3d9a1c35cf3cd04f9cb2e997b0ad88324d30737" +dependencies = [ + "anyhow", + "camino", + "clap", + "derive_more", + "schemars", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -725,6 +830,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "cmon" version = "0.1.0" @@ -736,8 +850,8 @@ dependencies = [ "crucible-protocol", "crucible-workspace-hack", "serde_json", - "strum 0.27.1", - "strum_macros 0.27.1", + "strum 0.27.2", + "strum_macros 0.27.2", "tokio", ] @@ -747,6 +861,20 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" +[[package]] +name = "cockroach-admin-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" +dependencies = [ + "chrono", + "csv", + "omicron-common", + "omicron-workspace-hack", + "schemars", + "serde", + "thiserror 2.0.16", +] + [[package]] name = "colorchoice" version = "1.0.0" @@ -755,12 +883,11 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -776,6 +903,26 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "const_format" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "constant_time_eq" version = "0.3.0" @@ -810,9 +957,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" @@ -832,6 +979,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -877,7 +1030,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "crossterm_winapi", "mio", "parking_lot", @@ -945,7 +1098,7 @@ dependencies = [ "slog-async", "slog-dtrace", "slog-term", - "strum 0.27.1", + "strum 0.27.2", "tempfile", "test-strategy", "tokio", @@ -1357,11 +1510,11 @@ dependencies = [ "bytes", "crucible-common", "crucible-workspace-hack", - "num_enum 0.7.4", + "num_enum", "schemars", "serde", - "strum 0.27.1", - "strum_macros 0.27.1", + "strum 0.27.2", + "strum_macros 0.27.2", "tokio", "tokio-util", "uuid", @@ -1381,27 +1534,31 @@ dependencies = [ [[package]] name = "crucible-smf" version = "0.0.0" -source = "git+https://github.com/oxidecomputer/crucible?rev=81a3528adacdbde18fcbf3938247fef17233db11#81a3528adacdbde18fcbf3938247fef17233db11" +source = "git+https://github.com/oxidecomputer/crucible?rev=65ca41e821ef53ec9c28909357f23e3348169e4f#65ca41e821ef53ec9c28909357f23e3348169e4f" dependencies = [ "crucible-workspace-hack", "libc", "num-derive", "num-traits", - "thiserror 1.0.69", + "thiserror 2.0.16", ] [[package]] name = "crucible-workspace-hack" version = "0.1.0" dependencies = [ + "aho-corasick", "arrayvec", - "bitflags 2.6.0", + "aws-lc-rs", + "aws-lc-sys", + "bitflags 2.9.4", "bstr", "bytes", "cc", "chrono", "clap", "clap_builder", + "crossbeam-epoch", "crossbeam-utils", "crypto-common", "digest", @@ -1420,27 +1577,34 @@ dependencies = [ "hyper", "hyper-rustls", "hyper-util", - "indexmap 2.11.4", + "indexmap", "libc", + "linux-raw-sys 0.4.14", "log", "memchr", "mio", "nix", + "nom", "num-integer", "num-iter", "num-traits", "once_cell", "openapiv3", "percent-encoding", - "phf_shared", + "phf_shared 0.11.2", + "portable-atomic", "rand 0.8.5", "rand_chacha 0.9.0", "rand_core 0.9.3", - "regex-automata", - "regex-syntax", + "regex", + "regex-automata 0.4.11", + "regex-syntax 0.8.5", "reqwest", + "ring", "rustix 0.38.37", + "rustls 0.23.13", "rustls-pki-types", + "rustls-webpki 0.102.8", "schemars", "scopeguard", "semver 1.0.27", @@ -1457,9 +1621,9 @@ dependencies = [ "tokio", "tokio-util", "toml_datetime 0.6.11", - "toml_edit 0.19.15", "tracing", "tracing-core", + "url", "usdt", "usdt-impl", "uuid", @@ -1583,9 +1747,9 @@ dependencies = [ [[package]] name = "daft" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca607475e0cd38d41f8d1a5bd8985e7cdc1a205a69942211a475b02e48e406e0" +checksum = "b6a26f1f0a7934549bf8d8448d9da072c31f14e1e407b6cbacfdc07b3777988e" dependencies = [ "daft-derive", "newtype-uuid", @@ -1596,9 +1760,9 @@ dependencies = [ [[package]] name = "daft-derive" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78e2436bc785be168ec3641025f713acc89b541ab41c318d7a1cfb4a4c2c50e" +checksum = "27c6a4a4003df965e441d13b2a7044efa44334b567c984701f8a2773f815c5e2" dependencies = [ "proc-macro2", "quote", @@ -1611,8 +1775,18 @@ version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", ] [[package]] @@ -1629,13 +1803,38 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.106", +] + [[package]] name = "darling_macro" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core", + "darling_core 0.20.11", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", "quote", "syn 2.0.106", ] @@ -1691,14 +1890,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", - "serde", +] + +[[package]] +name = "derive-ex" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bba95f299f6b9cd47f68a847eca2ae9060a2713af532dc35c342065544845407" +dependencies = [ + "proc-macro2", + "quote", + "structmeta", + "syn 2.0.106", ] [[package]] name = "derive-where" -version = "1.2.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25" +checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2", "quote", @@ -1720,7 +1930,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling", + "darling 0.20.11", "proc-macro2", "quote", "syn 2.0.106", @@ -1738,9 +1948,9 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.19" +version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "convert_case", "proc-macro2", @@ -1774,14 +1984,13 @@ dependencies = [ [[package]] name = "dlpi" version = "0.2.0" -source = "git+https://github.com/oxidecomputer/dlpi-sys#1d587ea98cf2d36f1b1624b0b960559c76d475d2" +source = "git+https://github.com/oxidecomputer/dlpi-sys#555fa6e1315a64f40c72716e4d168697c03795c6" dependencies = [ "libc", "libdlpi-sys", - "num_enum 0.5.11", - "pretty-hex 0.2.1", - "thiserror 1.0.69", - "tokio", + "num_enum", + "pretty-hex", + "thiserror 2.0.16", ] [[package]] @@ -1791,7 +2000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "558e5396321b677a59d2c43b3cc3bc44683109c63ac49275f3bbbf41c0ecd002" dependencies = [ "goblin", - "pretty-hex 0.4.1", + "pretty-hex", "serde", "serde_json", "thiserror 1.0.69", @@ -1805,7 +2014,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43eb40edecda6106744f5e4f3d4dc78b3adf19d3cfb2d81cc4faa007da91e527" dependencies = [ "anyhow", - "indexmap 2.11.4", + "indexmap", "openapiv3", "regex", "serde", @@ -1833,7 +2042,7 @@ dependencies = [ "http-body-util", "hyper", "hyper-util", - "indexmap 2.11.4", + "indexmap", "multer", "openapiv3", "paste", @@ -1975,6 +2184,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.16" @@ -2034,9 +2249,23 @@ checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "ereport-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" +dependencies = [ + "dropshot", + "omicron-uuid-kinds", + "omicron-workspace-hack", + "schemars", + "serde", + "serde_json", + "thiserror 2.0.16", +] [[package]] name = "errno" @@ -2050,10 +2279,11 @@ dependencies = [ [[package]] name = "expectorate" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de6f19b25bdfa2747ae775f37cd109c31f1272d4e4c83095be0727840aa1d75f" +checksum = "2cfe29c067b3dd398703f5cb05420a21c21079edfbcfa96c3ff2d9bde55cc8b3" dependencies = [ + "atomicwrites", "console", "newline-converter", "similar", @@ -2112,6 +2342,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -2152,6 +2388,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -2212,6 +2454,12 @@ dependencies = [ "autocfg 1.1.0", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -2316,36 +2564,76 @@ dependencies = [ [[package]] name = "gateway-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "base64 0.22.1", "chrono", + "daft", + "ereport-types", "gateway-messages", + "gateway-types", + "omicron-uuid-kinds", "omicron-workspace-hack", - "progenitor 0.9.1", - "rand 0.8.5", + "progenitor 0.10.0", + "rand 0.9.2", "reqwest", "schemars", "serde", "serde_json", "slog", + "thiserror 2.0.16", + "tokio", "uuid", ] [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=9bbac475dcaac88286c07a20b6bd3e94fc81d7f0#9bbac475dcaac88286c07a20b6bd3e94fc81d7f0" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=6bd2660d651332f38949cdfd3d23d751ca54b120#6bd2660d651332f38949cdfd3d23d751ca54b120" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "hubpack", "serde", "serde-big-array", "serde_repr", "static_assertions", - "strum_macros 0.25.3", + "strum 0.27.2", + "strum_macros 0.27.2", + "uuid", + "zerocopy 0.8.27", +] + +[[package]] +name = "gateway-types" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" +dependencies = [ + "daft", + "dropshot", + "gateway-messages", + "hex", + "omicron-common", + "omicron-uuid-kinds", + "omicron-workspace-hack", + "schemars", + "serde", + "thiserror 2.0.16", + "tufaceous-artifact", "uuid", - "zerocopy 0.6.6", +] + +[[package]] +name = "generator" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows 0.60.0", ] [[package]] @@ -2358,6 +2646,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "gethostname" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc3655aa6818d65bc620d6911f05aa7b6aeb596291e1e9f79e52df85583d1e30" +dependencies = [ + "rustix 0.38.37", + "windows-targets 0.52.6", +] + [[package]] name = "getrandom" version = "0.2.11" @@ -2393,7 +2691,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "libc", "libgit2-sys", "log", @@ -2402,13 +2700,26 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] -name = "goblin" -version = "0.8.0" +name = "globset" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.11", + "regex-syntax 0.8.5", +] + +[[package]] +name = "goblin" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887" dependencies = [ @@ -2429,7 +2740,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.11.4", + "indexmap", "slab", "tokio", "tokio-util", @@ -2462,7 +2773,16 @@ checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.4", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "allocator-api2", ] [[package]] @@ -2544,6 +2864,31 @@ dependencies = [ "url", ] +[[package]] +name = "hickory-proto" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 1.1.0", + "ipnet", + "once_cell", + "rand 0.9.2", + "ring", + "thiserror 2.0.16", + "tinyvec", + "tokio", + "tracing", + "url", +] + [[package]] name = "hickory-resolver" version = "0.24.4" @@ -2552,7 +2897,7 @@ checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" dependencies = [ "cfg-if", "futures-util", - "hickory-proto", + "hickory-proto 0.24.1", "ipconfig", "lru-cache", "once_cell", @@ -2565,12 +2910,42 @@ dependencies = [ "tracing", ] +[[package]] +name = "hickory-resolver" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto 0.25.2", + "ipconfig", + "moka", + "once_cell", + "parking_lot", + "rand 0.9.2", + "resolv-conf", + "smallvec", + "thiserror 2.0.16", + "tokio", + "tracing", +] + [[package]] name = "highway" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9040319a6910b901d5d49cbada4a99db52836a1b63228a05f7e2b7f8feef89b1" +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "hostname" version = "0.3.1" @@ -2590,7 +2965,7 @@ checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" dependencies = [ "cfg-if", "libc", - "windows", + "windows 0.52.0", ] [[package]] @@ -2740,7 +3115,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.0", "tower-service", - "webpki-roots", + "webpki-roots 0.26.6", ] [[package]] @@ -2801,21 +3176,22 @@ dependencies = [ "tokio", "tower-service", "tracing", - "windows-registry 0.5.0", + "windows-registry", ] [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core 0.51.1", + "windows-core 0.62.1", ] [[package]] @@ -2916,7 +3292,7 @@ dependencies = [ [[package]] name = "id-map" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "daft", "derive-where", @@ -2925,6 +3301,24 @@ dependencies = [ "serde", ] +[[package]] +name = "iddqd" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac5efd33e0c5eb0ac45cbd210541a214dac576896ca97ba08e16e3b1079cdd8" +dependencies = [ + "allocator-api2", + "daft", + "equivalent", + "foldhash 0.2.0", + "hashbrown 0.16.0", + "ref-cast", + "rustc-hash 2.1.1", + "schemars", + "serde_core", + "serde_json", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2965,12 +3359,15 @@ dependencies = [ [[package]] name = "illumos-sys-hdrs" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa#cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa" +source = "git+https://github.com/oxidecomputer/opte?rev=795a1e0aeefb7a2c6fe4139779fdf66930d09b80#795a1e0aeefb7a2c6fe4139779fdf66930d09b80" +dependencies = [ + "bitflags 2.9.4", +] [[package]] name = "illumos-utils" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "async-trait", @@ -2979,7 +3376,8 @@ dependencies = [ "camino", "camino-tempfile", "cfg-if", - "crucible-smf 0.0.0 (git+https://github.com/oxidecomputer/crucible?rev=81a3528adacdbde18fcbf3938247fef17233db11)", + "crucible-smf 0.0.0 (git+https://github.com/oxidecomputer/crucible?rev=65ca41e821ef53ec9c28909357f23e3348169e4f)", + "debug-ignore", "dropshot", "futures", "http", @@ -2999,7 +3397,7 @@ dependencies = [ "slog", "slog-error-chain", "smf", - "thiserror 1.0.69", + "thiserror 2.0.16", "tokio", "uuid", "whoami", @@ -3012,17 +3410,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cfe9645a18782869361d9c8732246be7b410ad4e919d3609ebabdac00ba12c3" -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg 1.1.0", - "hashbrown 0.12.3", - "serde", -] - [[package]] name = "indexmap" version = "2.11.4" @@ -3051,24 +3438,26 @@ dependencies = [ [[package]] name = "ingot" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/ingot.git?rev=bff93247fe75ff889121e39d494cc3805fc01906#bff93247fe75ff889121e39d494cc3805fc01906" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a17a93829808685f3b6882763901d7489efc1155ad4ae568499d1b303067ca6" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "ingot-macros", "ingot-types", "macaddr", "serde", - "zerocopy 0.8.23", + "zerocopy 0.8.27", ] [[package]] name = "ingot-macros" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/ingot.git?rev=bff93247fe75ff889121e39d494cc3805fc01906#bff93247fe75ff889121e39d494cc3805fc01906" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4c94e8b5b5e08b71943d585acdb6062daaeb6b19de82ebb377c7c9cbeff44bb" dependencies = [ - "darling", - "itertools 0.13.0", + "darling 0.21.3", + "itertools 0.14.0", "proc-macro2", "quote", "regex", @@ -3077,12 +3466,13 @@ dependencies = [ [[package]] name = "ingot-types" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/ingot.git?rev=bff93247fe75ff889121e39d494cc3805fc01906#bff93247fe75ff889121e39d494cc3805fc01906" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d0d55db2f1de52564cc3781ffd5a7ebb7f2c6e1888841c2fa54231a9498db5f" dependencies = [ "ingot-macros", "macaddr", - "zerocopy 0.8.23", + "zerocopy 0.8.27", ] [[package]] @@ -3112,23 +3502,25 @@ checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" [[package]] name = "internal-dns-resolver" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "futures", - "hickory-resolver", + "hickory-proto 0.25.2", + "hickory-resolver 0.25.2", "internal-dns-types", "omicron-common", + "omicron-uuid-kinds", "omicron-workspace-hack", "qorb", "reqwest", "slog", - "thiserror 1.0.69", + "thiserror 2.0.16", ] [[package]] name = "internal-dns-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "chrono", @@ -3145,7 +3537,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "cfg-if", "libc", ] @@ -3178,6 +3570,16 @@ dependencies = [ "serde", ] +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is-terminal" version = "0.4.12" @@ -3204,6 +3606,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.13.0" @@ -3228,11 +3639,52 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", + "windows-sys 0.59.0", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -3250,7 +3702,7 @@ dependencies = [ [[package]] name = "kstat-macro" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa#cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa" +source = "git+https://github.com/oxidecomputer/opte?rev=795a1e0aeefb7a2c6fe4139779fdf66930d09b80#795a1e0aeefb7a2c6fe4139779fdf66930d09b80" dependencies = [ "quote", "syn 2.0.106", @@ -3262,6 +3714,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.174" @@ -3271,7 +3729,7 @@ checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libdlpi-sys" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/dlpi-sys#1d587ea98cf2d36f1b1624b0b960559c76d475d2" +source = "git+https://github.com/oxidecomputer/dlpi-sys#555fa6e1315a64f40c72716e4d168697c03795c6" [[package]] name = "libgit2-sys" @@ -3285,6 +3743,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link 0.2.0", +] + [[package]] name = "libm" version = "0.2.8" @@ -3294,23 +3762,23 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libnet" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/netadm-sys?branch=main#f4eae3d8070760922da93b9edd56ca4103b4c390" +source = "git+https://github.com/oxidecomputer/netadm-sys?branch=main#0f99281333915a3986164b75e443cb4c1d0b5b8e" dependencies = [ "anyhow", "cfg-if", "colored", "dlpi", "libc", - "num_enum 0.5.11", + "num_enum", "nvpair", "nvpair-sys", "oxnet", - "rand 0.8.5", + "rand 0.9.2", "rusty-doors", - "socket2 0.5.10", - "thiserror 1.0.69", + "socket2 0.6.0", + "thiserror 2.0.16", "tracing", - "winnow 0.6.18", + "winnow 0.7.13", ] [[package]] @@ -3400,6 +3868,19 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + [[package]] name = "lru-cache" version = "0.1.2" @@ -3430,6 +3911,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "measure-iops" version = "0.0.1" @@ -3483,12 +3973,12 @@ dependencies = [ [[package]] name = "mg-admin-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/maghemite?rev=caafd889f31faacfaa51e02902990c220c20ef60#caafd889f31faacfaa51e02902990c220c20ef60" +source = "git+https://github.com/oxidecomputer/maghemite?rev=08f2a34d487658e87545ffbba3add632a82baf0d#08f2a34d487658e87545ffbba3add632a82baf0d" dependencies = [ "anyhow", "chrono", "percent-encoding", - "progenitor 0.8.0", + "progenitor 0.11.1", "reqwest", "schemars", "serde", @@ -3540,6 +4030,25 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "moka" +version = "0.12.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "loom", + "parking_lot", + "portable-atomic", + "rustc_version 0.4.1", + "smallvec", + "tagptr", + "thiserror 1.0.69", + "uuid", +] + [[package]] name = "multer" version = "3.1.0" @@ -3595,15 +4104,30 @@ dependencies = [ [[package]] name = "newtype-uuid" -version = "1.2.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3224f0e8be7c2a1ebc77ef9c3eecb90f55c6594399ee825de964526b3c9056" +checksum = "74d1216f62e63be5fb25a9ecd1e2b37b1556a9b8c02f4831770f5d01df85c226" dependencies = [ "schemars", "serde", + "serde_json", "uuid", ] +[[package]] +name = "newtype-uuid-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2e8f1451c201475b7c17007b26509ef981a04d6655edf1e52ed51da82968ae" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "serde", + "serde_tokenstream", + "syn 2.0.106", +] + [[package]] name = "newtype_derive" version = "0.1.6" @@ -3616,10 +4140,11 @@ dependencies = [ [[package]] name = "nexus-client" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "chrono", "futures", + "iddqd", "nexus-sled-agent-shared", "nexus-types", "omicron-common", @@ -3627,7 +4152,7 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "oxnet", - "progenitor 0.9.1", + "progenitor 0.10.0", "regress", "reqwest", "schemars", @@ -3640,10 +4165,15 @@ dependencies = [ [[package]] name = "nexus-sled-agent-shared" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ + "camino", + "chrono", "daft", + "id-map", + "iddqd", "illumos-utils", + "indent_write", "omicron-common", "omicron-passwords", "omicron-uuid-kinds", @@ -3652,15 +4182,16 @@ dependencies = [ "serde", "serde_json", "sled-hardware-types", - "strum 0.26.3", - "thiserror 1.0.69", + "strum 0.27.2", + "thiserror 2.0.16", + "tufaceous-artifact", "uuid", ] [[package]] name = "nexus-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "api_identity", @@ -3669,6 +4200,7 @@ dependencies = [ "chrono", "clap", "clickhouse-admin-types", + "cockroach-admin-types", "cookie", "daft", "derive-where", @@ -3676,12 +4208,16 @@ dependencies = [ "dropshot", "futures", "gateway-client", + "gateway-types", "http", "humantime", "id-map", + "iddqd", "illumos-utils", + "indent_write", "internal-dns-types", "ipnetwork", + "itertools 0.14.0", "newtype-uuid", "newtype_derive", "nexus-sled-agent-shared", @@ -3690,9 +4226,11 @@ dependencies = [ "omicron-uuid-kinds", "omicron-workspace-hack", "openssl", + "oximeter-db", "oxnet", "oxql-types", "parse-display", + "regex", "schemars", "semver 1.0.27", "serde", @@ -3701,9 +4239,18 @@ dependencies = [ "slog", "slog-error-chain", "steno", - "strum 0.26.3", - "thiserror 1.0.69", + "strum 0.27.2", + "swrite", + "tabled", + "test-strategy", + "textwrap", + "thiserror 2.0.16", + "tokio", + "tough", + "tufaceous-artifact", + "unicode-width 0.1.14", "update-engine", + "url", "uuid", ] @@ -3713,7 +4260,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "cfg-if", "cfg_aliases 0.2.1", "libc", @@ -3884,44 +4431,23 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" -dependencies = [ - "num_enum_derive 0.5.11", -] - [[package]] name = "num_enum" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" dependencies = [ - "num_enum_derive 0.7.4", + "num_enum_derive", "rustversion", ] -[[package]] -name = "num_enum_derive" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "num_enum_derive" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ - "proc-macro-crate 2.0.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.106", @@ -3967,13 +4493,24 @@ dependencies = [ ] [[package]] -name = "omicron-common" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +name = "olpc-cjson" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "696183c9b5fe81a7715d074fd632e8bd46f4ccc0231a3ed7fc580a80de5f7083" dependencies = [ - "anyhow", - "api_identity", - "async-trait", + "serde", + "serde_json", + "unicode-normalization", +] + +[[package]] +name = "omicron-common" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" +dependencies = [ + "anyhow", + "api_identity", + "async-trait", "backoff", "camino", "chrono", @@ -3982,6 +4519,8 @@ dependencies = [ "futures", "hex", "http", + "id-map", + "iddqd", "ipnetwork", "macaddr", "mg-admin-client", @@ -3989,8 +4528,9 @@ dependencies = [ "omicron-workspace-hack", "oxnet", "parse-display", - "progenitor-client 0.9.1", - "rand 0.8.5", + "progenitor-client 0.10.0", + "protocol", + "rand 0.9.2", "regress", "reqwest", "schemars", @@ -4001,8 +4541,8 @@ dependencies = [ "serde_with", "slog", "slog-error-chain", - "strum 0.26.3", - "thiserror 1.0.69", + "strum 0.27.2", + "thiserror 2.0.16", "tokio", "tufaceous-artifact", "uuid", @@ -4011,24 +4551,26 @@ dependencies = [ [[package]] name = "omicron-passwords" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "argon2", "omicron-workspace-hack", - "rand 0.8.5", + "rand 0.9.2", "schemars", + "secrecy", "serde", "serde_with", - "thiserror 1.0.69", + "thiserror 2.0.16", ] [[package]] name = "omicron-uuid-kinds" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "daft", "newtype-uuid", + "newtype-uuid-macros", "paste", "schemars", ] @@ -4073,9 +4615,13 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +dependencies = [ + "critical-section", + "portable-atomic", +] [[package]] name = "opaque-debug" @@ -4089,7 +4635,7 @@ version = "0.4.0" source = "git+https://github.com/oxidecomputer/openapi-lint?branch=main#ef442ee4343e97b6d9c217d3e7533962fe7d7236" dependencies = [ "heck 0.4.1", - "indexmap 2.11.4", + "indexmap", "lazy_static", "openapiv3", "regex", @@ -4101,7 +4647,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8d427828b22ae1fff2833a03d8486c2c881367f1c336349f307f321e7f4d05" dependencies = [ - "indexmap 2.11.4", + "indexmap", "serde", "serde_json", ] @@ -4112,7 +4658,7 @@ version = "0.10.59" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "cfg-if", "foreign-types 0.3.2", "libc", @@ -4158,7 +4704,7 @@ checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a" dependencies = [ "futures-core", "futures-sink", - "indexmap 2.11.4", + "indexmap", "js-sys", "once_cell", "pin-project-lite", @@ -4227,26 +4773,26 @@ dependencies = [ [[package]] name = "opte" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa#cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa" +source = "git+https://github.com/oxidecomputer/opte?rev=795a1e0aeefb7a2c6fe4139779fdf66930d09b80#795a1e0aeefb7a2c6fe4139779fdf66930d09b80" dependencies = [ - "bitflags 2.6.0", - "cfg-if", + "bitflags 2.9.4", "dyn-clone", "illumos-sys-hdrs", "ingot", "kstat-macro", "opte-api", "postcard", + "ref-cast", "serde", - "smoltcp", "tabwriter", "version_check", + "zerocopy 0.8.27", ] [[package]] name = "opte-api" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa#cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa" +source = "git+https://github.com/oxidecomputer/opte?rev=795a1e0aeefb7a2c6fe4139779fdf66930d09b80#795a1e0aeefb7a2c6fe4139779fdf66930d09b80" dependencies = [ "illumos-sys-hdrs", "ingot", @@ -4259,7 +4805,7 @@ dependencies = [ [[package]] name = "opte-ioctl" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa#cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa" +source = "git+https://github.com/oxidecomputer/opte?rev=795a1e0aeefb7a2c6fe4139779fdf66930d09b80#795a1e0aeefb7a2c6fe4139779fdf66930d09b80" dependencies = [ "libc", "libnet", @@ -4300,26 +4846,35 @@ version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" +[[package]] +name = "oxide-tokio-rt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84bd87abf37c68d414e4df90a545857542140e07206f75039b8f63b244da87b8" +dependencies = [ + "anyhow", + "tokio", + "tokio-dtrace", +] + [[package]] name = "oxide-vpc" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/opte?rev=cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa#cd9aa6467c5e62c6d97f6aafa2150d6930e3a0fa" +source = "git+https://github.com/oxidecomputer/opte?rev=795a1e0aeefb7a2c6fe4139779fdf66930d09b80#795a1e0aeefb7a2c6fe4139779fdf66930d09b80" dependencies = [ "cfg-if", "illumos-sys-hdrs", "opte", - "poptrie", "serde", - "smoltcp", "tabwriter", "uuid", - "zerocopy 0.8.23", + "zerocopy 0.8.27", ] [[package]] name = "oximeter" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "chrono", @@ -4335,10 +4890,63 @@ dependencies = [ "uuid", ] +[[package]] +name = "oximeter-db" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" +dependencies = [ + "anyhow", + "async-recursion", + "async-trait", + "bcs", + "bytes", + "camino", + "chrono", + "chrono-tz", + "clap", + "clickward", + "const_format", + "debug-ignore", + "dropshot", + "futures", + "gethostname", + "highway", + "iana-time-zone", + "indexmap", + "libc", + "nom", + "num 0.4.3", + "omicron-common", + "omicron-workspace-hack", + "oxide-tokio-rt", + "oximeter", + "oxql-types", + "parse-display", + "qorb", + "quote", + "regex", + "reqwest", + "schemars", + "serde", + "serde_json", + "slog", + "slog-async", + "slog-dtrace", + "slog-error-chain", + "slog-term", + "strum 0.27.2", + "termtree", + "thiserror 2.0.16", + "tokio", + "tokio-util", + "usdt", + "uuid", +] + [[package]] name = "oximeter-macro-impl" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "omicron-workspace-hack", "proc-macro2", @@ -4349,7 +4957,7 @@ dependencies = [ [[package]] name = "oximeter-producer" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "chrono", "dropshot", @@ -4363,7 +4971,7 @@ dependencies = [ "serde", "slog", "slog-dtrace", - "thiserror 1.0.69", + "thiserror 2.0.16", "tokio", "uuid", ] @@ -4371,7 +4979,7 @@ dependencies = [ [[package]] name = "oximeter-schema" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "chrono", @@ -4392,7 +5000,7 @@ dependencies = [ [[package]] name = "oximeter-timeseries-macro" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "omicron-workspace-hack", "oximeter-schema", @@ -4405,7 +5013,7 @@ dependencies = [ [[package]] name = "oximeter-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "bytes", "chrono", @@ -4417,30 +5025,33 @@ dependencies = [ "regex", "schemars", "serde", - "strum 0.26.3", - "thiserror 1.0.69", + "strum 0.27.2", + "thiserror 2.0.16", "uuid", ] [[package]] name = "oxlog" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "camino", "chrono", "clap", + "glob", + "jiff", "omicron-workspace-hack", + "rayon", "sigpipe", "uuid", ] [[package]] name = "oxnet" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95f58698da06f0f57b1ea4a8f1b0ca5741ee17927729d2e87dcfcb682266d21d" +checksum = "8200429754152e6379fbb1dd06eea90156c3b67591f6e31d08e787d010ef0168" dependencies = [ "ipnetwork", "schemars", @@ -4451,7 +5062,7 @@ dependencies = [ [[package]] name = "oxql-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "chrono", @@ -4461,6 +5072,19 @@ dependencies = [ "oximeter-types", "schemars", "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "papergrid" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad43c07024ef767f9160710b3a6773976194758c7919b17e63b863db0bdf7fb" +dependencies = [ + "bytecount", + "fnv", + "unicode-width 0.1.14", ] [[package]] @@ -4494,7 +5118,7 @@ checksum = "287d8d3ebdce117b8539f59411e4ed9ec226e0a4153c7f55495c6070d68e6f72" dependencies = [ "parse-display-derive", "regex", - "regex-syntax", + "regex-syntax 0.8.5", ] [[package]] @@ -4506,7 +5130,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "regex-syntax", + "regex-syntax 0.8.5", "structmeta", "syn 2.0.106", ] @@ -4534,6 +5158,16 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +dependencies = [ + "base64 0.22.1", + "serde", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -4592,19 +5226,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", - "indexmap 2.11.4", + "indexmap", "serde", "serde_derive", ] [[package]] name = "petgraph" -version = "0.7.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset 0.5.7", - "indexmap 2.11.4", + "hashbrown 0.15.2", + "indexmap", + "serde", ] [[package]] @@ -4613,7 +5249,16 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_shared", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_shared 0.12.1", ] [[package]] @@ -4623,7 +5268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" dependencies = [ "phf_generator", - "phf_shared", + "phf_shared 0.11.2", ] [[package]] @@ -4632,7 +5277,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "phf_shared", + "phf_shared 0.11.2", "rand 0.8.5", ] @@ -4642,7 +5287,36 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ - "siphasher", + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +dependencies = [ + "siphasher 1.0.1", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] @@ -4682,15 +5356,19 @@ dependencies = [ ] [[package]] -name = "poptrie" -version = "0.1.0" -source = "git+https://github.com/oxidecomputer/poptrie?branch=multipath#ca52bef3f87ff1a67d81b3c6e601dcb5fdbcc165" +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] -name = "portable-atomic" -version = "1.5.1" +name = "portable-atomic-util" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] [[package]] name = "postcard" @@ -4725,12 +5403,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "pretty-hex" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5c99d529f0d30937f6f4b8a86d988047327bb88d04d2c4afc356de74722131" - [[package]] name = "pretty-hex" version = "0.4.1" @@ -4739,24 +5411,14 @@ checksum = "bbc83ee4a840062f368f9096d80077a9841ec117e17e7f700df81958f1451254" [[package]] name = "prettyplease" -version = "0.2.31" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn 2.0.106", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "2.0.0" @@ -4792,35 +5454,13 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] -[[package]] -name = "progenitor" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293df5b79211fbf0c1ebad6513ba451d267e9c15f5f19ee5d3da775e2dd27331" -dependencies = [ - "progenitor-client 0.8.0", - "progenitor-impl 0.8.0", - "progenitor-macro 0.8.0", -] - -[[package]] -name = "progenitor" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88f54bd2506c3e7b6e45b6ab16500abef551689021264f3be260ef7e295ac327" -dependencies = [ - "progenitor-client 0.9.1", - "progenitor-impl 0.9.1", - "progenitor-macro 0.9.1", -] - [[package]] name = "progenitor" version = "0.10.0" @@ -4833,25 +5473,21 @@ dependencies = [ ] [[package]] -name = "progenitor-client" -version = "0.8.0" +name = "progenitor" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a5db54eac3cae7007a0785854bc3e89fd418cca7dfc2207b99b43979154c1b" +checksum = "135a23fcb9ad36a46ef4be323d006e195ad5121779c9da64ef95cf0600771b77" dependencies = [ - "bytes", - "futures-core", - "percent-encoding", - "reqwest", - "serde", - "serde_json", - "serde_urlencoded", + "progenitor-client 0.11.1", + "progenitor-impl 0.11.1", + "progenitor-macro 0.11.1", ] [[package]] name = "progenitor-client" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdae8df95f0b2a7d6159a9c43b7380016b8d3b0fc1ece46871ecd2e0087cfaf6" +checksum = "296003fd74e64c77aeb2c10eae850eb543211a8557dd3b3de6f4230b5071e44b" dependencies = [ "bytes", "futures-core", @@ -4864,9 +5500,9 @@ dependencies = [ [[package]] name = "progenitor-client" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "296003fd74e64c77aeb2c10eae850eb543211a8557dd3b3de6f4230b5071e44b" +checksum = "920f044db9ec07a3339175729794d3701e11d338dcf8cfd946df838102307780" dependencies = [ "bytes", "futures-core", @@ -4879,35 +5515,13 @@ dependencies = [ [[package]] name = "progenitor-impl" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d85934a440963a69f9f04f48507ff6e7aa2952a5b2d8f96cc37fa3dd5c270f66" -dependencies = [ - "heck 0.5.0", - "http", - "indexmap 2.11.4", - "openapiv3", - "proc-macro2", - "quote", - "regex", - "schemars", - "serde", - "serde_json", - "syn 2.0.106", - "thiserror 1.0.69", - "typify 0.2.0", - "unicode-ident", -] - -[[package]] -name = "progenitor-impl" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37adc80a94c9cae890e82deeeecc9d8f2a5cb153256caaf1bf0f03611e537214" +checksum = "b17e5363daa50bf1cccfade6b0fb970d2278758fd5cfa9ab69f25028e4b1afa3" dependencies = [ "heck 0.5.0", "http", - "indexmap 2.11.4", + "indexmap", "openapiv3", "proc-macro2", "quote", @@ -4917,19 +5531,19 @@ dependencies = [ "serde_json", "syn 2.0.106", "thiserror 2.0.16", - "typify 0.3.0", + "typify", "unicode-ident", ] [[package]] name = "progenitor-impl" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17e5363daa50bf1cccfade6b0fb970d2278758fd5cfa9ab69f25028e4b1afa3" +checksum = "8276d558f1dfd4cc7fc4cceee0a51dab482b5a4be2e69e7eab8c57fbfb1472f4" dependencies = [ "heck 0.5.0", "http", - "indexmap 2.11.4", + "indexmap", "openapiv3", "proc-macro2", "quote", @@ -4939,37 +5553,19 @@ dependencies = [ "serde_json", "syn 2.0.106", "thiserror 2.0.16", - "typify 0.4.1", + "typify", "unicode-ident", ] [[package]] name = "progenitor-macro" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d99a5a259e2d65a4933054aa51717c70b6aba0522695731ac354a522124efc9b" -dependencies = [ - "openapiv3", - "proc-macro2", - "progenitor-impl 0.8.0", - "quote", - "schemars", - "serde", - "serde_json", - "serde_tokenstream", - "serde_yaml", - "syn 2.0.106", -] - -[[package]] -name = "progenitor-macro" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3b2b9f0d5ba58375c5e8e89d5dff949108e234c1d9f22a3336d2be4daaf292" +checksum = "4972aec926d1e06d6abc11ab3f063d2f7063be3dd46fd2839442c14d8e48f3ed" dependencies = [ "openapiv3", "proc-macro2", - "progenitor-impl 0.9.1", + "progenitor-impl 0.10.0", "quote", "schemars", "serde", @@ -4981,13 +5577,13 @@ dependencies = [ [[package]] name = "progenitor-macro" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4972aec926d1e06d6abc11ab3f063d2f7063be3dd46fd2839442c14d8e48f3ed" +checksum = "5dd79317ec8ab905738484d2744d368beee6e357fc043944d985f85a0174f1f7" dependencies = [ "openapiv3", "proc-macro2", - "progenitor-impl 0.10.0", + "progenitor-impl 0.11.1", "quote", "schemars", "serde", @@ -5005,18 +5601,29 @@ checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.6.0", + "bitflags 2.9.4", "lazy_static", "num-traits", "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift 0.3.0", - "regex-syntax", + "regex-syntax 0.8.5", "rusty-fork", "tempfile", "unarray", ] +[[package]] +name = "protocol" +version = "0.1.0" +source = "git+https://github.com/oxidecomputer/lldp#515c31efad6ea915f95f9eefa0b4667aac2f2380" +dependencies = [ + "anyhow", + "schemars", + "serde", + "thiserror 1.0.69", +] + [[package]] name = "ptr_meta" version = "0.1.4" @@ -5039,19 +5646,19 @@ dependencies = [ [[package]] name = "qorb" -version = "0.2.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac55d5c7e6acb2b6b1a248b70d08ed437613eb8c05f833de3a5c9397d368fc71" +checksum = "2f223a85f489c9548719fb367c6733e8bc9d4eef76d6ea59a18299acd9497c60" dependencies = [ "anyhow", "async-trait", "debug-ignore", "derive-where", "futures", - "hickory-resolver", - "rand 0.8.5", + "hickory-resolver 0.24.4", + "rand 0.9.2", "serde", - "thiserror 1.0.69", + "thiserror 2.0.16", "tokio", "tokio-stream", "tracing", @@ -5074,7 +5681,7 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash", + "rustc-hash 2.1.1", "rustls 0.23.13", "socket2 0.5.10", "thiserror 1.0.69", @@ -5091,7 +5698,7 @@ dependencies = [ "bytes", "rand 0.8.5", "ring", - "rustc-hash", + "rustc-hash 2.1.1", "rustls 0.23.13", "slab", "thiserror 1.0.69", @@ -5375,15 +5982,44 @@ dependencies = [ ] [[package]] -name = "regex" -version = "1.11.3" +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "regex" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.11", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -5394,9 +6030,15 @@ checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.5" @@ -5405,9 +6047,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "regress" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ef7fa9ed0256d64a688a3747d0fef7a88851c18a5e1d57f115f38ec2e09366" +checksum = "145bb27393fe455dd64d6cbc8d059adfa392590a45eadf079c01b11857e7b010" dependencies = [ "hashbrown 0.15.2", "memchr", @@ -5441,9 +6083,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "base64 0.22.1", "bytes", @@ -5459,36 +6101,32 @@ dependencies = [ "hyper-rustls", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", "mime", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls 0.23.13", - "rustls-pemfile 2.1.3", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls 0.26.0", "tokio-util", "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", - "windows-registry 0.4.0", + "webpki-roots 1.0.2", ] [[package]] @@ -5511,7 +6149,7 @@ dependencies = [ "getrandom 0.2.11", "libc", "spin", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.48.0", ] @@ -5556,7 +6194,7 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e34486da88d8e051c7c0e23c3f15fd806ea8546260aa2fec247e97242ec143" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -5588,9 +6226,15 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc_version" @@ -5616,7 +6260,7 @@ version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys 0.4.14", @@ -5629,7 +6273,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys 0.9.3", @@ -5668,6 +6312,8 @@ version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ + "aws-lc-rs", + "log", "once_cell", "ring", "rustls-pki-types", @@ -5697,9 +6343,12 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-webpki" @@ -5708,7 +6357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -5717,9 +6366,10 @@ version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -5795,6 +6445,7 @@ dependencies = [ "semver 1.0.27", "serde", "serde_json", + "url", "uuid", ] @@ -5810,6 +6461,12 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -5843,7 +6500,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -5852,6 +6509,15 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "secrecy" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" +dependencies = [ + "zeroize", +] + [[package]] name = "security-framework" version = "2.9.2" @@ -5973,6 +6639,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_plain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" +dependencies = [ + "serde", +] + [[package]] name = "serde_repr" version = "0.1.18" @@ -6028,15 +6703,13 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.12.0" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e" dependencies = [ "base64 0.22.1", "chrono", "hex", - "indexmap 1.9.3", - "indexmap 2.11.4", "serde", "serde_derive", "serde_json", @@ -6046,11 +6719,11 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.12.0" +version = "3.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e" dependencies = [ - "darling", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.106", @@ -6062,7 +6735,7 @@ version = "0.9.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" dependencies = [ - "indexmap 2.11.4", + "indexmap", "itoa", "ryu", "serde", @@ -6100,6 +6773,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" version = "0.3.18" @@ -6172,6 +6851,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "slab" version = "0.4.9" @@ -6184,7 +6869,7 @@ dependencies = [ [[package]] name = "sled-hardware-types" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "illumos-utils", "omicron-common", @@ -6317,6 +7002,29 @@ dependencies = [ "managed", ] +[[package]] +name = "snafu" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e84b3f4eacbf3a1ce05eac6763b4d629d60cbc94d632e4092c54ade71f1e1a2" +dependencies = [ + "futures-core", + "pin-project", + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "socket2" version = "0.5.10" @@ -6436,24 +7144,11 @@ dependencies = [ [[package]] name = "strum" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" dependencies = [ - "strum_macros 0.27.1", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.106", + "strum_macros 0.27.2", ] [[package]] @@ -6471,14 +7166,13 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "rustversion", "syn 2.0.106", ] @@ -6573,7 +7267,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", "core-foundation", "system-configuration-sys", ] @@ -6588,6 +7282,30 @@ dependencies = [ "libc", ] +[[package]] +name = "tabled" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c998b0c8b921495196a48aabaf1901ff28be0760136e31604f7967b0792050e" +dependencies = [ + "papergrid", + "tabled_derive", + "unicode-width 0.1.14", +] + +[[package]] +name = "tabled_derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c138f99377e5d653a371cdad263615634cfc8467685dfe8e73e2b8e98f44b17" +dependencies = [ + "heck 0.4.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "tabwriter" version = "1.4.0" @@ -6597,6 +7315,12 @@ dependencies = [ "unicode-width 0.1.14", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "take_mut" version = "0.2.2" @@ -6622,9 +7346,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.19.1" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.1", @@ -6660,16 +7384,23 @@ checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662" dependencies = [ "fnv", "nom", - "phf", + "phf 0.11.2", "phf_codegen", ] +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + [[package]] name = "test-strategy" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95eb2d223f5cd3ec8dd7874cf4ada95c9cf2b5ed84ecfb1046d9aefee0c28b12" +checksum = "43b12f9683de37f9980e485167ee624bfaa0b6b04da661e98e25ef9c2669bc1b" dependencies = [ + "derive-ex", "proc-macro2", "quote", "structmeta", @@ -6847,6 +7578,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "tokio-dtrace" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5eb4bcf85c373ff09a8beb87a477c2df185cd8842a770386a88bc3ff7ac5abb" +dependencies = [ + "thiserror 2.0.16", + "tokio", + "usdt", +] + [[package]] name = "tokio-macros" version = "2.5.0" @@ -6935,6 +7677,7 @@ dependencies = [ "futures-core", "futures-sink", "pin-project-lite", + "slab", "tokio", ] @@ -6968,7 +7711,7 @@ version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0" dependencies = [ - "indexmap 2.11.4", + "indexmap", "serde_core", "serde_spanned 1.0.2", "toml_datetime 0.7.2", @@ -7001,7 +7744,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.11.4", + "indexmap", "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", @@ -7014,7 +7757,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.11.4", + "indexmap", "toml_datetime 0.6.11", "winnow 0.5.19", ] @@ -7025,7 +7768,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.4", + "indexmap", "serde", "serde_spanned 0.6.9", "toml_datetime 0.6.11", @@ -7060,6 +7803,41 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" +[[package]] +name = "tough" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe73519c5c485dc0b585088523ad861cda19836b2eb94896fac278db68bd5ab" +dependencies = [ + "async-recursion", + "async-trait", + "aws-lc-rs", + "bytes", + "chrono", + "dyn-clone", + "futures", + "futures-core", + "globset", + "hex", + "log", + "olpc-cjson", + "pem", + "percent-encoding", + "reqwest", + "rustls 0.23.13", + "serde", + "serde_json", + "serde_plain", + "snafu", + "tempfile", + "tokio", + "tokio-util", + "typed-path", + "untrusted 0.7.1", + "url", + "walkdir", +] + [[package]] name = "tower" version = "0.5.2" @@ -7075,6 +7853,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags 2.9.4", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -7154,10 +7950,14 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ + "matchers", "nu-ansi-term 0.46.0", + "once_cell", + "regex", "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", ] @@ -7171,9 +7971,10 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tufaceous-artifact" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/tufaceous?branch=main#d2387032714f66e31b7e255d89f9bf6eb9b3a010" +source = "git+https://github.com/oxidecomputer/tufaceous?branch=main#db072743d0cfde918dcf981a064f225b0003b98d" dependencies = [ - "parse-display", + "daft", + "hex", "proptest", "schemars", "semver 1.0.27", @@ -7181,6 +7982,7 @@ dependencies = [ "serde_human_bytes", "strum 0.26.3", "test-strategy", + "thiserror 2.0.16", ] [[package]] @@ -7193,86 +7995,32 @@ dependencies = [ ] [[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "typify" -version = "0.2.0" +name = "typed-path" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c644dda9862f0fef3a570d8ddb3c2cfb1d5ac824a1f2ddfa7bc8f071a5ad8a" -dependencies = [ - "typify-impl 0.2.0", - "typify-macro 0.2.0", -] +checksum = "82205ffd44a9697e34fc145491aa47310f9871540bb7909eaa9365e0a9a46607" [[package]] -name = "typify" -version = "0.3.0" +name = "typenum" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e03ba3643450cfd95a1aca2e1938fef63c1c1994489337998aff4ad771f21ef8" -dependencies = [ - "typify-impl 0.3.0", - "typify-macro 0.3.0", -] +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typify" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc5bec3cdff70fd542e579aa2e52967833e543a25fae0d14579043d2e868a50" -dependencies = [ - "typify-impl 0.4.1", - "typify-macro 0.4.1", -] - -[[package]] -name = "typify-impl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59ab345b6c0d8ae9500b9ff334a4c7c0d316c1c628dc55726b95887eb8dbd11" -dependencies = [ - "heck 0.5.0", - "log", - "proc-macro2", - "quote", - "regress", - "schemars", - "semver 1.0.27", - "serde", - "serde_json", - "syn 2.0.106", - "thiserror 1.0.69", - "unicode-ident", -] - -[[package]] -name = "typify-impl" -version = "0.3.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bce48219a2f3154aaa2c56cbf027728b24a3c8fe0a47ed6399781de2b3f3eeaf" +checksum = "7144144e97e987c94758a3017c920a027feac0799df325d6df4fc8f08d02068e" dependencies = [ - "heck 0.5.0", - "log", - "proc-macro2", - "quote", - "regress", - "schemars", - "semver 1.0.27", - "serde", - "serde_json", - "syn 2.0.106", - "thiserror 2.0.16", - "unicode-ident", + "typify-impl", + "typify-macro", ] [[package]] name = "typify-impl" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b52a67305054e1da6f3d99ad94875dcd0c7c49adbd17b4b64f0eefb7ae5bf8ab" +checksum = "062879d46aa4c9dfe0d33b035bbaf512da192131645d05deacb7033ec8581a09" dependencies = [ "heck 0.5.0", "log", @@ -7290,43 +8038,9 @@ dependencies = [ [[package]] name = "typify-macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "785e2cdcef0df8160fdd762ed548a637aaec1e83704fdbc14da0df66013ee8d0" -dependencies = [ - "proc-macro2", - "quote", - "schemars", - "semver 1.0.27", - "serde", - "serde_json", - "serde_tokenstream", - "syn 2.0.106", - "typify-impl 0.2.0", -] - -[[package]] -name = "typify-macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b5780d745920ed73c5b7447496a9b5c42ed2681a9b70859377aec423ecf02b" -dependencies = [ - "proc-macro2", - "quote", - "schemars", - "semver 1.0.27", - "serde", - "serde_json", - "serde_tokenstream", - "syn 2.0.106", - "typify-impl 0.3.0", -] - -[[package]] -name = "typify-macro" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ff5799be156e4f635c348c6051d165e1c59997827155133351a8c4d333d9841" +checksum = "9708a3ceb6660ba3f8d2b8f0567e7d4b8b198e2b94d093b8a6077a751425de9e" dependencies = [ "proc-macro2", "quote", @@ -7336,7 +8050,7 @@ dependencies = [ "serde_json", "serde_tokenstream", "syn 2.0.106", - "typify-impl 0.4.1", + "typify-impl", ] [[package]] @@ -7405,6 +8119,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "universal-hash" version = "0.5.1" @@ -7421,6 +8141,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" @@ -7430,7 +8156,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "update-engine" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/omicron?branch=main#52d7df46c6df67cfcbbe9a7cb0a3ae1f72c8a3ae" +source = "git+https://github.com/oxidecomputer/omicron?branch=main#4d5bdc6d348b27761348d763c4085f060bcefc18" dependencies = [ "anyhow", "cancel-safe-futures", @@ -7440,12 +8166,12 @@ dependencies = [ "either", "futures", "indent_write", - "indexmap 2.11.4", + "indexmap", "libsw", "linear-map", "omicron-workspace-hack", "owo-colors", - "petgraph 0.7.1", + "petgraph 0.8.3", "schemars", "serde", "serde_json", @@ -7466,6 +8192,7 @@ dependencies = [ "form_urlencoded", "idna 1.1.0", "percent-encoding", + "serde", ] [[package]] @@ -7827,6 +8554,27 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webpki-roots" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.37", +] + [[package]] name = "which" version = "8.0.0" @@ -7897,12 +8645,25 @@ dependencies = [ ] [[package]] -name = "windows-core" -version = "0.51.1" +name = "windows" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "ddf874e74c7a99773e62b1c671427abf01a425e77c3d3fb9fb1e4883ea934529" dependencies = [ - "windows-targets 0.48.5", + "windows-collections", + "windows-core 0.60.1", + "windows-future", + "windows-link 0.1.0", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5467f79cc1ba3f52ebb2ed41dbb459b8e7db636cc3429458d9a852e15bc24dec" +dependencies = [ + "windows-core 0.60.1", ] [[package]] @@ -7914,6 +8675,75 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247" +dependencies = [ + "windows-implement 0.59.0", + "windows-interface", + "windows-link 0.1.0", + "windows-result 0.3.1", + "windows-strings 0.3.1", +] + +[[package]] +name = "windows-core" +version = "0.62.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" +dependencies = [ + "windows-implement 0.60.1", + "windows-interface", + "windows-link 0.2.0", + "windows-result 0.4.0", + "windows-strings 0.5.0", +] + +[[package]] +name = "windows-future" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a787db4595e7eb80239b74ce8babfb1363d8e343ab072f2ffe901400c03349f0" +dependencies = [ + "windows-core 0.60.1", + "windows-link 0.1.0", +] + +[[package]] +name = "windows-implement" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-implement" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "windows-interface" +version = "0.59.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "windows-link" version = "0.1.0" @@ -7921,14 +8751,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" [[package]] -name = "windows-registry" -version = "0.4.0" +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-numerics" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "005dea54e2f6499f2cee279b8f703b3cf3b5734a2d8d21867c8f44003182eeed" dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.53.0", + "windows-core 0.60.1", + "windows-link 0.1.0", ] [[package]] @@ -7937,9 +8772,9 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c44a98275e31bfd112bb06ba96c8ab13c03383a3753fdddd715406a1824c7e0" dependencies = [ - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.0", + "windows-result 0.3.1", + "windows-strings 0.3.1", ] [[package]] @@ -7948,7 +8783,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" dependencies = [ - "windows-link", + "windows-link 0.1.0", +] + +[[package]] +name = "windows-result" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -7957,7 +8801,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" dependencies = [ - "windows-link", + "windows-link 0.1.0", +] + +[[package]] +name = "windows-strings" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -8035,29 +8888,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -8076,12 +8913,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -8100,12 +8931,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -8124,24 +8949,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -8160,12 +8973,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -8184,12 +8991,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -8208,12 +9009,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -8232,12 +9027,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" version = "0.5.19" @@ -8247,15 +9036,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winnow" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.7.13" @@ -8287,7 +9067,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ - "bitflags 2.6.0", + "bitflags 2.9.4", ] [[package]] @@ -8348,16 +9128,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "zerocopy" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" -dependencies = [ - "byteorder", - "zerocopy-derive 0.6.6", -] - [[package]] name = "zerocopy" version = "0.7.32" @@ -8370,22 +9140,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ - "zerocopy-derive 0.8.23", -] - -[[package]] -name = "zerocopy-derive" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "zerocopy-derive 0.8.27", ] [[package]] @@ -8401,9 +9160,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -8472,11 +9231,11 @@ dependencies = [ [[package]] name = "zone" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62a428a79ea2224ce8ab05d6d8a21bdd7b4b68a8dbc1230511677a56e72ef22" +checksum = "5d9ff514599b819915af2745e8adf6304030b28c072b2b1eb895e5739381bd0c" dependencies = [ - "itertools 0.10.5", + "itertools 0.12.1", "thiserror 1.0.69", "tokio", "zone_cfg_derive", diff --git a/agent-antagonist/src/main.rs b/agent-antagonist/src/main.rs index b12cf505f..a33eeb29e 100644 --- a/agent-antagonist/src/main.rs +++ b/agent-antagonist/src/main.rs @@ -718,6 +718,10 @@ async fn signal_thread(log: Logger, stop_flag: Arc) { } } +#[allow( + clippy::disallowed_macros, + reason = "using `#[tokio::main]` in tests is fine" +)] #[tokio::main] async fn main() -> Result<()> { let args = Args::try_parse()?; diff --git a/agent-types/src/region.rs b/agent-types/src/region.rs index 834f0a2a8..f9040e5af 100644 --- a/agent-types/src/region.rs +++ b/agent-types/src/region.rs @@ -64,7 +64,7 @@ impl Region { * Given a root directory, return a list of SMF properties to ensure for * the corresponding running instance. */ - pub fn get_smf_properties(&self, dir: &Path) -> Vec { + pub fn get_smf_properties(&self, dir: &Path) -> Vec> { let mut results = vec![ SmfProperty { name: "directory", diff --git a/agent-types/src/snapshot.rs b/agent-types/src/snapshot.rs index d14423652..fa6c24b5a 100644 --- a/agent-types/src/snapshot.rs +++ b/agent-types/src/snapshot.rs @@ -33,7 +33,7 @@ impl RunningSnapshot { * Given a root directory, return a list of SMF properties to ensure for * the corresponding running instance. */ - pub fn get_smf_properties(&self, dir: &Path) -> Vec { + pub fn get_smf_properties(&self, dir: &Path) -> Vec> { let mut results = vec![ SmfProperty { name: "directory", diff --git a/agent/src/main.rs b/agent/src/main.rs index 7c2348aef..6d0c48ae7 100644 --- a/agent/src/main.rs +++ b/agent/src/main.rs @@ -8,7 +8,6 @@ use slog::{debug, error, info, o, Logger}; use std::collections::HashSet; use std::net::SocketAddr; use std::path::{Path, PathBuf}; -use std::process::Command; use std::sync::Arc; const PROG: &str = "crucible-agent"; @@ -800,6 +799,394 @@ where Ok(()) } +/** + * For region with state Tombstoned, destroy the region. + * + * For region with state Requested, create the region. + */ +fn worker( + log: Logger, + df: Arc, + regions_dataset: ZFSDataset, + downstairs_program: PathBuf, + downstairs_prefix: String, + snapshot_prefix: String, +) { + let regions_dataset_path = match regions_dataset.path() { + Ok(regions_dataset_path) => regions_dataset_path, + Err(e) => { + panic!( + "Cannot get regions_dataset_path for {:?}: {}", + regions_dataset, e, + ); + } + }; + + loop { + /* + * This loop fires whenever there's work to do. This work may be: + * + * - create a region + * - delete a region + * - create a running snapshot + * - delete a running snapshot + * + * We use first_in_states to both get the next available Resource enum, + * which wraps either a Region or RegionSnapshot that has changed. + * Otherwise, first_in_states will wait on the condvar. + */ + let work = df.first_in_states(&[State::Tombstoned, State::Requested]); + + match work { + Resource::Region(r) => { + /* + * If the region is State::Requested, we create that region + * then run the apply_smf(). + * + * If the region is State:Tombstoned, we apply_smf() first, + * then we finish up destroying the region. + */ + match &r.state { + State::Requested => 'requested: { + /* + * Compute the actual size required for a full region, + * then add our metadata overhead to that. + */ + let region_size = r.block_size + * r.extent_size + * r.extent_count as u64; + let reservation = + (region_size as f64 * RESERVATION_FACTOR).round() + as u64; + let quota = region_size * QUOTA_FACTOR; + + info!( + log, + "Region size:{} reservation:{} quota:{}", + region_size, + reservation, + quota, + ); + + // If regions need to be created, do that before + // apply_smf. + let region_dataset = match regions_dataset + .ensure_child_dataset( + &r.id.0, + Some(reservation), + Some(quota), + &log, + ) { + Ok(region_dataset) => region_dataset, + Err(e) => { + error!( + log, + "Dataset {} creation failed: {}", + &r.id.0, + e, + ); + df.fail(&r.id); + break 'requested; + } + }; + + let dataset_path = match region_dataset.path() { + Ok(dataset_path) => dataset_path, + Err(e) => { + error!( + log, + "Failed to find path for dataset {}: {}", + &r.id.0, + e, + ); + df.fail(&r.id); + break 'requested; + } + }; + + // It's important that a region transition to "Created" + // only after it has been created as a dataset: + // after the crucible agent restarts, `apply_smf` will + // only start downstairs services for those in + // "Created". If the `df.created` is moved to after this + // function's `apply_smf` call, and there is a crash + // before that moved `df.created` is set, then the agent + // will not start a downstairs service for this region + // when rebooted. + let res = worker_region_create( + &log, + &downstairs_program, + &r, + &dataset_path, + ) + .and_then(|_| df.created(&r.id)); + + if let Err(e) = res { + error!( + log, + "region {:?} create failed: {:?}", r.id.0, e + ); + df.fail(&r.id); + break 'requested; + } + + info!(log, "applying SMF actions post create..."); + let result = apply_smf( + &log, + &df, + regions_dataset_path.clone(), + &downstairs_prefix, + &snapshot_prefix, + ); + + if let Err(e) = result { + error!(log, "SMF application failure: {:?}", e); + } else { + info!(log, "SMF ok!"); + } + } + + State::Tombstoned => 'tombstoned: { + info!(log, "applying SMF actions before removal..."); + let result = apply_smf( + &log, + &df, + regions_dataset_path.clone(), + &downstairs_prefix, + &snapshot_prefix, + ); + + if let Err(e) = result { + error!(log, "SMF application failure: {:?}", e); + } else { + info!(log, "SMF ok!"); + } + + // After SMF successfully shuts off downstairs, remove + // zfs dataset. + let region_dataset = + match regions_dataset.from_child_dataset(&r.id.0) { + Ok(region_dataset) => region_dataset, + Err(e) => { + error!( + log, + "Cannot find region {:?} to remove: {}", + r.id.0, + e, + ); + let _ = df.destroyed(&r.id); + break 'tombstoned; + } + }; + let res = + worker_region_destroy(&log, &r, region_dataset) + .and_then(|_| df.destroyed(&r.id)); + + if let Err(e) = res { + error!( + log, + "region {:?} destroy failed: {:?}", r.id.0, e + ); + df.fail(&r.id); + } + } + _ => { + error!( + log, + "worker got unexpected region state: {:?}", r + ); + std::process::exit(1); + } + } + } + + Resource::RunningSnapshot(region_id, snapshot_name, rs) => { + /* + * No matter what the state is, we run apply_smf(). Creating and + * deleting running snapshots only requires us to create and + * delete services. The snapshots are not created by us. + * + * If the running snapshot is Requested, we apply_smf() first, + * then set the state to Created. This is a little different + * from how Regions are handled. + * + * If the running snapshot is Tombstoned, we apply_smf() first, + * then we set the state to Destroyed + */ + info!( + log, + "applying SMF actions for region {} running snapshot {} (state {:?})...", + rs.id.0, + rs.name, + rs.state, + ); + + let result = apply_smf( + &log, + &df, + regions_dataset_path.clone(), + &downstairs_prefix, + &snapshot_prefix, + ); + + if let Err(e) = result { + error!(log, "SMF application failure: {:?}", e); + + // There's no fail_rs here: a future `apply_smf` should + // attempt to start the service again. + } else { + info!(log, "SMF ok!"); + + // `apply_smf` returned Ok, so the desired state transition + // succeeded: update the datafile. + let res = match &rs.state { + State::Requested => { + df.created_rs(®ion_id, &snapshot_name) + } + + State::Tombstoned => { + df.destroyed_rs(®ion_id, &snapshot_name) + } + + _ => { + error!( + log, + "worker got unexpected running snapshot state: {:?}", + rs, + ); + std::process::exit(1); + } + }; + + if let Err(e) = res { + error!( + log, + "running snapshot {} state change failed: {:?}", + rs.id.0, + e + ); + + df.fail_rs(®ion_id, &snapshot_name); + } + } + } + } + } +} + +fn worker_region_create( + log: &Logger, + prog: &Path, + region: ®ion::Region, + dir: &Path, +) -> Result<()> { + let log = log.new(o!("region" => region.id.0.to_string())); + + /* + * We may have crashed half way through a previous provision. To make + * this idempotent, clean out the target data directory and try + * again. + */ + for entry in std::fs::read_dir(dir)? { + let entry = entry?; + let path = entry.path(); + + if entry.file_type()?.is_dir() { + info!(log, "removing existing directory {:?}", path); + std::fs::remove_dir_all(&path)?; + } else { + info!(log, "removing existing file {:?}", path); + std::fs::remove_file(&path)?; + } + } + + /* + * Run the downstairs program in the mode where it will create the data + * files (note region starts blank). + */ + info!(log, "creating region {:?} at {:?}", region, dir); + + let mut binding = std::process::Command::new(prog); + let mut cmd = binding + .env_clear() + .arg("create") + .arg("--uuid") + .arg(region.id.0.clone()) + .arg("--data") + .arg(dir) + .arg("--block-size") + .arg(region.block_size.to_string()) + .arg("--extent-size") + .arg(region.extent_size.to_string()) + .arg("--extent-count") + .arg(region.extent_count.to_string()); + + if region.encrypted { + cmd = cmd.arg("--encrypted"); + } + + if let Some(source) = region.source { + cmd = cmd.arg("--clone-source").arg(source.to_string()); + } + + info!(log, "downstairs create with: {:?}", cmd); + let cmd = cmd.output()?; + + if cmd.status.success() { + info!(log, "region files created ok"); + } else { + let err = String::from_utf8_lossy(&cmd.stderr); + let out = String::from_utf8_lossy(&cmd.stdout); + error!(log, "downstairs create failed: out {:?} err {:?}", out, err); + bail!("region files create failure"); + } + + /* + * If there are X509 files, write those out to the same directory. + */ + if let Some(cert_pem) = ®ion.cert_pem { + let mut path = dir.to_path_buf(); + path.push("cert.pem"); + std::fs::write(path, cert_pem)?; + } + + if let Some(key_pem) = ®ion.key_pem { + let mut path = dir.to_path_buf(); + path.push("key.pem"); + std::fs::write(path, key_pem)?; + } + + if let Some(root_pem) = ®ion.root_pem { + let mut path = dir.to_path_buf(); + path.push("root.pem"); + std::fs::write(path, root_pem)?; + } + + /* + * `apply_smf` will then create the appropriate instance + */ + + Ok(()) +} + +fn worker_region_destroy( + log: &Logger, + region: ®ion::Region, + region_dataset: ZFSDataset, +) -> Result<()> { + let log = log.new(o!("region" => region.id.0.to_string())); + + let region_dataset_name = region_dataset.dataset(); + + info!(log, "deleting zfs dataset {:?}", region_dataset_name); + + // Note: zfs destroy will fail if snapshots exist, but previous steps should + // prevent that scenario. + region_dataset.destroy(&log)?; + + Ok(()) +} + #[cfg(test)] mod test { use super::*; @@ -863,8 +1250,8 @@ mod test { let expected_snapshot_instances: Vec = running_snapshots .iter() .flat_map(|(_, n)| { - n.iter() - .map(|(_, s)| { + n.values() + .map(|s| { format!("{}-{}-{}", snapshot_prefix, s.id.0, s.name) }) .collect::>() @@ -1353,607 +1740,219 @@ mod test { .unwrap(); assert!(instance.enabled()); - let pg = instance.get_pg("config")?.unwrap(); - - let directory = pg.get_property("directory")?.unwrap(); - assert_eq!( - directory.value()?.unwrap().as_string()?, - harness.snapshot_path_string(®ion_id, snapshot_name.clone()) - ); - } - - // Running snapshots transition from state Requested to state Created - // when the smf apply is ok. Make sure (via the Drop comparison that - // TestSmfHarness does) that when the agent zone bounces it reads - // from the datafile, then creates running snapshots for objects in - // state Created too. - harness.df.created_rs(®ion_id, &snapshot_name)?; - - Ok(()) - } - - #[test] - fn test_smf_datafile_race_running_snapshots() -> Result<()> { - // Test a race between the state changes that occur from what the user - // is requesting, and the state changes that occur from worker. - - let harness = TestSmfHarness::new()?; - - let region_id = RegionId(Uuid::new_v4().to_string()); - let snapshot_name = Uuid::new_v4().to_string(); - - // Submit a create region request (http) - harness.df.create_region_request(CreateRegion { - id: region_id.clone(), - - block_size: 512, - extent_size: 10, - extent_count: 10, - encrypted: true, - - cert_pem: None, - key_pem: None, - root_pem: None, - source: None, - })?; - - // Pretend to actually create the region (worker) - harness.df.created(®ion_id)?; - - // Now call apply_smf (worker) - harness.apply_smf()?; - - // The downstairs SMF instance was created - { - let instance = harness - .smf_interface - .get_instance(&format!("downstairs-{}", region_id.0))? - .unwrap(); - assert!(instance.enabled()); - - let pg = instance.get_pg("config")?.unwrap(); - - let directory = pg.get_property("directory")?.unwrap(); - assert_eq!( - directory.value()?.unwrap().as_string()?, - harness.region_path_string(®ion_id) - ); - } - - // Pretend to create a snapshot (pantry, or from propolis) - harness.create_snapshot(region_id.0.to_string(), snapshot_name.clone()); - - // Submit a create running snapshot request - harness.df.create_running_snapshot_request( - CreateRunningSnapshotRequest { - id: region_id.clone(), - name: snapshot_name.clone(), - - cert_pem: None, - key_pem: None, - root_pem: None, - }, - )?; - - // From Nexus's perspective, the saga to create a snapshot might have - // already completed before apply_smf runs. - - // Call apply_smf (worker) - harness.apply_smf()?; - - // The running snapshot should exist - { - let instance = harness - .smf_interface - .get_instance(&format!( - "snapshot-{}-{}", - region_id.0, snapshot_name - ))? - .unwrap(); - assert!(instance.enabled()); - - let pg = instance.get_pg("config")?.unwrap(); - - let directory = pg.get_property("directory")?.unwrap(); - assert_eq!( - directory.value()?.unwrap().as_string()?, - harness.snapshot_path_string(®ion_id, snapshot_name.clone()) - ); - } - - // After apply_smf, the running snapshot will be in state Requested - { - let running_snapshots = harness.df.running_snapshots(); - let region_running_snapshots = - running_snapshots.get(®ion_id).unwrap(); - let running_snapshot = - region_running_snapshots.get(&snapshot_name).unwrap(); - assert_eq!(running_snapshot.state, State::Requested); - } - - // Say a snapshot_delete saga runs now. Before the worker can call - // `df.created_rs`, there's a destroy_rs call that comes in and sets it - // to tombstoned. - harness.df.delete_running_snapshot_request( - DeleteRunningSnapshotRequest { - id: region_id.clone(), - name: snapshot_name.clone(), - }, - )?; - - // Now it's in state Tombstoned - { - let running_snapshots = harness.df.running_snapshots(); - let region_running_snapshots = - running_snapshots.get(®ion_id).unwrap(); - let running_snapshot = - region_running_snapshots.get(&snapshot_name).unwrap(); - assert_eq!(running_snapshot.state, State::Tombstoned); - } - - // worker finishes up with calling `created_rs` - harness.df.created_rs(®ion_id, &snapshot_name)?; - - // There's a check in `created_rs` that sees if the RunningSnapshot is - // in state Tombstoned, and bails out. The state should still be - // Tombstoned. - { - let running_snapshots = harness.df.running_snapshots(); - let region_running_snapshots = - running_snapshots.get(®ion_id).unwrap(); - let running_snapshot = - region_running_snapshots.get(&snapshot_name).unwrap(); - assert_eq!(running_snapshot.state, State::Tombstoned); - } - - // `delete_running_snapshot_request` will notify the worker to run, so - // run apply_smf. - harness.apply_smf()?; - - Ok(()) - } - - #[test] - fn test_smf_datafile_race_region() -> Result<()> { - // Test a race between the state changes that occur from what the user - // is requesting, and the state changes that occur from worker. - - let harness = TestSmfHarness::new()?; - - let region_id = RegionId(Uuid::new_v4().to_string()); - - // Submit a create region request (http) - harness.df.create_region_request(CreateRegion { - id: region_id.clone(), - - block_size: 512, - extent_size: 10, - extent_count: 10, - encrypted: true, - - cert_pem: None, - key_pem: None, - root_pem: None, - source: None, - })?; - - // The Region is Requested before `worker` ensures that the child - // dataset exists. - { - let region = harness.df.get(®ion_id).unwrap(); - assert_eq!(region.state, State::Requested); - } - - // If Nexus then requests to destroy the region, - harness.df.destroy(®ion_id)?; - - // the State will be Tombstoned - { - let region = harness.df.get(®ion_id).unwrap(); - assert_eq!(region.state, State::Tombstoned); - } - - // Worker will create the child dataset, then call `df.created`: - harness.df.created(®ion_id)?; - - // It should still be Tombstoned - { - let region = harness.df.get(®ion_id).unwrap(); - assert_eq!(region.state, State::Tombstoned); - } - - // `apply_smf` will be called twice - harness.apply_smf()?; - harness.apply_smf()?; - - Ok(()) - } -} + let pg = instance.get_pg("config")?.unwrap(); -/** - * For region with state Tombstoned, destroy the region. - * - * For region with state Requested, create the region. - */ -fn worker( - log: Logger, - df: Arc, - regions_dataset: ZFSDataset, - downstairs_program: PathBuf, - downstairs_prefix: String, - snapshot_prefix: String, -) { - let regions_dataset_path = match regions_dataset.path() { - Ok(regions_dataset_path) => regions_dataset_path, - Err(e) => { - panic!( - "Cannot get regions_dataset_path for {:?}: {}", - regions_dataset, e, + let directory = pg.get_property("directory")?.unwrap(); + assert_eq!( + directory.value()?.unwrap().as_string()?, + harness.snapshot_path_string(®ion_id, snapshot_name.clone()) ); } - }; - - loop { - /* - * This loop fires whenever there's work to do. This work may be: - * - * - create a region - * - delete a region - * - create a running snapshot - * - delete a running snapshot - * - * We use first_in_states to both get the next available Resource enum, - * which wraps either a Region or RegionSnapshot that has changed. - * Otherwise, first_in_states will wait on the condvar. - */ - let work = df.first_in_states(&[State::Tombstoned, State::Requested]); - match work { - Resource::Region(r) => { - /* - * If the region is State::Requested, we create that region - * then run the apply_smf(). - * - * If the region is State:Tombstoned, we apply_smf() first, - * then we finish up destroying the region. - */ - match &r.state { - State::Requested => 'requested: { - /* - * Compute the actual size required for a full region, - * then add our metadata overhead to that. - */ - let region_size = r.block_size - * r.extent_size - * r.extent_count as u64; - let reservation = - (region_size as f64 * RESERVATION_FACTOR).round() - as u64; - let quota = region_size * QUOTA_FACTOR; + // Running snapshots transition from state Requested to state Created + // when the smf apply is ok. Make sure (via the Drop comparison that + // TestSmfHarness does) that when the agent zone bounces it reads + // from the datafile, then creates running snapshots for objects in + // state Created too. + harness.df.created_rs(®ion_id, &snapshot_name)?; - info!( - log, - "Region size:{} reservation:{} quota:{}", - region_size, - reservation, - quota, - ); + Ok(()) + } - // If regions need to be created, do that before - // apply_smf. - let region_dataset = match regions_dataset - .ensure_child_dataset( - &r.id.0, - Some(reservation), - Some(quota), - &log, - ) { - Ok(region_dataset) => region_dataset, - Err(e) => { - error!( - log, - "Dataset {} creation failed: {}", - &r.id.0, - e, - ); - df.fail(&r.id); - break 'requested; - } - }; + #[test] + fn test_smf_datafile_race_running_snapshots() -> Result<()> { + // Test a race between the state changes that occur from what the user + // is requesting, and the state changes that occur from worker. - let dataset_path = match region_dataset.path() { - Ok(dataset_path) => dataset_path, - Err(e) => { - error!( - log, - "Failed to find path for dataset {}: {}", - &r.id.0, - e, - ); - df.fail(&r.id); - break 'requested; - } - }; + let harness = TestSmfHarness::new()?; - // It's important that a region transition to "Created" - // only after it has been created as a dataset: - // after the crucible agent restarts, `apply_smf` will - // only start downstairs services for those in - // "Created". If the `df.created` is moved to after this - // function's `apply_smf` call, and there is a crash - // before that moved `df.created` is set, then the agent - // will not start a downstairs service for this region - // when rebooted. - let res = worker_region_create( - &log, - &downstairs_program, - &r, - &dataset_path, - ) - .and_then(|_| df.created(&r.id)); + let region_id = RegionId(Uuid::new_v4().to_string()); + let snapshot_name = Uuid::new_v4().to_string(); - if let Err(e) = res { - error!( - log, - "region {:?} create failed: {:?}", r.id.0, e - ); - df.fail(&r.id); - break 'requested; - } + // Submit a create region request (http) + harness.df.create_region_request(CreateRegion { + id: region_id.clone(), - info!(log, "applying SMF actions post create..."); - let result = apply_smf( - &log, - &df, - regions_dataset_path.clone(), - &downstairs_prefix, - &snapshot_prefix, - ); + block_size: 512, + extent_size: 10, + extent_count: 10, + encrypted: true, - if let Err(e) = result { - error!(log, "SMF application failure: {:?}", e); - } else { - info!(log, "SMF ok!"); - } - } + cert_pem: None, + key_pem: None, + root_pem: None, + source: None, + })?; - State::Tombstoned => 'tombstoned: { - info!(log, "applying SMF actions before removal..."); - let result = apply_smf( - &log, - &df, - regions_dataset_path.clone(), - &downstairs_prefix, - &snapshot_prefix, - ); + // Pretend to actually create the region (worker) + harness.df.created(®ion_id)?; - if let Err(e) = result { - error!(log, "SMF application failure: {:?}", e); - } else { - info!(log, "SMF ok!"); - } + // Now call apply_smf (worker) + harness.apply_smf()?; - // After SMF successfully shuts off downstairs, remove - // zfs dataset. - let region_dataset = - match regions_dataset.from_child_dataset(&r.id.0) { - Ok(region_dataset) => region_dataset, - Err(e) => { - error!( - log, - "Cannot find region {:?} to remove: {}", - r.id.0, - e, - ); - let _ = df.destroyed(&r.id); - break 'tombstoned; - } - }; - let res = - worker_region_destroy(&log, &r, region_dataset) - .and_then(|_| df.destroyed(&r.id)); + // The downstairs SMF instance was created + { + let instance = harness + .smf_interface + .get_instance(&format!("downstairs-{}", region_id.0))? + .unwrap(); + assert!(instance.enabled()); - if let Err(e) = res { - error!( - log, - "region {:?} destroy failed: {:?}", r.id.0, e - ); - df.fail(&r.id); - } - } - _ => { - error!( - log, - "worker got unexpected region state: {:?}", r - ); - std::process::exit(1); - } - } - } + let pg = instance.get_pg("config")?.unwrap(); - Resource::RunningSnapshot(region_id, snapshot_name, rs) => { - /* - * No matter what the state is, we run apply_smf(). Creating and - * deleting running snapshots only requires us to create and - * delete services. The snapshots are not created by us. - * - * If the running snapshot is Requested, we apply_smf() first, - * then set the state to Created. This is a little different - * from how Regions are handled. - * - * If the running snapshot is Tombstoned, we apply_smf() first, - * then we set the state to Destroyed - */ - info!( - log, - "applying SMF actions for region {} running snapshot {} (state {:?})...", - rs.id.0, - rs.name, - rs.state, - ); + let directory = pg.get_property("directory")?.unwrap(); + assert_eq!( + directory.value()?.unwrap().as_string()?, + harness.region_path_string(®ion_id) + ); + } - let result = apply_smf( - &log, - &df, - regions_dataset_path.clone(), - &downstairs_prefix, - &snapshot_prefix, - ); + // Pretend to create a snapshot (pantry, or from propolis) + harness.create_snapshot(region_id.0.to_string(), snapshot_name.clone()); - if let Err(e) = result { - error!(log, "SMF application failure: {:?}", e); + // Submit a create running snapshot request + harness.df.create_running_snapshot_request( + CreateRunningSnapshotRequest { + id: region_id.clone(), + name: snapshot_name.clone(), - // There's no fail_rs here: a future `apply_smf` should - // attempt to start the service again. - } else { - info!(log, "SMF ok!"); + cert_pem: None, + key_pem: None, + root_pem: None, + }, + )?; - // `apply_smf` returned Ok, so the desired state transition - // succeeded: update the datafile. - let res = match &rs.state { - State::Requested => { - df.created_rs(®ion_id, &snapshot_name) - } + // From Nexus's perspective, the saga to create a snapshot might have + // already completed before apply_smf runs. - State::Tombstoned => { - df.destroyed_rs(®ion_id, &snapshot_name) - } + // Call apply_smf (worker) + harness.apply_smf()?; - _ => { - error!( - log, - "worker got unexpected running snapshot state: {:?}", - rs, - ); - std::process::exit(1); - } - }; + // The running snapshot should exist + { + let instance = harness + .smf_interface + .get_instance(&format!( + "snapshot-{}-{}", + region_id.0, snapshot_name + ))? + .unwrap(); + assert!(instance.enabled()); - if let Err(e) = res { - error!( - log, - "running snapshot {} state change failed: {:?}", - rs.id.0, - e - ); + let pg = instance.get_pg("config")?.unwrap(); - df.fail_rs(®ion_id, &snapshot_name); - } - } - } + let directory = pg.get_property("directory")?.unwrap(); + assert_eq!( + directory.value()?.unwrap().as_string()?, + harness.snapshot_path_string(®ion_id, snapshot_name.clone()) + ); } - } -} -fn worker_region_create( - log: &Logger, - prog: &Path, - region: ®ion::Region, - dir: &Path, -) -> Result<()> { - let log = log.new(o!("region" => region.id.0.to_string())); + // After apply_smf, the running snapshot will be in state Requested + { + let running_snapshots = harness.df.running_snapshots(); + let region_running_snapshots = + running_snapshots.get(®ion_id).unwrap(); + let running_snapshot = + region_running_snapshots.get(&snapshot_name).unwrap(); + assert_eq!(running_snapshot.state, State::Requested); + } - /* - * We may have crashed half way through a previous provision. To make - * this idempotent, clean out the target data directory and try - * again. - */ - for entry in std::fs::read_dir(dir)? { - let entry = entry?; - let path = entry.path(); + // Say a snapshot_delete saga runs now. Before the worker can call + // `df.created_rs`, there's a destroy_rs call that comes in and sets it + // to tombstoned. + harness.df.delete_running_snapshot_request( + DeleteRunningSnapshotRequest { + id: region_id.clone(), + name: snapshot_name.clone(), + }, + )?; - if entry.file_type()?.is_dir() { - info!(log, "removing existing directory {:?}", path); - std::fs::remove_dir_all(&path)?; - } else { - info!(log, "removing existing file {:?}", path); - std::fs::remove_file(&path)?; + // Now it's in state Tombstoned + { + let running_snapshots = harness.df.running_snapshots(); + let region_running_snapshots = + running_snapshots.get(®ion_id).unwrap(); + let running_snapshot = + region_running_snapshots.get(&snapshot_name).unwrap(); + assert_eq!(running_snapshot.state, State::Tombstoned); } - } - /* - * Run the downstairs program in the mode where it will create the data - * files (note region starts blank). - */ - info!(log, "creating region {:?} at {:?}", region, dir); + // worker finishes up with calling `created_rs` + harness.df.created_rs(®ion_id, &snapshot_name)?; - let mut binding = Command::new(prog); - let mut cmd = binding - .env_clear() - .arg("create") - .arg("--uuid") - .arg(region.id.0.clone()) - .arg("--data") - .arg(dir) - .arg("--block-size") - .arg(region.block_size.to_string()) - .arg("--extent-size") - .arg(region.extent_size.to_string()) - .arg("--extent-count") - .arg(region.extent_count.to_string()); + // There's a check in `created_rs` that sees if the RunningSnapshot is + // in state Tombstoned, and bails out. The state should still be + // Tombstoned. + { + let running_snapshots = harness.df.running_snapshots(); + let region_running_snapshots = + running_snapshots.get(®ion_id).unwrap(); + let running_snapshot = + region_running_snapshots.get(&snapshot_name).unwrap(); + assert_eq!(running_snapshot.state, State::Tombstoned); + } - if region.encrypted { - cmd = cmd.arg("--encrypted"); - } + // `delete_running_snapshot_request` will notify the worker to run, so + // run apply_smf. + harness.apply_smf()?; - if let Some(source) = region.source { - cmd = cmd.arg("--clone-source").arg(source.to_string()); + Ok(()) } - info!(log, "downstairs create with: {:?}", cmd); - let cmd = cmd.output()?; + #[test] + fn test_smf_datafile_race_region() -> Result<()> { + // Test a race between the state changes that occur from what the user + // is requesting, and the state changes that occur from worker. - if cmd.status.success() { - info!(log, "region files created ok"); - } else { - let err = String::from_utf8_lossy(&cmd.stderr); - let out = String::from_utf8_lossy(&cmd.stdout); - error!(log, "downstairs create failed: out {:?} err {:?}", out, err); - bail!("region files create failure"); - } + let harness = TestSmfHarness::new()?; - /* - * If there are X509 files, write those out to the same directory. - */ - if let Some(cert_pem) = ®ion.cert_pem { - let mut path = dir.to_path_buf(); - path.push("cert.pem"); - std::fs::write(path, cert_pem)?; - } + let region_id = RegionId(Uuid::new_v4().to_string()); - if let Some(key_pem) = ®ion.key_pem { - let mut path = dir.to_path_buf(); - path.push("key.pem"); - std::fs::write(path, key_pem)?; - } + // Submit a create region request (http) + harness.df.create_region_request(CreateRegion { + id: region_id.clone(), - if let Some(root_pem) = ®ion.root_pem { - let mut path = dir.to_path_buf(); - path.push("root.pem"); - std::fs::write(path, root_pem)?; - } + block_size: 512, + extent_size: 10, + extent_count: 10, + encrypted: true, - /* - * `apply_smf` will then create the appropriate instance - */ + cert_pem: None, + key_pem: None, + root_pem: None, + source: None, + })?; - Ok(()) -} + // The Region is Requested before `worker` ensures that the child + // dataset exists. + { + let region = harness.df.get(®ion_id).unwrap(); + assert_eq!(region.state, State::Requested); + } -fn worker_region_destroy( - log: &Logger, - region: ®ion::Region, - region_dataset: ZFSDataset, -) -> Result<()> { - let log = log.new(o!("region" => region.id.0.to_string())); + // If Nexus then requests to destroy the region, + harness.df.destroy(®ion_id)?; - let region_dataset_name = region_dataset.dataset(); + // the State will be Tombstoned + { + let region = harness.df.get(®ion_id).unwrap(); + assert_eq!(region.state, State::Tombstoned); + } - info!(log, "deleting zfs dataset {:?}", region_dataset_name); + // Worker will create the child dataset, then call `df.created`: + harness.df.created(®ion_id)?; - // Note: zfs destroy will fail if snapshots exist, but previous steps should - // prevent that scenario. - region_dataset.destroy(&log)?; + // It should still be Tombstoned + { + let region = harness.df.get(®ion_id).unwrap(); + assert_eq!(region.state, State::Tombstoned); + } - Ok(()) + // `apply_smf` will be called twice + harness.apply_smf()?; + harness.apply_smf()?; + + Ok(()) + } } diff --git a/agent/src/smf_interface.rs b/agent/src/smf_interface.rs index 898be511a..037f5e119 100644 --- a/agent/src/smf_interface.rs +++ b/agent/src/smf_interface.rs @@ -1,9 +1,6 @@ // Copyright 2023 Oxide Computer Company use anyhow::Result; -use std::collections::HashMap; -use std::sync::Arc; -use std::sync::Mutex; /// Interfaces for an implementation to interface with SMF objects. pub trait SmfInterface { @@ -357,415 +354,439 @@ impl SmfTransaction for RealSmfTransaction<'_> { } } -#[derive(Debug)] #[cfg(test)] -pub struct MockSmf { - scope: String, - - // Instance name -> Mock instance entry - config: Mutex>, -} +pub use mock::*; #[cfg(test)] -impl MockSmf { - pub fn new(scope: String) -> MockSmf { - MockSmf { - scope, - config: Mutex::new(HashMap::new()), - } - } +mod mock { + use super::*; + use std::collections::HashMap; + use std::sync::Arc; + use std::sync::Mutex; - pub fn config_is_empty(&self) -> bool { - self.config.lock().unwrap().is_empty() + #[derive(Debug)] + pub struct MockSmf { + scope: String, + + // Instance name -> Mock instance entry + config: Mutex>, } -} -#[cfg(test)] -impl PartialEq for MockSmf { - fn eq(&self, other: &Self) -> bool { - let lhs = self.config.lock().unwrap(); - let rhs = other.config.lock().unwrap(); + impl MockSmf { + pub fn new(scope: String) -> MockSmf { + MockSmf { + scope, + config: Mutex::new(HashMap::new()), + } + } - self.scope == other.scope && *lhs == *rhs + pub fn config_is_empty(&self) -> bool { + self.config.lock().unwrap().is_empty() + } } -} -#[cfg(test)] -impl SmfInterface for MockSmf { - fn instances( - &self, - ) -> Result>, crucible_smf::ScfError> { - let config = self.config.lock().unwrap(); - let mut instances: Vec> = vec![]; + impl PartialEq for MockSmf { + fn eq(&self, other: &Self) -> bool { + let lhs = self.config.lock().unwrap(); + let rhs = other.config.lock().unwrap(); - for value in config.values() { - instances.push(Box::new(value.clone())); + self.scope == other.scope && *lhs == *rhs } - - Ok(instances) } - fn get_instance( - &self, - name: &str, - ) -> Result>, crucible_smf::ScfError> { - let config = self.config.lock().unwrap(); - if let Some(value) = config.get(name) { - Ok(Some(Box::new(value.clone()))) - } else { - Ok(None) + impl SmfInterface for MockSmf { + fn instances( + &self, + ) -> Result>, crucible_smf::ScfError> + { + let config = self.config.lock().unwrap(); + let mut instances: Vec> = vec![]; + + for value in config.values() { + instances.push(Box::new(value.clone())); + } + + Ok(instances) } - } - fn add_instance( - &self, - name: &str, - ) -> Result, crucible_smf::ScfError> { - let mut config = self.config.lock().unwrap(); + fn get_instance( + &self, + name: &str, + ) -> Result>, crucible_smf::ScfError> + { + let config = self.config.lock().unwrap(); + if let Some(value) = config.get(name) { + Ok(Some(Box::new(value.clone()))) + } else { + Ok(None) + } + } - config.insert( - name.to_string(), - MockSmfInstance::new( + fn add_instance( + &self, + name: &str, + ) -> Result, crucible_smf::ScfError> { + let mut config = self.config.lock().unwrap(); + + config.insert( name.to_string(), - format!("{}:{}", self.scope, name), - ), - ); + MockSmfInstance::new( + name.to_string(), + format!("{}:{}", self.scope, name), + ), + ); - drop(config); + drop(config); - Ok(self.get_instance(name)?.unwrap()) - } + Ok(self.get_instance(name)?.unwrap()) + } - /// When testing to see if running `apply_smf` based on the on-disk - /// datafile, disabled stuff remains in the current SMF interface and will - /// cause PartialEq comparison to fail. Prune that here so that comparison - /// can be done. - fn prune(&self) { - let mut config = self.config.lock().unwrap(); - let pairs: Vec<(String, MockSmfInstance)> = config.drain().collect(); - for (key, value) in pairs { - if value.inner.lock().unwrap().enabled { - config.insert(key, value); + /// When testing to see if running `apply_smf` based on the on-disk + /// datafile, disabled stuff remains in the current SMF interface and will + /// cause PartialEq comparison to fail. Prune that here so that comparison + /// can be done. + fn prune(&self) { + let mut config = self.config.lock().unwrap(); + let pairs: Vec<(String, MockSmfInstance)> = + config.drain().collect(); + for (key, value) in pairs { + if value.inner.lock().unwrap().enabled { + config.insert(key, value); + } } } } -} -#[derive(Clone, Debug, PartialEq, Default)] -pub struct MockSmfInstanceInner { - enabled: bool, - temporary: bool, - property_groups: HashMap, -} - -impl MockSmfInstanceInner { - pub fn get_property_group( - &self, - name: &str, - ) -> Option { - self.property_groups.get(name).cloned() + #[derive(Clone, Debug, PartialEq, Default)] + pub struct MockSmfInstanceInner { + enabled: bool, + temporary: bool, + property_groups: HashMap, } - pub fn add_property_group( - &mut self, - name: &str, - pg_type: &str, - ) -> MockSmfPropertyGroup { - self.property_groups - .entry(name.to_string()) - .or_insert(MockSmfPropertyGroup::new( - name.to_string(), - pg_type.to_string(), - )) - .clone() + impl MockSmfInstanceInner { + pub fn get_property_group( + &self, + name: &str, + ) -> Option { + self.property_groups.get(name).cloned() + } + + pub fn add_property_group( + &mut self, + name: &str, + pg_type: &str, + ) -> MockSmfPropertyGroup { + self.property_groups + .entry(name.to_string()) + .or_insert(MockSmfPropertyGroup::new( + name.to_string(), + pg_type.to_string(), + )) + .clone() + } } -} -#[derive(Clone, Debug)] -pub struct MockSmfInstance { - name: String, - fmri: String, - inner: Arc>, -} + #[derive(Clone, Debug)] + pub struct MockSmfInstance { + name: String, + fmri: String, + inner: Arc>, + } -#[cfg(test)] -impl MockSmfInstance { - pub fn new(name: String, fmri: String) -> MockSmfInstance { - MockSmfInstance { - name, - fmri, - inner: Arc::new(Mutex::new(MockSmfInstanceInner::default())), + impl MockSmfInstance { + pub fn new(name: String, fmri: String) -> MockSmfInstance { + MockSmfInstance { + name, + fmri, + inner: Arc::new(Mutex::new(MockSmfInstanceInner::default())), + } } } -} -impl PartialEq for MockSmfInstance { - fn eq(&self, other: &Self) -> bool { - let lhs = self.inner.lock().unwrap(); - let rhs = other.inner.lock().unwrap(); + impl PartialEq for MockSmfInstance { + fn eq(&self, other: &Self) -> bool { + let lhs = self.inner.lock().unwrap(); + let rhs = other.inner.lock().unwrap(); - self.name == other.name && self.fmri == other.fmri && *lhs == *rhs + self.name == other.name && self.fmri == other.fmri && *lhs == *rhs + } } -} -impl SmfInstance for MockSmfInstance { - fn name(&self) -> Result { - Ok(self.name.clone()) - } + impl SmfInstance for MockSmfInstance { + fn name(&self) -> Result { + Ok(self.name.clone()) + } - fn fmri(&self) -> Result { - Ok(self.fmri.clone()) - } + fn fmri(&self) -> Result { + Ok(self.fmri.clone()) + } - fn states( - &self, - ) -> Result< - (Option, Option), - crucible_smf::ScfError, - > { - let inner = self.inner.lock().unwrap(); - if inner.enabled { - Ok((Some(crucible_smf::State::Online), None)) - } else { - Ok((Some(crucible_smf::State::Disabled), None)) + fn states( + &self, + ) -> Result< + (Option, Option), + crucible_smf::ScfError, + > { + let inner = self.inner.lock().unwrap(); + if inner.enabled { + Ok((Some(crucible_smf::State::Online), None)) + } else { + Ok((Some(crucible_smf::State::Disabled), None)) + } } - } - fn disable(&self, temporary: bool) -> Result<(), crucible_smf::ScfError> { - let mut inner = self.inner.lock().unwrap(); - inner.enabled = false; - inner.temporary = temporary; + fn disable( + &self, + temporary: bool, + ) -> Result<(), crucible_smf::ScfError> { + let mut inner = self.inner.lock().unwrap(); + inner.enabled = false; + inner.temporary = temporary; - Ok(()) - } + Ok(()) + } - fn enable(&self, temporary: bool) -> Result<(), crucible_smf::ScfError> { - let mut inner = self.inner.lock().unwrap(); - inner.enabled = true; - inner.temporary = temporary; + fn enable( + &self, + temporary: bool, + ) -> Result<(), crucible_smf::ScfError> { + let mut inner = self.inner.lock().unwrap(); + inner.enabled = true; + inner.temporary = temporary; - Ok(()) - } + Ok(()) + } - #[cfg(test)] - fn enabled(&self) -> bool { - self.inner.lock().unwrap().enabled - } + fn enabled(&self) -> bool { + self.inner.lock().unwrap().enabled + } - fn get_pg( - &self, - name: &str, - ) -> Result>, crucible_smf::ScfError> - { - let inner = self.inner.lock().unwrap(); - if let Some(pg) = inner.get_property_group(name) { - Ok(Some(Box::new(pg))) - } else { - Ok(None) + fn get_pg( + &self, + name: &str, + ) -> Result< + Option>, + crucible_smf::ScfError, + > { + let inner = self.inner.lock().unwrap(); + if let Some(pg) = inner.get_property_group(name) { + Ok(Some(Box::new(pg))) + } else { + Ok(None) + } } - } - fn add_pg( - &self, - name: &str, - pgtype: &str, - ) -> Result, crucible_smf::ScfError> { - let mut inner = self.inner.lock().unwrap(); - let pg = inner.add_property_group(name, pgtype); - Ok(Box::new(pg)) - } + fn add_pg( + &self, + name: &str, + pgtype: &str, + ) -> Result, crucible_smf::ScfError> + { + let mut inner = self.inner.lock().unwrap(); + let pg = inner.add_property_group(name, pgtype); + Ok(Box::new(pg)) + } - fn get_snapshot( - &self, - _name: &str, - ) -> Result>, crucible_smf::ScfError> { - // XXX this probably isn't how it works? - let inner = self.inner.lock().unwrap(); - Ok(Some(Box::new(MockSmfSnapshot::new( - inner.property_groups.clone(), - )))) + fn get_snapshot( + &self, + _name: &str, + ) -> Result>, crucible_smf::ScfError> + { + // XXX this probably isn't how it works? + let inner = self.inner.lock().unwrap(); + Ok(Some(Box::new(MockSmfSnapshot::new( + inner.property_groups.clone(), + )))) + } } -} - -#[derive(Debug, PartialEq)] -pub struct MockSmfSnapshot { - property_groups: HashMap, -} -impl MockSmfSnapshot { - pub fn new( + #[derive(Debug, PartialEq)] + pub struct MockSmfSnapshot { property_groups: HashMap, - ) -> MockSmfSnapshot { - MockSmfSnapshot { property_groups } } -} -impl SmfSnapshot for MockSmfSnapshot { - fn get_pg( - &self, - name: &str, - ) -> Result>, crucible_smf::ScfError> - { - if let Some(pg) = self.property_groups.get(name) { - Ok(Some(Box::new(pg.clone()))) - } else { - Ok(None) + impl MockSmfSnapshot { + pub fn new( + property_groups: HashMap, + ) -> MockSmfSnapshot { + MockSmfSnapshot { property_groups } } } -} - -#[derive(Clone, Debug)] -pub struct MockSmfPropertyGroup { - pg_name: String, - pgtype: String, - properties: Arc>>, -} -impl MockSmfPropertyGroup { - pub fn new(pg_name: String, pgtype: String) -> MockSmfPropertyGroup { - MockSmfPropertyGroup { - pg_name, - pgtype, - properties: Arc::new(Mutex::new(HashMap::new())), + impl SmfSnapshot for MockSmfSnapshot { + fn get_pg( + &self, + name: &str, + ) -> Result< + Option>, + crucible_smf::ScfError, + > { + if let Some(pg) = self.property_groups.get(name) { + Ok(Some(Box::new(pg.clone()))) + } else { + Ok(None) + } } } -} -impl PartialEq for MockSmfPropertyGroup { - fn eq(&self, other: &Self) -> bool { - let lhs = self.properties.lock().unwrap(); - let rhs = other.properties.lock().unwrap(); - - self.pg_name == other.pg_name - && self.pgtype == other.pgtype - && *lhs == *rhs + #[derive(Clone, Debug)] + pub struct MockSmfPropertyGroup { + pg_name: String, + pgtype: String, + properties: Arc>>, } -} -impl SmfPropertyGroup for MockSmfPropertyGroup { - fn get_property( - &self, - name: &str, - ) -> Result>, crucible_smf::ScfError> { - let properties = self.properties.lock().unwrap(); - if let Some(value) = properties.get(name) { - Ok(Some(Box::new(value.clone()))) - } else { - Ok(None) + impl MockSmfPropertyGroup { + pub fn new(pg_name: String, pgtype: String) -> MockSmfPropertyGroup { + MockSmfPropertyGroup { + pg_name, + pgtype, + properties: Arc::new(Mutex::new(HashMap::new())), + } } } - fn transaction( - &self, - ) -> Result, crucible_smf::ScfError> { - Ok(Box::new(MockSmfTransaction::new(self.properties.clone()))) + impl PartialEq for MockSmfPropertyGroup { + fn eq(&self, other: &Self) -> bool { + let lhs = self.properties.lock().unwrap(); + let rhs = other.properties.lock().unwrap(); + + self.pg_name == other.pg_name + && self.pgtype == other.pgtype + && *lhs == *rhs + } } -} -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct MockSmfProperty { - name: String, - value: Option, -} + impl SmfPropertyGroup for MockSmfPropertyGroup { + fn get_property( + &self, + name: &str, + ) -> Result>, crucible_smf::ScfError> + { + let properties = self.properties.lock().unwrap(); + if let Some(value) = properties.get(name) { + Ok(Some(Box::new(value.clone()))) + } else { + Ok(None) + } + } -impl MockSmfProperty { - // XXX don't store scf_type_t, can't derive Eq - pub fn new( + fn transaction( + &self, + ) -> Result, crucible_smf::ScfError> + { + Ok(Box::new(MockSmfTransaction::new(self.properties.clone()))) + } + } + + #[derive(Clone, Debug, PartialEq, Eq)] + pub struct MockSmfProperty { name: String, - _typ: crucible_smf::scf_type_t, value: Option, - ) -> MockSmfProperty { - MockSmfProperty { name, value } } -} -impl SmfProperty for MockSmfProperty { - fn value( - &self, - ) -> Result>, crucible_smf::ScfError> { - if let Some(value) = &self.value { - Ok(Some(Box::new(MockSmfValue { - value: value.clone(), - }))) - } else { - Ok(None) + impl MockSmfProperty { + // XXX don't store scf_type_t, can't derive Eq + pub fn new( + name: String, + _typ: crucible_smf::scf_type_t, + value: Option, + ) -> MockSmfProperty { + MockSmfProperty { name, value } } } -} -pub struct MockSmfValue { - value: String, -} + impl SmfProperty for MockSmfProperty { + fn value( + &self, + ) -> Result>, crucible_smf::ScfError> + { + if let Some(value) = &self.value { + Ok(Some(Box::new(MockSmfValue { + value: value.clone(), + }))) + } else { + Ok(None) + } + } + } -impl SmfValue for MockSmfValue { - fn as_string(&self) -> Result { - Ok(self.value.clone()) + pub struct MockSmfValue { + value: String, } -} -pub struct MockSmfTransaction { - properties: Arc>>, - ensured: Mutex>, -} + impl SmfValue for MockSmfValue { + fn as_string(&self) -> Result { + Ok(self.value.clone()) + } + } -impl MockSmfTransaction { - pub fn new( + pub struct MockSmfTransaction { properties: Arc>>, - ) -> MockSmfTransaction { - MockSmfTransaction { - properties, - ensured: Mutex::new(HashMap::new()), - } + ensured: Mutex>, } -} -impl SmfTransaction for MockSmfTransaction { - fn start(&self) -> Result<(), crucible_smf::ScfError> { - Ok(()) + impl MockSmfTransaction { + pub fn new( + properties: Arc>>, + ) -> MockSmfTransaction { + MockSmfTransaction { + properties, + ensured: Mutex::new(HashMap::new()), + } + } } - fn property_ensure( - &self, - name: &str, - typ: crucible_smf::scf_type_t, - val: &str, - ) -> Result<(), crucible_smf::ScfError> { - let mut ensured = self.ensured.lock().unwrap(); + impl SmfTransaction for MockSmfTransaction { + fn start(&self) -> Result<(), crucible_smf::ScfError> { + Ok(()) + } - if let Some(p) = ensured.get_mut(name) { - *p = MockSmfProperty::new( - name.to_string(), - typ, - Some(val.to_string()), - ); - } else { - ensured.insert( - name.to_string(), - MockSmfProperty::new( + fn property_ensure( + &self, + name: &str, + typ: crucible_smf::scf_type_t, + val: &str, + ) -> Result<(), crucible_smf::ScfError> { + let mut ensured = self.ensured.lock().unwrap(); + + if let Some(p) = ensured.get_mut(name) { + *p = MockSmfProperty::new( name.to_string(), typ, Some(val.to_string()), - ), - ); - } + ); + } else { + ensured.insert( + name.to_string(), + MockSmfProperty::new( + name.to_string(), + typ, + Some(val.to_string()), + ), + ); + } - Ok(()) - } + Ok(()) + } - fn commit( - &self, - ) -> Result { - let ensured = self.ensured.lock().unwrap(); - let mut properties = self.properties.lock().unwrap(); + fn commit( + &self, + ) -> Result + { + let ensured = self.ensured.lock().unwrap(); + let mut properties = self.properties.lock().unwrap(); - for (name, property) in &*ensured { - if let Some(p) = properties.get_mut(name) { - *p = property.clone(); - } else { - properties.insert(name.clone(), property.clone()); + for (name, property) in &*ensured { + if let Some(p) = properties.get_mut(name) { + *p = property.clone(); + } else { + properties.insert(name.clone(), property.clone()); + } } - } - Ok(crucible_smf::CommitResult::Success) + Ok(crucible_smf::CommitResult::Success) + } } } diff --git a/common/src/lib.rs b/common/src/lib.rs index 3494c7af2..3ab74b835 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -172,7 +172,7 @@ impl From for CrucibleError { impl From for std::io::Error { fn from(e: CrucibleError) -> Self { - std::io::Error::new(std::io::ErrorKind::Other, e) + std::io::Error::other(e) } } diff --git a/common/src/region.rs b/common/src/region.rs index f2a384089..2f8532681 100644 --- a/common/src/region.rs +++ b/common/src/region.rs @@ -279,7 +279,7 @@ impl RegionDefinition { /// Checks whether the byte length is valid pub fn is_valid_byte_size(&self, bytelen: usize) -> bool { - bytelen % (self.block_size as usize) == 0 + bytelen.is_multiple_of(self.block_size as usize) } } diff --git a/crutest/src/cli.rs b/crutest/src/cli.rs index d56bfcb18..c70e1bdcb 100644 --- a/crutest/src/cli.rs +++ b/crutest/src/cli.rs @@ -597,26 +597,29 @@ async fn cmd_to_msg( #[derive(Clone)] pub struct CliPrompt; impl Prompt for CliPrompt { - fn render_prompt_left(&self) -> Cow { + fn render_prompt_left(&self) -> Cow<'_, str> { Cow::Owned(String::from(">> ")) } - fn render_prompt_right(&self) -> Cow { + fn render_prompt_right(&self) -> Cow<'_, str> { Cow::Owned(String::from("")) } - fn render_prompt_indicator(&self, _edit_mode: PromptEditMode) -> Cow { + fn render_prompt_indicator( + &self, + _edit_mode: PromptEditMode, + ) -> Cow<'_, str> { Cow::Owned(String::from("")) } - fn render_prompt_multiline_indicator(&self) -> Cow { + fn render_prompt_multiline_indicator(&self) -> Cow<'_, str> { Cow::Owned(String::from("")) } fn render_prompt_history_search_indicator( &self, _history_search: PromptHistorySearch, - ) -> Cow { + ) -> Cow<'_, str> { Cow::Owned(String::from("")) } } diff --git a/downstairs/src/extent_inner_sqlite.rs b/downstairs/src/extent_inner_sqlite.rs index efe140579..e1d309c25 100644 --- a/downstairs/src/extent_inner_sqlite.rs +++ b/downstairs/src/extent_inner_sqlite.rs @@ -898,10 +898,7 @@ impl SqliteMoreInner { // write out metadb.close().map_err(|e| { - std::io::Error::new( - std::io::ErrorKind::Other, - format!("metadb.close() failed! {}", e.1), - ) + std::io::Error::other(format!("metadb.close() failed! {}", e.1)) })?; // Save it as DB seed diff --git a/downstairs/src/lib.rs b/downstairs/src/lib.rs index d7dac4c0e..ce4b14f57 100644 --- a/downstairs/src/lib.rs +++ b/downstairs/src/lib.rs @@ -1030,8 +1030,8 @@ impl ActiveConnection { fn reply( &self, msg: Message, - ) -> Result<(), mpsc::error::SendError> { - self.data.reply_channel_tx.send(msg) + ) -> Result<(), Box>> { + self.data.reply_channel_tx.send(msg).map_err(Box::new) } async fn handle_frame( @@ -1908,8 +1908,8 @@ impl ConnectionState { fn reply( &self, msg: Message, - ) -> Result<(), mpsc::error::SendError> { - self.data().reply_channel_tx.send(msg) + ) -> Result<(), Box>> { + self.data().reply_channel_tx.send(msg).map_err(Box::new) } fn upstairs_connection(&self) -> Option { diff --git a/downstairs/src/region.rs b/downstairs/src/region.rs index cda6c19e8..90330ed49 100644 --- a/downstairs/src/region.rs +++ b/downstairs/src/region.rs @@ -2094,7 +2094,7 @@ pub(crate) mod test { /* * Build the Vec for our region dir */ - let dvec = vec![dir.into_path()]; + let dvec = vec![dir.keep()]; /* * Dump the region @@ -2121,9 +2121,9 @@ pub(crate) mod test { * Build the Vec for our region dirs */ let mut dvec = Vec::new(); - let pdir = dir.into_path(); + let pdir = dir.keep(); dvec.push(pdir); - let pdir = dir2.into_path(); + let pdir = dir2.keep(); dvec.push(pdir); /* @@ -2152,9 +2152,9 @@ pub(crate) mod test { * Build the Vec for our region dirs */ let mut dvec = Vec::new(); - let pdir = dir.into_path(); + let pdir = dir.keep(); dvec.push(pdir); - let pdir = dir2.into_path(); + let pdir = dir2.keep(); dvec.push(pdir); /* diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index 8bdb2f277..52ad084ab 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -714,6 +714,7 @@ mod integration_tests { self.downstairs3.address() } + #[cfg_attr(not(target_os = "illumos"), expect(unused))] pub fn snapshot_exists(&self, snapshot_name: &str) -> Result { Ok(self.downstairs1.snapshot_exists(snapshot_name)? && self.downstairs2.snapshot_exists(snapshot_name)? diff --git a/measure_iops/src/main.rs b/measure_iops/src/main.rs index b49b13645..d2dffdddb 100644 --- a/measure_iops/src/main.rs +++ b/measure_iops/src/main.rs @@ -93,7 +93,7 @@ async fn main() -> Result<()> { let total_blocks: u64 = guest.total_size().await? / bsz; let io_size = if let Some(io_size_in_bytes) = opt.io_size_in_bytes { - if io_size_in_bytes as u64 % bsz != 0 { + if !(io_size_in_bytes as u64).is_multiple_of(bsz) { bail!( "invalid io size: {io_size_in_bytes} is not divisible by {bsz}" ); diff --git a/openapi/crucible-control.json b/openapi/crucible-control.json index 6286a1ffc..4adcefb84 100644 --- a/openapi/crucible-control.json +++ b/openapi/crucible-control.json @@ -384,7 +384,6 @@ ] }, "NegotiationState": { - "description": "Auto-generated discriminant enum variants", "oneOf": [ { "description": "One-shot sender to ask the client to open its connection\n\nThis is used to hold the client (without connecting) in cases where we have deliberately deactivated this client.", diff --git a/pantry/src/pantry.rs b/pantry/src/pantry.rs index 2c1c8838e..04c84bc3b 100644 --- a/pantry/src/pantry.rs +++ b/pantry/src/pantry.rs @@ -352,7 +352,7 @@ impl PantryEntry { size_to_validate.unwrap_or(self.volume.total_size().await?); let block_size = self.volume.get_block_size().await?; - if (size_to_validate % block_size) != 0 { + if !size_to_validate.is_multiple_of(block_size) { crucible_bail!( InvalidNumberOfBlocks, "size to validate {} not divisible by block size {}!", @@ -588,13 +588,7 @@ impl Pantry { } pub async fn status(&self) -> Result { - let volumes = self - .entries - .lock() - .await - .iter() - .map(|(k, _)| k.clone()) - .collect(); + let volumes = self.entries.lock().await.keys().cloned().collect(); let num_job_handles = self.jobs.lock().await.total_job_handles(); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 4bd1ff459..2ce412d5a 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.86.0" +channel = "1.90.0" profile = "default" diff --git a/smf/src/instance.rs b/smf/src/instance.rs index 57f033d49..1c4d9bd7d 100644 --- a/smf/src/instance.rs +++ b/smf/src/instance.rs @@ -147,7 +147,7 @@ impl<'a> Instance<'a> { Ok((state, next_state)) } - pub fn snapshots(&self) -> Result { + pub fn snapshots(&self) -> Result> { Snapshots::new(self) } @@ -161,12 +161,12 @@ impl<'a> Instance<'a> { * `running` snapshot. May return other errors if querying for the running * snapshot fails. */ - pub fn get_running_snapshot(&self) -> Result { + pub fn get_running_snapshot(&self) -> Result> { let maybe_snapshot = self.get_snapshot("running")?; maybe_snapshot.ok_or(ScfError::NoRunningSnapshot) } - pub fn get_snapshot(&self, name: &str) -> Result> { + pub fn get_snapshot(&self, name: &str) -> Result>> { let name = CString::new(name).unwrap(); let snap = Snapshot::new(self)?; @@ -188,11 +188,11 @@ impl<'a> Instance<'a> { } } - pub fn pgs(&self) -> Result { + pub fn pgs(&self) -> Result> { PropertyGroups::new_instance(self) } - pub fn get_pg(&self, name: &str) -> Result> { + pub fn get_pg(&self, name: &str) -> Result>> { let name = CString::new(name).unwrap(); let pg = PropertyGroup::new(self.scf)?; @@ -214,7 +214,11 @@ impl<'a> Instance<'a> { } } - pub fn add_pg(&self, name: &str, pgtype: &str) -> Result { + pub fn add_pg( + &self, + name: &str, + pgtype: &str, + ) -> Result> { let name = CString::new(name).unwrap(); let pgtype = CString::new(pgtype).unwrap(); let pg = PropertyGroup::new(self.scf)?; diff --git a/smf/src/lib.rs b/smf/src/lib.rs index c7520e17c..4072762f4 100644 --- a/smf/src/lib.rs +++ b/smf/src/lib.rs @@ -157,7 +157,7 @@ impl Scf { } } - pub fn scope_local(&self) -> Result { + pub fn scope_local(&self) -> Result> { let scope = Scope::new(self)?; if unsafe { @@ -174,7 +174,7 @@ impl Scf { Ok(scope) } - pub fn scopes(&self) -> Result { + pub fn scopes(&self) -> Result> { Scopes::new(self) } diff --git a/smf/src/property.rs b/smf/src/property.rs index 8fa5f3a75..05b4f80bb 100644 --- a/smf/src/property.rs +++ b/smf/src/property.rs @@ -54,11 +54,11 @@ impl<'a> Property<'a> { * scf_property_get_value(3SCF) */ - pub fn values(&self) -> Result { + pub fn values(&self) -> Result> { Values::new(self) } - pub fn value(&self) -> Result> { + pub fn value(&self) -> Result>> { let mut values = Values::new(self)?.collect::>>()?; match values.len() { 0 => Ok(None), diff --git a/smf/src/propertygroup.rs b/smf/src/propertygroup.rs index ba0293883..fb2797087 100644 --- a/smf/src/propertygroup.rs +++ b/smf/src/propertygroup.rs @@ -54,11 +54,11 @@ impl<'a> PropertyGroup<'a> { str_from(&mut buf, ret) } - pub fn properties(&self) -> Result { + pub fn properties(&self) -> Result> { Properties::new(self) } - pub fn get_property(&self, name: &str) -> Result> { + pub fn get_property(&self, name: &str) -> Result>> { let name = CString::new(name).unwrap(); let prop = Property::new(self.scf)?; @@ -100,7 +100,7 @@ impl<'a> PropertyGroup<'a> { } } - pub fn transaction(&self) -> Result { + pub fn transaction(&self) -> Result> { let tx = Transaction::new(self)?; Ok(tx) } diff --git a/smf/src/scope.rs b/smf/src/scope.rs index f6e3e160e..325cf2b7b 100644 --- a/smf/src/scope.rs +++ b/smf/src/scope.rs @@ -39,11 +39,11 @@ impl<'a> Scope<'a> { str_from(&mut buf, ret) } - pub fn services(&self) -> Result { + pub fn services(&self) -> Result> { Services::new(self) } - pub fn get_service(&self, name: &str) -> Result> { + pub fn get_service(&self, name: &str) -> Result>> { let name = CString::new(name).unwrap(); let service = Service::new(self.scf)?; @@ -65,7 +65,7 @@ impl<'a> Scope<'a> { } } - pub fn add_service(&self, name: &str) -> Result { + pub fn add_service(&self, name: &str) -> Result> { let name = CString::new(name).unwrap(); let service = Service::new(self.scf)?; diff --git a/smf/src/service.rs b/smf/src/service.rs index 9dacb9344..c6b95c0db 100644 --- a/smf/src/service.rs +++ b/smf/src/service.rs @@ -39,11 +39,11 @@ impl<'a> Service<'a> { str_from(&mut buf, ret) } - pub fn instances(&self) -> Result { + pub fn instances(&self) -> Result> { Instances::new(self) } - pub fn pgs(&self) -> Result { + pub fn pgs(&self) -> Result> { PropertyGroups::new_service(self) } @@ -52,7 +52,7 @@ impl<'a> Service<'a> { * scf_service_delete(3SCF) */ - pub fn get_instance(&self, name: &str) -> Result> { + pub fn get_instance(&self, name: &str) -> Result>> { let name = CString::new(name).unwrap(); let instance = Instance::new(self.scf)?; @@ -74,7 +74,7 @@ impl<'a> Service<'a> { } } - pub fn add_instance(&self, name: &str) -> Result { + pub fn add_instance(&self, name: &str) -> Result> { let name = CString::new(name).unwrap(); let instance = Instance::new(self.scf)?; diff --git a/smf/src/snapshot.rs b/smf/src/snapshot.rs index 58d0331f3..4c7ac77a9 100644 --- a/smf/src/snapshot.rs +++ b/smf/src/snapshot.rs @@ -40,11 +40,11 @@ impl<'a> Snapshot<'a> { str_from(&mut buf, ret) } - pub fn pgs(&self) -> Result { + pub fn pgs(&self) -> Result> { PropertyGroups::new_composed(self.instance, self) } - pub fn get_pg(&self, name: &str) -> Result> { + pub fn get_pg(&self, name: &str) -> Result>> { let name = CString::new(name).unwrap(); let pg = PropertyGroup::new(self.instance.scf)?; diff --git a/tools/install_builder_prerequisites.sh b/tools/install_builder_prerequisites.sh new file mode 100755 index 000000000..e93338e52 --- /dev/null +++ b/tools/install_builder_prerequisites.sh @@ -0,0 +1,203 @@ +#!/usr/bin/env bash + +# This file is adapted from Omicron's install_builder_prerequisites.sh. + +set -eu + +MARKER=/etc/opt/oxide/NO_INSTALL +if [[ -f "$MARKER" ]]; then + echo "This system has the marker file $MARKER, aborting." >&2 + exit 1 +fi + +# Set the CWD to Omicron's source. +SOURCE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +cd "${SOURCE_DIR}/.." + +function on_exit +{ + echo "Something went wrong, but this script is idempotent - If you can fix the issue, try re-running" +} + +trap on_exit ERR + +function usage +{ + echo "Usage: ./install_builder_prerequisites.sh " + echo " Options: " + echo " -y: Assume 'yes' instead of showing confirmation prompts" + echo " -p: Skip checking paths" + echo " -r: Number of retries to perform for network operations (default: 3)" + exit 1 +} + +ASSUME_YES="false" +SKIP_PATH_CHECK="false" +OMIT_SUDO="false" +RETRY_ATTEMPTS=3 +while getopts ypsr: flag +do + case "${flag}" in + y) ASSUME_YES="true" ;; + p) SKIP_PATH_CHECK="true" ;; + s) OMIT_SUDO="true" ;; + r) RETRY_ATTEMPTS=${OPTARG} ;; + *) usage + esac +done + +# Offers a confirmation prompt, unless we were passed `-y`. +# +# Args: +# $1: Text to be displayed +function confirm +{ + if [[ "${ASSUME_YES}" == "true" ]]; then + response=y + else + read -r -p "$1 (y/n): " response + fi + case $response in + [yY]) + true + ;; + *) + false + ;; + esac +} + +# Function which executes all provided arguments, up to ${RETRY_ATTEMPTS} +# times, or until the command succeeds. +function retry +{ + attempts="${RETRY_ATTEMPTS}" + # Always try at least once + attempts=$((attempts < 1 ? 1 : attempts)) + for i in $(seq 1 $attempts); do + retry_rc=0 + "$@" || retry_rc=$?; + if [[ "$retry_rc" -eq 0 ]]; then + return + fi + + if [[ $i -ne $attempts ]]; then + echo "Failed to run command -- will try $((attempts - i)) more times" + fi + done + + exit $retry_rc +} + +function xtask +{ + if [ -z ${XTASK_BIN+x} ]; then + cargo xtask "$@" + else + "$XTASK_BIN" "$@" + fi +} + +HOST_OS=$(uname -s) + +function install_packages { + if [[ "${HOST_OS}" == "Linux" ]]; then + # TODO: configure a Nix flake for folks who prefer that + + packages=( + 'build-essential' + 'libclang-dev' + 'pkg-config' + ) + if [[ "${OMIT_SUDO}" == "false" ]]; then + maybe_sudo="sudo" + else + maybe_sudo="" + fi + $maybe_sudo apt-get update + if [[ "${ASSUME_YES}" == "true" ]]; then + $maybe_sudo apt-get install -y "${packages[@]}" + else + confirm "Install (or update) [${packages[*]}]?" && $maybe_sudo apt-get install "${packages[@]}" + fi + elif [[ "${HOST_OS}" == "SunOS" ]]; then + CLANGVER=15 + PGVER=13 + packages=( + "pkg:/package/pkg" + "build-essential" + "pkg-config" + # "bindgen leverages libclang to preprocess, parse, and type check C and C++ header files." + "pkg:/ooce/developer/clang-$CLANGVER" + ) + + # Install/update the set of packages. + # Explicitly manage the return code using "rc" to observe the result of this + # command without exiting the script entirely (due to bash's "errexit"). + rc=0 + confirm "Install (or update) [${packages[*]}]?" && { pfexec pkg install -v "${packages[@]}" || rc=$?; } + # Return codes: + # 0: Normal Success + # 4: Failure because we're already up-to-date. Also acceptable. + if ((rc != 4 && rc != 0)); then + exit "$rc" + fi + + confirm "Set mediators?" && { + pfexec pkg set-mediator -V $CLANGVER clang llvm + } + + pkg mediator -a + pkg publisher + pkg list -afv "${packages[@]}" + elif [[ "${HOST_OS}" == "Darwin" ]]; then + # clang is expected to be installed via the Xcode Command Line Tools. + echo "Nothing to do on macOS" + else + echo "Unsupported OS: ${HOST_OS}" + exit 1 + fi +} + +retry install_packages + +# Validate the PATH: +expected_in_path=( + 'pkg-config' +) + +function show_hint +{ + case "$1" in + "pkg-config") + if [[ "${HOST_OS}" == "SunOS" ]]; then + echo "On illumos, $1 is typically found in '/usr/bin'" + fi + ;; + *) + ;; + esac +} + +# Check all paths before returning an error, unless we were told not too. +if [[ "$SKIP_PATH_CHECK" == "true" ]]; then + echo "All prerequisites installed successfully" + exit 0 +fi + +ANY_PATH_ERROR="false" +for command in "${expected_in_path[@]}"; do + rc=0 + which "$command" &> /dev/null || rc=$? + if [[ "$rc" -ne 0 ]]; then + echo "ERROR: $command seems installed, but was not found in PATH. Please add it." + show_hint "$command" + ANY_PATH_ERROR="true" + fi +done + +if [[ "$ANY_PATH_ERROR" == "true" ]]; then + exit 1 +fi + +echo "All builder prerequisites installed successfully, and PATH looks valid" diff --git a/upstairs/src/active_jobs.rs b/upstairs/src/active_jobs.rs index bd9189b18..f876dd726 100644 --- a/upstairs/src/active_jobs.rs +++ b/upstairs/src/active_jobs.rs @@ -115,7 +115,7 @@ impl ActiveJobs { #[inline] pub fn keys( &self, - ) -> std::collections::btree_map::Keys { + ) -> std::collections::btree_map::Keys<'_, JobId, DownstairsIO> { self.jobs.keys() } diff --git a/upstairs/src/client.rs b/upstairs/src/client.rs index d2b916b9a..dac51c62b 100644 --- a/upstairs/src/client.rs +++ b/upstairs/src/client.rs @@ -1627,7 +1627,7 @@ impl DownstairsClient { .. } => { assert!(!dest_clients.is_empty()); - if dest_clients.iter().any(|d| *d == self.client_id) { + if dest_clients.contains(&self.client_id) { info!(self.log, "sending reconcile request {repair_id:?}"); self.send(job.op.clone()); } else { diff --git a/upstairs/src/downstairs.rs b/upstairs/src/downstairs.rs index 1337884b9..a50622923 100644 --- a/upstairs/src/downstairs.rs +++ b/upstairs/src/downstairs.rs @@ -611,24 +611,24 @@ impl Downstairs { ) { match work { IOop::Read { .. } => { - cdt::gw__read__done!(|| (ds_id.0)); + cdt::gw__read__done!(|| ds_id.0); stats.add_read(io_size as i64); } IOop::Write { .. } => { - cdt::gw__write__done!(|| (ds_id.0)); + cdt::gw__write__done!(|| ds_id.0); // We already updated metrics right after the fast ack. } IOop::WriteUnwritten { .. } => { - cdt::gw__write__unwritten__done!(|| (ds_id.0)); + cdt::gw__write__unwritten__done!(|| ds_id.0); // We don't include WriteUnwritten operation in the // metrics for this guest. } IOop::Flush { .. } => { - cdt::gw__flush__done!(|| (ds_id.0)); + cdt::gw__flush__done!(|| ds_id.0); stats.add_flush(); } IOop::Barrier { .. } => { - cdt::gw__barrier__done!(|| (ds_id.0)); + cdt::gw__barrier__done!(|| ds_id.0); stats.add_barrier(); } IOop::ExtentFlushClose { extent, .. } => { @@ -640,7 +640,7 @@ impl Downstairs { stats.add_extent_repair(); } IOop::ExtentLiveNoOp { .. } => { - cdt::gw__noop__done!(|| (ds_id.0)); + cdt::gw__noop__done!(|| ds_id.0); stats.add_extent_noop(); } IOop::ExtentLiveReopen { extent, .. } => { @@ -1239,7 +1239,7 @@ impl Downstairs { let flush_id = self.submit_flush(None, None, None); info!(self.log, "LiveRepair final flush submitted"); - cdt::up__to__ds__flush__start!(|| (flush_id.0)); + cdt::up__to__ds__flush__start!(|| flush_id.0); // The borrow was dropped earlier, so reborrow `self.repair` self.repair.as_mut().unwrap().state = @@ -1278,7 +1278,7 @@ impl Downstairs { fn create_and_enqueue_noop_io(&mut self, deps: Vec, noop_id: JobId) { let nio = IOop::ExtentLiveNoOp { dependencies: deps }; - cdt::gw__noop__start!(|| (noop_id.0)); + cdt::gw__noop__start!(|| noop_id.0); self.enqueue(noop_id, nio, None, None) } @@ -1559,9 +1559,9 @@ impl Downstairs { ) -> JobId { let ds_id = self.next_id(); if is_write_unwritten { - cdt::gw__write__unwritten__start!(|| (ds_id.0)); + cdt::gw__write__unwritten__start!(|| ds_id.0); } else { - cdt::gw__write__start!(|| (ds_id.0)); + cdt::gw__write__start!(|| ds_id.0); } let dependencies = self.ds_active.deps_for_write(ds_id, blocks); @@ -1988,7 +1988,7 @@ impl Downstairs { io_guard: Option, ) -> JobId { let next_id = self.next_id(); - cdt::gw__flush__start!(|| (next_id.0)); + cdt::gw__flush__start!(|| next_id.0); let flush_id = self.next_flush_id(); let dep = self.ds_active.deps_for_flush(next_id); @@ -2062,7 +2062,7 @@ impl Downstairs { pub(crate) fn submit_barrier(&mut self) -> JobId { let next_id = self.next_id(); - cdt::gw__barrier__start!(|| (next_id.0)); + cdt::gw__barrier__start!(|| next_id.0); // A barrier has the same deps as a flush (namely, it depends on all // previous jobs and acts as the only dependency for all subsequent diff --git a/upstairs/src/dummy_downstairs_tests.rs b/upstairs/src/dummy_downstairs_tests.rs index a6bc18f35..0e9904fcc 100644 --- a/upstairs/src/dummy_downstairs_tests.rs +++ b/upstairs/src/dummy_downstairs_tests.rs @@ -133,8 +133,8 @@ impl DownstairsHandle { fn send( &mut self, m: Message, - ) -> Result<(), mpsc::error::SendError> { - self.tx.send(m) + ) -> Result<(), Box>> { + self.tx.send(m).map_err(Box::new) } pub async fn negotiate_start(&mut self) { diff --git a/upstairs/src/notify.rs b/upstairs/src/notify.rs index 3d187feb3..039b1c8da 100644 --- a/upstairs/src/notify.rs +++ b/upstairs/src/notify.rs @@ -275,7 +275,9 @@ async fn notify_task_nexus( .iter() .map(|(region_uuid, target_addr)| { DownstairsUnderRepair { - region_uuid: (*region_uuid).into(), + region_uuid: TypedUuid::from_untyped_uuid( + *region_uuid, + ), target_addr: target_addr.to_string(), } }) @@ -355,7 +357,9 @@ async fn notify_task_nexus( .iter() .map(|(region_uuid, target_addr)| { DownstairsUnderRepair { - region_uuid: (*region_uuid).into(), + region_uuid: TypedUuid::from_untyped_uuid( + *region_uuid, + ), target_addr: target_addr.to_string(), } }) diff --git a/upstairs/src/pseudo_file.rs b/upstairs/src/pseudo_file.rs index 979d332e0..2b7f9c564 100644 --- a/upstairs/src/pseudo_file.rs +++ b/upstairs/src/pseudo_file.rs @@ -244,10 +244,7 @@ impl CruciblePseudoFile { impl Read for CruciblePseudoFile { fn read(&mut self, buf: &mut [u8]) -> IOResult { if !self.active { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - CrucibleError::UpstairsInactive, - )); + return Err(std::io::Error::other(CrucibleError::UpstairsInactive)); } tokio::task::block_in_place(|| { @@ -260,10 +257,7 @@ impl Read for CruciblePseudoFile { impl Write for CruciblePseudoFile { fn write(&mut self, buf: &[u8]) -> IOResult { if !self.active { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - CrucibleError::UpstairsInactive, - )); + return Err(std::io::Error::other(CrucibleError::UpstairsInactive)); } tokio::task::block_in_place(|| { @@ -274,10 +268,7 @@ impl Write for CruciblePseudoFile { fn flush(&mut self) -> IOResult<()> { if !self.active { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - CrucibleError::UpstairsInactive, - )); + return Err(std::io::Error::other(CrucibleError::UpstairsInactive)); } tokio::task::block_in_place(|| { @@ -306,10 +297,7 @@ impl Seek for CruciblePseudoFile { } if offset < 0 { - Err(std::io::Error::new( - std::io::ErrorKind::Other, - "offset is negative!", - )) + Err(std::io::Error::other("offset is negative!")) } else { // offset >= 0 self.offset = offset as u64; diff --git a/upstairs/src/upstairs.rs b/upstairs/src/upstairs.rs index be29041c7..e2d715ffd 100644 --- a/upstairs/src/upstairs.rs +++ b/upstairs/src/upstairs.rs @@ -470,7 +470,7 @@ impl Upstairs { while !self.done() { let action = self.select().await; self.counters.apply += 1; - cdt::up__apply!(|| (self.counters.apply)); + cdt::up__apply!(|| self.counters.apply); self.apply(action) } } @@ -546,14 +546,12 @@ impl Upstairs { match action { UpstairsAction::Downstairs(d) => { self.counters.action_downstairs += 1; - cdt::up__action_downstairs!(|| (self - .counters - .action_downstairs)); + cdt::up__action_downstairs!(|| self.counters.action_downstairs); self.apply_downstairs_action(d) } UpstairsAction::Guest(b) => { self.counters.action_guest += 1; - cdt::up__action_guest!(|| (self.counters.action_guest)); + cdt::up__action_guest!(|| self.counters.action_guest); self.defer_guest_request(b); } UpstairsAction::GuestDropped => { @@ -561,24 +559,24 @@ impl Upstairs { } UpstairsAction::DeferredBlockOp(req) => { self.counters.action_deferred_block += 1; - cdt::up__action_deferred_block!(|| (self + cdt::up__action_deferred_block!(|| self .counters - .action_deferred_block)); + .action_deferred_block); self.apply_guest_request(req); } UpstairsAction::DeferredMessage(m) => { self.counters.action_deferred_message += 1; - cdt::up__action_deferred_message!(|| (self + cdt::up__action_deferred_message!(|| self .counters - .action_deferred_message)); + .action_deferred_message); self.on_client_message(m); } UpstairsAction::FlushCheck => { if !has_jobs { self.counters.action_flush_check += 1; - cdt::up__action_flush_check!(|| (self + cdt::up__action_flush_check!(|| self .counters - .action_flush_check)); + .action_flush_check); if self.need_flush { let io_guard = self.try_acquire_io(0); self.submit_flush(None, None, io_guard); @@ -599,22 +597,20 @@ impl Upstairs { } UpstairsAction::StatUpdate => { self.counters.action_stat_check += 1; - cdt::up__action_stat_check!(|| (self - .counters - .action_stat_check)); + cdt::up__action_stat_check!(|| self.counters.action_stat_check); self.on_stat_update(); self.stat_deadline = Instant::now() + STAT_INTERVAL; } UpstairsAction::Control(c) => { self.counters.action_control_check += 1; - cdt::up__action_control_check!(|| (self + cdt::up__action_control_check!(|| self .counters - .action_control_check)); + .action_control_check); self.on_control_req(c); } UpstairsAction::NoOp => { self.counters.action_noop += 1; - cdt::up__action_noop!(|| (self.counters.action_noop)); + cdt::up__action_noop!(|| self.counters.action_noop); } } @@ -1331,7 +1327,7 @@ impl Upstairs { self.downstairs .submit_flush(snapshot_details, res, io_guard); - cdt::up__to__ds__flush__start!(|| (ds_id.0)); + cdt::up__to__ds__flush__start!(|| ds_id.0); } fn submit_barrier(&mut self) { @@ -1341,7 +1337,7 @@ impl Upstairs { // call it! let ds_id = self.downstairs.submit_barrier(); - cdt::up__to__ds__barrier__start!(|| (ds_id.0)); + cdt::up__to__ds__barrier__start!(|| ds_id.0); } /// Submits a read job to the downstairs @@ -1415,7 +1411,7 @@ impl Upstairs { self.downstairs .submit_read(impacted_blocks, data, res, io_guard); - cdt::up__to__ds__read__start!(|| (ds_id.0)); + cdt::up__to__ds__read__start!(|| ds_id.0); } /// Submits a dummy write (without an associated `BlockOp`) @@ -1558,9 +1554,9 @@ impl Upstairs { ); if write.is_write_unwritten { - cdt::up__to__ds__write__unwritten__start!(|| (ds_id.0)); + cdt::up__to__ds__write__unwritten__start!(|| ds_id.0); } else { - cdt::up__to__ds__write__start!(|| (ds_id.0)); + cdt::up__to__ds__write__start!(|| ds_id.0); } } diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index a32a2ff89..87f95aefe 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -15,13 +15,17 @@ publish = false ### BEGIN HAKARI SECTION [dependencies] +aho-corasick = { version = "1" } arrayvec = { version = "0.7", default-features = false, features = ["std"] } +aws-lc-rs = { version = "1", features = ["prebuilt-nasm"] } +aws-lc-sys = { version = "0.30", default-features = false, features = ["prebuilt-nasm"] } bitflags = { version = "2", default-features = false, features = ["serde"] } bstr = { version = "1" } bytes = { version = "1", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] } clap = { version = "4", features = ["cargo", "derive", "env", "wrap_help"] } clap_builder = { version = "4", default-features = false, features = ["cargo", "color", "env", "std", "suggestions", "usage", "wrap_help"] } +crossbeam-epoch = { version = "0.9" } crossbeam-utils = { version = "0.8" } crypto-common = { version = "0.1", default-features = false, features = ["getrandom", "std"] } digest = { version = "0.10", features = ["mac", "std"] } @@ -42,17 +46,21 @@ memchr = { version = "2" } num-integer = { version = "0.1", default-features = false, features = ["i128", "std"] } num-iter = { version = "0.1", default-features = false, features = ["i128", "std"] } num-traits = { version = "0.2", features = ["i128", "libm"] } -once_cell = { version = "1" } +once_cell = { version = "1", features = ["critical-section"] } openapiv3 = { version = "2", default-features = false, features = ["skip_serializing_defaults"] } percent-encoding = { version = "2" } phf_shared = { version = "0.11" } +portable-atomic = { version = "1" } rand = { version = "0.8", features = ["small_rng"] } rand_chacha = { version = "0.9" } rand_core = { version = "0.9", default-features = false, features = ["os_rng", "std"] } -regex-automata = { version = "0.4", default-features = false, features = ["dfa-onepass", "dfa-search", "hybrid", "meta", "nfa-backtrack", "perf-inline", "perf-literal", "std", "unicode"] } +regex-automata = { version = "0.4", default-features = false, features = ["dfa-onepass", "dfa-search", "hybrid", "meta", "nfa", "perf", "std", "unicode"] } regex-syntax = { version = "0.8" } reqwest = { version = "0.12", features = ["blocking", "json", "rustls-tls", "stream"] } -schemars = { version = "0.8", features = ["bytes", "chrono", "semver", "uuid1"] } +ring = { version = "0.17" } +rustls-pki-types = { version = "1", features = ["std"] } +rustls-webpki = { version = "0.102", default-features = false, features = ["aws_lc_rs", "ring", "std"] } +schemars = { version = "0.8", features = ["bytes", "chrono", "semver", "url", "uuid1"] } scopeguard = { version = "1" } semver = { version = "1", features = ["serde"] } serde = { version = "1", features = ["alloc", "derive", "rc"] } @@ -64,15 +72,20 @@ smallvec = { version = "1", default-features = false, features = ["const_new"] } syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] } time = { version = "0.3", features = ["formatting", "local-offset", "macros", "parsing"] } tokio = { version = "1", features = ["full", "test-util"] } +tokio-util = { version = "0.7", features = ["codec", "io-util", "time"] } toml_datetime = { version = "0.6", default-features = false, features = ["serde"] } tracing = { version = "0.1" } tracing-core = { version = "0.1" } +url = { version = "2", features = ["serde"] } usdt = { version = "0.5" } usdt-impl = { version = "0.5", default-features = false, features = ["asm", "des"] } uuid = { version = "1", features = ["serde", "v4"] } winnow = { version = "0.7" } [build-dependencies] +aho-corasick = { version = "1" } +aws-lc-rs = { version = "1", features = ["prebuilt-nasm"] } +aws-lc-sys = { version = "0.30", default-features = false, features = ["prebuilt-nasm"] } bitflags = { version = "2", default-features = false, features = ["serde"] } bytes = { version = "1", features = ["serde"] } cc = { version = "1", default-features = false, features = ["parallel"] } @@ -99,15 +112,21 @@ memchr = { version = "2" } num-integer = { version = "0.1", default-features = false, features = ["i128", "std"] } num-iter = { version = "0.1", default-features = false, features = ["i128", "std"] } num-traits = { version = "0.2", features = ["i128", "libm"] } -once_cell = { version = "1" } +once_cell = { version = "1", features = ["critical-section"] } openapiv3 = { version = "2", default-features = false, features = ["skip_serializing_defaults"] } percent-encoding = { version = "2" } phf_shared = { version = "0.11" } +portable-atomic = { version = "1" } rand = { version = "0.8", features = ["small_rng"] } -regex-automata = { version = "0.4", default-features = false, features = ["dfa-onepass", "dfa-search", "hybrid", "meta", "nfa-backtrack", "perf-inline", "perf-literal", "std", "unicode"] } +rand_chacha = { version = "0.9" } +rand_core = { version = "0.9", default-features = false, features = ["os_rng", "std"] } +regex-automata = { version = "0.4", default-features = false, features = ["dfa-onepass", "dfa-search", "hybrid", "meta", "nfa", "perf", "std", "unicode"] } regex-syntax = { version = "0.8" } reqwest = { version = "0.12", features = ["blocking", "json", "rustls-tls", "stream"] } -schemars = { version = "0.8", features = ["bytes", "chrono", "semver", "uuid1"] } +ring = { version = "0.17" } +rustls-pki-types = { version = "1", features = ["std"] } +rustls-webpki = { version = "0.102", default-features = false, features = ["aws_lc_rs", "ring", "std"] } +schemars = { version = "0.8", features = ["bytes", "chrono", "semver", "url", "uuid1"] } scopeguard = { version = "1" } semver = { version = "1", features = ["serde"] } serde = { version = "1", features = ["alloc", "derive", "rc"] } @@ -119,9 +138,11 @@ syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "vis time = { version = "0.3", features = ["formatting", "local-offset", "macros", "parsing"] } time-macros = { version = "0.2", default-features = false, features = ["formatting", "parsing"] } tokio = { version = "1", features = ["full", "test-util"] } +tokio-util = { version = "0.7", features = ["codec", "io-util", "time"] } toml_datetime = { version = "0.6", default-features = false, features = ["serde"] } tracing = { version = "0.1" } tracing-core = { version = "0.1" } +url = { version = "2", features = ["serde"] } usdt = { version = "0.5" } usdt-impl = { version = "0.5", default-features = false, features = ["asm", "des"] } uuid = { version = "1", features = ["serde", "v4"] } @@ -134,12 +155,12 @@ getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-f hyper = { version = "1", features = ["full"] } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", features = ["full"] } +linux-raw-sys = { version = "0.4", default-features = false, features = ["elf", "errno", "general", "ioctl", "no_std", "system"] } mio = { version = "1", features = ["net", "os-ext"] } nix = { version = "0.29", features = ["feature", "fs", "term", "uio"] } -rustix = { version = "0.38", features = ["fs", "stdio", "termios"] } -rustls-pki-types = { version = "1", features = ["std"] } +rustix = { version = "0.38", features = ["fs", "stdio", "system", "termios"] } +rustls = { version = "0.23", features = ["ring"] } spin = { version = "0.9", default-features = false, features = ["once", "spin_mutex"] } -tokio-util = { version = "0.7", features = ["codec", "io"] } [target.x86_64-unknown-linux-gnu.build-dependencies] bitflags = { version = "2", default-features = false, features = ["std"] } @@ -148,11 +169,11 @@ getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-f hyper = { version = "1", features = ["full"] } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", features = ["full"] } +linux-raw-sys = { version = "0.4", default-features = false, features = ["elf", "errno", "general", "ioctl", "no_std", "system"] } mio = { version = "1", features = ["net", "os-ext"] } -rustix = { version = "0.38", features = ["fs", "stdio", "termios"] } -rustls-pki-types = { version = "1", features = ["std"] } +rustix = { version = "0.38", features = ["fs", "stdio", "system", "termios"] } +rustls = { version = "0.23", features = ["ring"] } spin = { version = "0.9", default-features = false, features = ["once", "spin_mutex"] } -tokio-util = { version = "0.7", features = ["codec", "io"] } [target.aarch64-apple-darwin.dependencies] bitflags = { version = "2", default-features = false, features = ["std"] } @@ -162,9 +183,8 @@ hyper-rustls = { version = "0.27", default-features = false, features = ["http1" hyper-util = { version = "0.1", features = ["full"] } mio = { version = "1", features = ["net", "os-ext"] } nix = { version = "0.29", features = ["feature", "fs", "term", "uio"] } -rustix = { version = "0.38", features = ["fs", "stdio", "termios"] } -rustls-pki-types = { version = "1", features = ["std"] } -tokio-util = { version = "0.7", features = ["codec", "io"] } +rustix = { version = "0.38", features = ["fs", "stdio", "system", "termios"] } +rustls = { version = "0.23", features = ["ring"] } [target.aarch64-apple-darwin.build-dependencies] bitflags = { version = "2", default-features = false, features = ["std"] } @@ -173,9 +193,8 @@ hyper = { version = "1", features = ["full"] } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", features = ["full"] } mio = { version = "1", features = ["net", "os-ext"] } -rustix = { version = "0.38", features = ["fs", "stdio", "termios"] } -rustls-pki-types = { version = "1", features = ["std"] } -tokio-util = { version = "0.7", features = ["codec", "io"] } +rustix = { version = "0.38", features = ["fs", "stdio", "system", "termios"] } +rustls = { version = "0.23", features = ["ring"] } [target.x86_64-unknown-illumos.dependencies] bitflags = { version = "2", default-features = false, features = ["std"] } @@ -186,11 +205,11 @@ hyper-rustls = { version = "0.27", default-features = false, features = ["http1" hyper-util = { version = "0.1", features = ["full"] } mio = { version = "1", features = ["net", "os-ext"] } nix = { version = "0.29", features = ["feature", "fs", "term", "uio"] } -rustix = { version = "0.38", features = ["fs", "stdio", "termios"] } -rustls-pki-types = { version = "1", features = ["std"] } +nom = { version = "7" } +regex = { version = "1" } +rustix = { version = "0.38", features = ["fs", "stdio", "system", "termios"] } +rustls = { version = "0.23", features = ["ring"] } spin = { version = "0.9", default-features = false, features = ["once", "spin_mutex"] } -tokio-util = { version = "0.7", features = ["codec", "io"] } -toml_edit = { version = "0.19", features = ["serde"] } [target.x86_64-unknown-illumos.build-dependencies] bitflags = { version = "2", default-features = false, features = ["std"] } @@ -200,10 +219,10 @@ hyper = { version = "1", features = ["full"] } hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "ring", "tls12", "webpki-tokio"] } hyper-util = { version = "0.1", features = ["full"] } mio = { version = "1", features = ["net", "os-ext"] } -rustix = { version = "0.38", features = ["fs", "stdio", "termios"] } -rustls-pki-types = { version = "1", features = ["std"] } +nom = { version = "7" } +regex = { version = "1" } +rustix = { version = "0.38", features = ["fs", "stdio", "system", "termios"] } +rustls = { version = "0.23", features = ["ring"] } spin = { version = "0.9", default-features = false, features = ["once", "spin_mutex"] } -tokio-util = { version = "0.7", features = ["codec", "io"] } -toml_edit = { version = "0.19", features = ["serde"] } ### END HAKARI SECTION diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 0063a60b0..7c659e53c 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -22,7 +22,7 @@ enum XtaskCommands { Openapi(external::External), } -#[expect( +#[allow( clippy::disallowed_macros, reason = "using `#[tokio::main]` in xtasks is fine, as they are not \ deployed in production"