difftreelog
feat remowt integration
46 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,15 +3,6 @@
version = 4
[[package]]
-name = "abort-on-drop"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5dd6d700ad9af641490c1f7d67980d2de4d1433016e5b12f819448d3c832142a"
-dependencies = [
- "tokio",
-]
-
-[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -23,54 +14,91 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [
- "crypto-common",
- "generic-array",
+ "crypto-common 0.1.7",
+ "generic-array 0.14.7",
]
[[package]]
+name = "aead"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef60ac202874e574ce7a7158cc8bca7313dd344322482e4fadee288bf4a306b8"
+dependencies = [
+ "crypto-common 0.2.2",
+ "inout 0.2.2",
+]
+
+[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
- "cipher",
+ "cipher 0.4.4",
"cpufeatures 0.2.17",
]
[[package]]
+name = "aes"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1fc76eaeac4c9164506c466d4ffdd8ec9d0c5bf57ee97177c4d8eceb3a0e138"
+dependencies = [
+ "cipher 0.5.2",
+ "cpubits",
+ "cpufeatures 0.3.0",
+ "zeroize",
+]
+
+[[package]]
name = "aes-gcm"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
dependencies = [
- "aead",
- "aes",
- "cipher",
- "ctr",
- "ghash",
+ "aead 0.5.2",
+ "aes 0.8.4",
+ "cipher 0.4.4",
+ "ctr 0.9.2",
+ "ghash 0.5.1",
"subtle",
]
[[package]]
+name = "aes-gcm"
+version = "0.11.0-rc.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da8c919c118108f144adecad74b425b804ad075580d605d9b33c2d6d1c62a2f8"
+dependencies = [
+ "aead 0.6.0",
+ "aes 0.9.1",
+ "cipher 0.5.2",
+ "ctr 0.10.1",
+ "ghash 0.6.0",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
name = "age"
-version = "0.11.2"
+version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf640be7658959746f1f0f2faab798f6098a9436a8e18e148d18bc9875e13c4b"
+checksum = "a07d86e4272c093c88caf7864a2d09af52a5159180848ca4832a3cdbd7d014d5"
dependencies = [
- "aes",
- "aes-gcm",
+ "aes 0.8.4",
+ "aes-gcm 0.10.3",
"age-core",
"base64 0.21.7",
- "bcrypt-pbkdf",
+ "bcrypt-pbkdf 0.10.0",
"bech32",
- "cbc",
+ "cbc 0.1.2",
"chacha20poly1305",
- "cipher",
+ "cipher 0.4.4",
"cookie-factory",
- "ctr",
- "curve25519-dalek",
- "hmac",
+ "ctr 0.9.2",
+ "curve25519-dalek 4.1.3",
+ "hmac 0.12.1",
"i18n-embed",
"i18n-embed-fl",
"lazy_static",
@@ -78,10 +106,10 @@
"num-traits",
"pin-project",
"rand 0.8.6",
- "rsa",
+ "rsa 0.9.10",
"rust-embed",
- "scrypt",
- "sha2",
+ "scrypt 0.11.0",
+ "sha2 0.10.9",
"subtle",
"which",
"wsl",
@@ -98,12 +126,12 @@
"base64 0.21.7",
"chacha20poly1305",
"cookie-factory",
- "hkdf",
+ "hkdf 0.12.4",
"io_tee",
"nom 7.1.3",
"rand 0.8.6",
"secrecy",
- "sha2",
+ "sha2 0.10.9",
"tempfile",
]
@@ -191,34 +219,144 @@
]
[[package]]
+name = "argon2"
+version = "0.6.0-rc.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7af50940b73bf4e16c15c448a2b121c63f2d68e3e54b6a8731673cb4aa0cdff5"
+dependencies = [
+ "base64ct",
+ "blake2",
+ "cpufeatures 0.3.0",
+ "password-hash",
+]
+
+[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
-name = "async-stream"
-version = "0.3.6"
+name = "async-broadcast"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
+dependencies = [
+ "event-listener",
+ "event-listener-strategy",
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-channel"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
+checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
dependencies = [
- "async-stream-impl",
+ "concurrent-queue",
+ "event-listener-strategy",
"futures-core",
"pin-project-lite",
]
[[package]]
-name = "async-stream-impl"
-version = "0.3.6"
+name = "async-executor"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a"
+dependencies = [
+ "async-task",
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "pin-project-lite",
+ "slab",
+]
+
+[[package]]
+name = "async-io"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "concurrent-queue",
+ "futures-io",
+ "futures-lite",
+ "parking",
+ "polling",
+ "rustix 1.1.4",
+ "slab",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "async-lock"
+version = "3.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
+dependencies = [
+ "event-listener",
+ "event-listener-strategy",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-process"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
+dependencies = [
+ "async-channel",
+ "async-io",
+ "async-lock",
+ "async-signal",
+ "async-task",
+ "blocking",
+ "cfg-if",
+ "event-listener",
+ "futures-lite",
+ "rustix 1.1.4",
+]
+
+[[package]]
+name = "async-recursion"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
+checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "async-signal"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485"
+dependencies = [
+ "async-io",
+ "async-lock",
+ "atomic-waker",
+ "cfg-if",
+ "futures-core",
+ "futures-io",
+ "rustix 1.1.4",
+ "signal-hook-registry",
+ "slab",
+ "windows-sys 0.61.2",
]
[[package]]
+name = "async-task"
+version = "4.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
+
+[[package]]
name = "async-trait"
version = "0.1.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -226,10 +364,19 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
+name = "async_fn_traits"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc58d489c5f2d2c5be31b9004cec7af25a70d23df4d8111715eee736234cf217"
+dependencies = [
+ "paste",
+]
+
+[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -237,56 +384,15 @@
[[package]]
name = "autocfg"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
-
-[[package]]
-name = "axum"
-version = "0.7.9"
+version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
-dependencies = [
- "async-trait",
- "axum-core",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "http-body-util",
- "itoa",
- "matchit",
- "memchr",
- "mime",
- "percent-encoding",
- "pin-project-lite",
- "rustversion",
- "serde",
- "sync_wrapper",
- "tower 0.5.3",
- "tower-layer",
- "tower-service",
-]
+checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
-name = "axum-core"
-version = "0.4.5"
+name = "base16ct"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
-dependencies = [
- "async-trait",
- "bytes",
- "futures-util",
- "http",
- "http-body",
- "http-body-util",
- "mime",
- "pin-project-lite",
- "rustversion",
- "sync_wrapper",
- "tower-layer",
- "tower-service",
-]
+checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6"
[[package]]
name = "base64"
@@ -321,9 +427,20 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2"
dependencies = [
- "blowfish",
- "pbkdf2",
- "sha2",
+ "blowfish 0.9.1",
+ "pbkdf2 0.12.2",
+ "sha2 0.10.9",
+]
+
+[[package]]
+name = "bcrypt-pbkdf"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "144e573728da132683b9488acd528274c790e07fc06ff81ee29f9d8f8b1041e0"
+dependencies = [
+ "blowfish 0.10.0",
+ "pbkdf2 0.13.0",
+ "sha2 0.11.0",
]
[[package]]
@@ -333,14 +450,45 @@
checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445"
[[package]]
-name = "better-command"
-version = "0.1.0"
+name = "bifrostlink"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2fb01af731c11dd31b23783a83a36a29f644cc1972481f6fa4f4fabc709079eb"
dependencies = [
- "regex",
+ "async-trait",
+ "async_fn_traits",
+ "bifrostlink-macros",
+ "bytes",
+ "derivative",
+ "futures",
"serde",
"serde_json",
+ "tokio",
+ "tracing",
+ "uuid",
+]
+
+[[package]]
+name = "bifrostlink-macros"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c4b7a5fb38b36bd81910c17ebf369f9296e508d92b1277a768a63c8a2254fdb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "bifrostlink-ports"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "977acfcb8ed3c24ab7c2f76fb3eeebff1533c72708733ce6020f2501980b7cf2"
+dependencies = [
+ "bifrostlink",
+ "bytes",
+ "tokio",
"tracing",
- "tracing-indicatif",
]
[[package]]
@@ -359,15 +507,24 @@
"quote",
"regex",
"rustc-hash 2.1.2",
- "shlex",
- "syn",
+ "shlex 1.3.0",
+ "syn 2.0.117",
]
[[package]]
name = "bitflags"
-version = "2.11.1"
+version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
+checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
+
+[[package]]
+name = "blake2"
+version = "0.11.0-rc.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "061f1a09225e328e1ffbb378d2d49923c0ca5fee19fb5ac1cc9c1e9d52b93690"
+dependencies = [
+ "digest 0.11.3",
+]
[[package]]
name = "block-buffer"
@@ -375,33 +532,85 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
- "generic-array",
+ "generic-array 0.14.7",
]
[[package]]
+name = "block-buffer"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa"
+dependencies = [
+ "hybrid-array",
+ "zeroize",
+]
+
+[[package]]
name = "block-padding"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93"
dependencies = [
- "generic-array",
+ "generic-array 0.14.7",
]
[[package]]
+name = "block-padding"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "710f1dd022ef4e93f8a438b4ba958de7f64308434fa6a87104481645cc30068b"
+dependencies = [
+ "hybrid-array",
+]
+
+[[package]]
+name = "blocking"
+version = "1.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
+dependencies = [
+ "async-channel",
+ "async-task",
+ "futures-io",
+ "futures-lite",
+ "piper",
+]
+
+[[package]]
name = "blowfish"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7"
dependencies = [
"byteorder",
- "cipher",
+ "cipher 0.4.4",
+]
+
+[[package]]
+name = "blowfish"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62ce3946557b35e71d1bbe07ec385073ce9eda05043f95de134eb578fcf1a298"
+dependencies = [
+ "byteorder",
+ "cipher 0.5.2",
+]
+
+[[package]]
+name = "bstr"
+version = "1.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
+dependencies = [
+ "memchr",
+ "serde",
]
[[package]]
name = "bumpalo"
-version = "3.20.2"
+version = "3.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
+checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]]
name = "bytecount"
@@ -422,22 +631,40 @@
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]]
+name = "camino"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48"
+dependencies = [
+ "serde_core",
+]
+
+[[package]]
name = "cbc"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6"
dependencies = [
- "cipher",
+ "cipher 0.4.4",
]
[[package]]
+name = "cbc"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce2dc9ee5f88d11e0beb842c88b33c8a5cf0d1329c4b19494af42b07dbfe8896"
+dependencies = [
+ "cipher 0.5.2",
+]
+
+[[package]]
name = "cc"
-version = "1.2.60"
+version = "1.2.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
+checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f"
dependencies = [
"find-msvc-tools",
- "shlex",
+ "shlex 2.0.1",
]
[[package]]
@@ -468,7 +695,7 @@
checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
dependencies = [
"cfg-if",
- "cipher",
+ "cipher 0.4.4",
"cpufeatures 0.2.17",
]
@@ -479,8 +706,10 @@
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
dependencies = [
"cfg-if",
+ "cipher 0.5.2",
"cpufeatures 0.3.0",
"rand_core 0.10.1",
+ "zeroize",
]
[[package]]
@@ -489,18 +718,18 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
dependencies = [
- "aead",
+ "aead 0.5.2",
"chacha20 0.9.1",
- "cipher",
- "poly1305",
+ "cipher 0.4.4",
+ "poly1305 0.8.0",
"zeroize",
]
[[package]]
name = "chrono"
-version = "0.4.44"
+version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
+checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
dependencies = [
"iana-time-zone",
"js-sys",
@@ -516,8 +745,20 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
- "crypto-common",
- "inout",
+ "crypto-common 0.1.7",
+ "inout 0.1.4",
+ "zeroize",
+]
+
+[[package]]
+name = "cipher"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c"
+dependencies = [
+ "block-buffer 0.12.1",
+ "crypto-common 0.2.2",
+ "inout 0.2.2",
"zeroize",
]
@@ -559,9 +800,9 @@
[[package]]
name = "clap_complete"
-version = "4.6.2"
+version = "4.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ff7a1dccbdd8b078c2bdebff47e404615151534d5043da397ec50286816f9cb"
+checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772"
dependencies = [
"clap",
]
@@ -575,7 +816,7 @@
"heck",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -585,6 +826,12 @@
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
+name = "cmov"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a"
+
+[[package]]
name = "codespan-reporting"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -602,6 +849,15 @@
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
+name = "concurrent-queue"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
name = "console"
version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -615,9 +871,9 @@
[[package]]
name = "const-hex"
-version = "1.18.1"
+version = "1.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "531185e432bb31db1ecda541e9e7ab21468d4d844ad7505e0546a49b4945d49b"
+checksum = "33e2a781ebdf4467d1428dc4593067825fb646f6871475098d8577421af73558"
dependencies = [
"cfg-if",
"cpufeatures 0.2.17",
@@ -632,6 +888,12 @@
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
+name = "const-oid"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
+
+[[package]]
name = "cookie-factory"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -657,6 +919,12 @@
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
+name = "cpubits"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae"
+
+[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -684,23 +952,86 @@
]
[[package]]
+name = "crossbeam-utils"
+version = "0.8.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
+
+[[package]]
+name = "crypto-bigint"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42a0d26b245348befa0c121944541476763dcc46ede886c88f9d12e1697d27c3"
+dependencies = [
+ "cpubits",
+ "ctutils",
+ "getrandom 0.4.2",
+ "hybrid-array",
+ "num-traits",
+ "rand_core 0.10.1",
+ "serdect",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
- "generic-array",
+ "generic-array 0.14.7",
"rand_core 0.6.4",
"typenum",
]
[[package]]
+name = "crypto-common"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
+dependencies = [
+ "getrandom 0.4.2",
+ "hybrid-array",
+ "rand_core 0.10.1",
+]
+
+[[package]]
+name = "crypto-primes"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3633a51a39c69ebbaa4feaa694bd83d241e4093901c84a0963b19d9bb3f0cf8f"
+dependencies = [
+ "crypto-bigint",
+ "rand_core 0.10.1",
+]
+
+[[package]]
name = "ctr"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
dependencies = [
- "cipher",
+ "cipher 0.4.4",
+]
+
+[[package]]
+name = "ctr"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baaca1c4b237092596f64d571e9db6ce4109c4ef9742e27590f1709594461f21"
+dependencies = [
+ "cipher 0.5.2",
+]
+
+[[package]]
+name = "ctutils"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e"
+dependencies = [
+ "cmov",
+ "subtle",
]
[[package]]
@@ -718,14 +1049,30 @@
"cfg-if",
"cpufeatures 0.2.17",
"curve25519-dalek-derive",
- "digest",
- "fiat-crypto",
+ "digest 0.10.7",
+ "fiat-crypto 0.2.9",
"rustc_version",
"subtle",
"zeroize",
]
[[package]]
+name = "curve25519-dalek"
+version = "5.0.0-rc.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f359e08ca85e7bd759e1fd933ff2bccd81864c60a8fba0e259c7f822b0924bf"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.3.0",
+ "curve25519-dalek-derive",
+ "digest 0.11.3",
+ "fiat-crypto 0.3.0",
+ "rustc_version",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
name = "curve25519-dalek-derive"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -733,7 +1080,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -759,11 +1106,11 @@
dependencies = [
"cc",
"codespan-reporting",
- "indexmap 2.14.0",
+ "indexmap",
"proc-macro2",
"quote",
"scratch",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -774,10 +1121,10 @@
dependencies = [
"clap",
"codespan-reporting",
- "indexmap 2.14.0",
+ "indexmap",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -792,10 +1139,27 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6acc6b5822b9526adfb4fc377b67128fdd60aac757cc4a741a6278603f763cf"
dependencies = [
- "indexmap 2.14.0",
+ "indexmap",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "data-encoding"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8"
+
+[[package]]
+name = "delegate"
+version = "0.13.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "780eb241654bf097afb00fc5f054a09b687dad862e485fdcf8399bb056565370"
+dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -804,7 +1168,18 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [
- "const-oid",
+ "const-oid 0.9.6",
+ "zeroize",
+]
+
+[[package]]
+name = "der"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b"
+dependencies = [
+ "const-oid 0.10.2",
+ "pem-rfc7468",
"zeroize",
]
@@ -813,9 +1188,25 @@
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
+
+[[package]]
+name = "derivative"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "des"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "916a94e407b54f9034d71dd748234cd1e516ced6284009906ae246f177eafe5a"
dependencies = [
- "powerfmt",
- "serde_core",
+ "cipher 0.5.2",
]
[[package]]
@@ -824,21 +1215,48 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
- "block-buffer",
- "const-oid",
- "crypto-common",
+ "block-buffer 0.10.4",
+ "const-oid 0.9.6",
+ "crypto-common 0.1.7",
"subtle",
]
[[package]]
+name = "digest"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
+dependencies = [
+ "block-buffer 0.12.1",
+ "const-oid 0.10.2",
+ "crypto-common 0.2.2",
+ "ctutils",
+]
+
+[[package]]
name = "displaydoc"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "ecdsa"
+version = "0.17.0-rc.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54fb064faabbee66e1fc8e5c5a9458d4269dc2d8b638fe86a425adb2510d1a96"
+dependencies = [
+ "der 0.8.0",
+ "digest 0.11.3",
+ "elliptic-curve",
+ "rfc6979",
+ "signature 3.0.0",
+ "spki 0.8.0",
+ "zeroize",
]
[[package]]
@@ -847,29 +1265,78 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
dependencies = [
- "pkcs8",
- "signature",
+ "pkcs8 0.10.2",
+ "signature 2.2.0",
]
[[package]]
+name = "ed25519"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a"
+dependencies = [
+ "pkcs8 0.11.0",
+ "signature 3.0.0",
+]
+
+[[package]]
name = "ed25519-dalek"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
dependencies = [
- "curve25519-dalek",
- "ed25519",
+ "curve25519-dalek 4.1.3",
+ "ed25519 2.2.3",
"serde",
- "sha2",
+ "sha2 0.10.9",
"subtle",
"zeroize",
]
[[package]]
+name = "ed25519-dalek"
+version = "3.0.0-rc.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b011170fe4f04665565b4110afef66774fe9ffff278f3eb5b81cc73d26e27d60"
+dependencies = [
+ "curve25519-dalek 5.0.0-rc.0",
+ "ed25519 3.0.0",
+ "rand_core 0.10.1",
+ "serde",
+ "sha2 0.11.0",
+ "signature 3.0.0",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
name = "either"
-version = "1.15.0"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
+
+[[package]]
+name = "elliptic-curve"
+version = "0.14.0-rc.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+checksum = "102d3643d30dd8b559613c5cced68317199597fffb278cdc88daa2ef7fafc935"
+dependencies = [
+ "base16ct",
+ "crypto-bigint",
+ "crypto-common 0.2.2",
+ "digest 0.11.3",
+ "ff",
+ "group",
+ "hkdf 0.13.0",
+ "hybrid-array",
+ "once_cell",
+ "pem-rfc7468",
+ "pkcs8 0.11.0",
+ "rand_core 0.10.1",
+ "sec1",
+ "subtle",
+ "zeroize",
+]
[[package]]
name = "encode_unicode"
@@ -878,6 +1345,45 @@
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
+name = "endi"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
+
+[[package]]
+name = "enum_dispatch"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd"
+dependencies = [
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "enumflags2"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
+dependencies = [
+ "enumflags2_derive",
+ "serde",
+]
+
+[[package]]
+name = "enumflags2_derive"
+version = "0.7.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
name = "env_filter"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -915,18 +1421,55 @@
]
[[package]]
+name = "event-listener"
+version = "5.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "event-listener-strategy"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
+dependencies = [
+ "event-listener",
+ "pin-project-lite",
+]
+
+[[package]]
name = "fastrand"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
[[package]]
+name = "ff"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f"
+dependencies = [
+ "rand_core 0.10.1",
+ "subtle",
+]
+
+[[package]]
name = "fiat-crypto"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
[[package]]
+name = "fiat-crypto"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24"
+
+[[package]]
name = "find-crate"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -940,12 +1483,6 @@
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
-
-[[package]]
-name = "fixedbitset"
-version = "0.5.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
[[package]]
name = "flate2"
@@ -961,42 +1498,27 @@
name = "fleet"
version = "0.2.0"
dependencies = [
- "abort-on-drop",
- "age",
- "age-core",
"anyhow",
- "async-trait",
- "base64 0.22.1",
- "better-command",
- "chrono",
+ "camino",
"clap",
"clap_complete",
"fleet-base",
- "fleet-shared",
"futures",
- "hostname",
"human-repr",
"indicatif",
"itertools 0.14.0",
"nix-eval",
- "nixlike",
- "nom 8.0.0",
- "openssh",
"opentelemetry",
"opentelemetry-appender-tracing",
"opentelemetry-exporter-env",
"opentelemetry_sdk",
- "peg",
- "regex",
+ "remowt-fleet",
"serde",
"serde_json",
- "shlex",
+ "shlex 1.3.0",
"tabled",
"tempfile",
- "thiserror 2.0.18",
- "time",
"tokio",
- "tokio-util",
"tracing",
"tracing-indicatif",
"tracing-opentelemetry",
@@ -1009,7 +1531,7 @@
dependencies = [
"age",
"anyhow",
- "better-command",
+ "camino",
"chrono",
"clap",
"fleet-shared",
@@ -1020,17 +1542,18 @@
"nix-eval",
"nixlike",
"nom 8.0.0",
- "openssh",
"rand 0.10.1",
+ "remowt-client",
+ "remowt-endpoints",
+ "remowt-fleet",
+ "remowt-link-shared",
+ "remowt-ui-prompt",
"serde",
"serde_json",
"tabled",
"tempfile",
- "thiserror 2.0.18",
"time",
"tokio",
- "tokio-util",
- "toml_edit",
"tracing",
]
@@ -1042,13 +1565,13 @@
"anyhow",
"base64 0.22.1",
"clap",
- "ed25519-dalek",
+ "ed25519-dalek 2.2.0",
"fleet-shared",
"hex",
- "hmac",
- "pbkdf2",
+ "hmac 0.12.1",
+ "pbkdf2 0.12.2",
"rand 0.10.1",
- "sha2",
+ "sha2 0.10.9",
"x25519-dalek",
]
@@ -1197,6 +1720,19 @@
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
+name = "futures-lite"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
name = "futures-macro"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1204,7 +1740,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1247,6 +1783,17 @@
]
[[package]]
+name = "generic-array"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2e55f16dcf0e9c00efbe2e655ffe45fc98e7066b52bc92f8a79e64060a79351"
+dependencies = [
+ "generic-array 0.14.7",
+ "rustversion",
+ "typenum",
+]
+
+[[package]]
name = "getrandom"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1280,11 +1827,13 @@
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
dependencies = [
"cfg-if",
+ "js-sys",
"libc",
"r-efi 6.0.0",
"rand_core 0.10.1",
"wasip2",
"wasip3",
+ "wasm-bindgen",
]
[[package]]
@@ -1294,20 +1843,53 @@
checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1"
dependencies = [
"opaque-debug",
- "polyval",
+ "polyval 0.6.2",
]
[[package]]
+name = "ghash"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5"
+dependencies = [
+ "polyval 0.7.1",
+]
+
+[[package]]
name = "glob"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
+name = "globset"
+version = "0.4.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3"
+dependencies = [
+ "aho-corasick",
+ "bstr",
+ "log",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "group"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4"
+dependencies = [
+ "ff",
+ "rand_core 0.10.1",
+ "subtle",
+]
+
+[[package]]
name = "h2"
-version = "0.4.13"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
+checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733"
dependencies = [
"atomic-waker",
"bytes",
@@ -1315,7 +1897,7 @@
"futures-core",
"futures-sink",
"http",
- "indexmap 2.14.0",
+ "indexmap",
"slab",
"tokio",
"tokio-util",
@@ -1324,12 +1906,6 @@
[[package]]
name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
@@ -1339,9 +1915,9 @@
[[package]]
name = "hashbrown"
-version = "0.17.0"
+version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "heck"
@@ -1350,27 +1926,57 @@
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
+name = "hermit-abi"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
+
+[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
+name = "hex-literal"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e712f64ec3850b98572bffac52e2c6f282b29fe6c5fa6d42334b30be438d95c1"
+
+[[package]]
name = "hkdf"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
dependencies = [
- "hmac",
+ "hmac 0.12.1",
]
[[package]]
+name = "hkdf"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018"
+dependencies = [
+ "hmac 0.13.0",
+]
+
+[[package]]
name = "hmac"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
- "digest",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "hmac"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f"
+dependencies = [
+ "digest 0.11.3",
]
[[package]]
@@ -1395,9 +2001,9 @@
[[package]]
name = "http"
-version = "1.4.0"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
+checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425"
dependencies = [
"bytes",
"itoa",
@@ -1433,22 +2039,28 @@
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
-name = "httpdate"
-version = "1.0.3"
+name = "human-repr"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+checksum = "f58b778a5761513caf593693f8951c97a5b610841e754788400f32102eefdff1"
[[package]]
-name = "human-repr"
-version = "1.1.0"
+name = "hybrid-array"
+version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f58b778a5761513caf593693f8951c97a5b610841e754788400f32102eefdff1"
+checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da"
+dependencies = [
+ "ctutils",
+ "subtle",
+ "typenum",
+ "zeroize",
+]
[[package]]
name = "hyper"
-version = "1.9.0"
+version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca"
+checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498"
dependencies = [
"atomic-waker",
"bytes",
@@ -1458,7 +2070,6 @@
"http",
"http-body",
"httparse",
- "httpdate",
"itoa",
"pin-project-lite",
"smallvec",
@@ -1512,7 +2123,7 @@
"libc",
"percent-encoding",
"pin-project-lite",
- "socket2 0.6.3",
+ "socket2",
"tokio",
"tower-service",
"tracing",
@@ -1567,7 +2178,7 @@
"proc-macro2",
"quote",
"strsim",
- "syn",
+ "syn 2.0.117",
"unic-langid",
]
@@ -1581,7 +2192,7 @@
"i18n-config",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -1709,9 +2320,9 @@
[[package]]
name = "idna_adapter"
-version = "1.2.1"
+version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
+checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
dependencies = [
"icu_normalizer",
"icu_properties",
@@ -1719,22 +2330,12 @@
[[package]]
name = "indexmap"
-version = "1.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
-dependencies = [
- "autocfg",
- "hashbrown 0.12.3",
-]
-
-[[package]]
-name = "indexmap"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
- "hashbrown 0.17.0",
+ "hashbrown 0.17.1",
"serde",
"serde_core",
]
@@ -1768,11 +2369,33 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
dependencies = [
- "block-padding",
- "generic-array",
+ "block-padding 0.3.3",
+ "generic-array 0.14.7",
]
[[package]]
+name = "inout"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7"
+dependencies = [
+ "block-padding 0.4.2",
+ "hybrid-array",
+]
+
+[[package]]
+name = "internal-russh-num-bigint"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae8e22120c32fb4d19ec55fba35015f57095cd95a2e3b732e44457f5915b2ee8"
+dependencies = [
+ "num-integer",
+ "num-traits",
+ "rand 0.10.1",
+ "rand_core 0.10.1",
+]
+
+[[package]]
name = "intl-memoizer"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1802,16 +2425,6 @@
version = "2.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
-
-[[package]]
-name = "iri-string"
-version = "0.7.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20"
-dependencies = [
- "memchr",
- "serde",
-]
[[package]]
name = "is_terminal_polyfill"
@@ -1845,17 +2458,36 @@
[[package]]
name = "js-sys"
-version = "0.3.95"
+version = "0.3.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca"
+checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31"
dependencies = [
"cfg-if",
"futures-util",
- "once_cell",
"wasm-bindgen",
]
[[package]]
+name = "keccak"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.3.0",
+]
+
+[[package]]
+name = "kem"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01737161ba802849cfd486b5bd209d38ba4943494c249a8126005170c7621edd"
+dependencies = [
+ "crypto-common 0.2.2",
+ "rand_core 0.10.1",
+]
+
+[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1872,9 +2504,9 @@
[[package]]
name = "libc"
-version = "0.2.185"
+version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
+checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "libloading"
@@ -1893,6 +2525,18 @@
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
+name = "libredox"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3"
+dependencies = [
+ "bitflags",
+ "libc",
+ "plain",
+ "redox_syscall 0.8.1",
+]
+
+[[package]]
name = "link-cplusplus"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1936,9 +2580,9 @@
[[package]]
name = "log"
-version = "0.4.29"
+version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
+checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a"
[[package]]
name = "lru-slab"
@@ -1956,22 +2600,25 @@
]
[[package]]
-name = "matchit"
-version = "0.7.3"
+name = "md5"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
+checksum = "ae960838283323069879657ca3de837e9f7bbb4c7bf6ea7f1b290d5e9476d2e0"
[[package]]
name = "memchr"
-version = "2.8.0"
+version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
-name = "mime"
-version = "0.3.17"
+name = "memoffset"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
+dependencies = [
+ "autocfg",
+]
[[package]]
name = "minimal-lexical"
@@ -1991,9 +2638,9 @@
[[package]]
name = "mio"
-version = "1.2.0"
+version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
+checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
dependencies = [
"libc",
"wasi",
@@ -2001,16 +2648,35 @@
]
[[package]]
-name = "multimap"
-version = "0.10.1"
+name = "ml-kem"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e15f3e5b957493873e396a66914e83e616b6afe335cdef7efe5c6e1216aba66"
+dependencies = [
+ "hybrid-array",
+ "kem",
+ "module-lattice",
+ "pkcs8 0.11.0",
+ "rand_core 0.10.1",
+ "sha3",
+]
+
+[[package]]
+name = "module-lattice"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
+checksum = "0c61b87c9683ab7cb1c6871d261ad5479b6b10ceb52c4352aaca3b5d35a8febe"
+dependencies = [
+ "ctutils",
+ "hybrid-array",
+ "num-traits",
+]
[[package]]
name = "nix"
-version = "0.31.2"
+version = "0.31.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
+checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d"
dependencies = [
"bitflags",
"cfg-if",
@@ -2024,15 +2690,16 @@
dependencies = [
"anyhow",
"bindgen",
+ "camino",
"cxx",
"cxx-build",
+ "futures",
"itertools 0.14.0",
"nixlike",
"pkg-config",
"serde",
"serde_json",
"test-log",
- "thiserror 2.0.18",
"tokio",
"tracing",
"tracing-indicatif",
@@ -2040,6 +2707,13 @@
]
[[package]]
+name = "nix-plugin-fleet"
+version = "0.1.0"
+dependencies = [
+ "fleet-base",
+]
+
+[[package]]
name = "nixlike"
version = "0.1.0"
dependencies = [
@@ -2047,8 +2721,6 @@
"linked-hash-map",
"peg",
"serde",
- "serde-transcode",
- "serde_json",
"thiserror 2.0.18",
]
@@ -2081,6 +2753,16 @@
]
[[package]]
+name = "num-bigint"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
+dependencies = [
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
name = "num-bigint-dig"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2098,9 +2780,9 @@
[[package]]
name = "num-conv"
-version = "0.2.1"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967"
+checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441"
[[package]]
name = "num-integer"
@@ -2151,20 +2833,6 @@
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]]
-name = "openssh"
-version = "0.11.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d534c4bfecb0ed71dea4db444a5922a294d15cf40e700548f27295e1feb0ef18"
-dependencies = [
- "libc",
- "once_cell",
- "shell-escape",
- "tempfile",
- "thiserror 2.0.18",
- "tokio",
-]
-
-[[package]]
name = "openssl-probe"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2229,12 +2897,12 @@
"opentelemetry-http",
"opentelemetry-proto",
"opentelemetry_sdk",
- "prost 0.14.3",
+ "prost",
"reqwest",
"serde_json",
"thiserror 2.0.18",
"tokio",
- "tonic 0.14.5",
+ "tonic",
"tracing",
]
@@ -2248,10 +2916,10 @@
"const-hex",
"opentelemetry",
"opentelemetry_sdk",
- "prost 0.14.3",
+ "prost",
"serde",
"serde_json",
- "tonic 0.14.5",
+ "tonic",
"tonic-prost",
]
@@ -2271,6 +2939,77 @@
]
[[package]]
+name = "ordered-stream"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "p256"
+version = "0.14.0-rc.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41adc63effe99d48837a8cc0e6d7a77e32ae6a07f6000df466178dbc2193093e"
+dependencies = [
+ "ecdsa",
+ "elliptic-curve",
+ "primefield",
+ "primeorder",
+ "sha2 0.11.0",
+]
+
+[[package]]
+name = "p384"
+version = "0.14.0-rc.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bd5333afa5ae0347f39e6a0f2c9c155da431583fd71fe5555bd0521b4ccaf02"
+dependencies = [
+ "ecdsa",
+ "elliptic-curve",
+ "fiat-crypto 0.3.0",
+ "primefield",
+ "primeorder",
+ "sha2 0.11.0",
+]
+
+[[package]]
+name = "p521"
+version = "0.14.0-rc.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3a5297f53dc16d35909060ba3032cff7867e8809f01e273ff325579d5f0ceae"
+dependencies = [
+ "base16ct",
+ "ecdsa",
+ "elliptic-curve",
+ "primefield",
+ "primeorder",
+ "sha2 0.11.0",
+]
+
+[[package]]
+name = "pageant"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f3a5ae18f65a85c67a77d18d42d3606c07948e3c17c1e5f74852b26589e88a5"
+dependencies = [
+ "base16ct",
+ "byteorder",
+ "bytes",
+ "delegate",
+ "futures",
+ "log",
+ "rand 0.10.1",
+ "sha2 0.11.0",
+ "thiserror 2.0.18",
+ "tokio",
+ "windows",
+ "windows-strings",
+]
+
+[[package]]
name = "papergrid"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2282,6 +3021,12 @@
]
[[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
+[[package]]
name = "parking_lot"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2299,26 +3044,51 @@
dependencies = [
"cfg-if",
"libc",
- "redox_syscall",
+ "redox_syscall 0.5.18",
"smallvec",
"windows-link",
]
[[package]]
+name = "password-hash"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aab41826031698d6ffcd9cff78ef56ef998e39dc7e5067cdfebe373842d4723b"
+dependencies = [
+ "phc",
+]
+
+[[package]]
+name = "paste"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+
+[[package]]
name = "pbkdf2"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
dependencies = [
- "digest",
- "hmac",
+ "digest 0.10.7",
+ "hmac 0.12.1",
+]
+
+[[package]]
+name = "pbkdf2"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "112d82ceb8c5bf524d9af484d4e4970c9fd5a0cc15ba14ad93dccd28873b0629"
+dependencies = [
+ "digest 0.11.3",
+ "hmac 0.13.0",
]
[[package]]
name = "peg"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9928cfca101b36ec5163e70049ee5368a8a1c3c6efc9ca9c5f9cc2f816152477"
+checksum = "0aad070be5b63aa72103f2fcdd70a83adbd5e90112ce5b574171ff1c65501773"
dependencies = [
"peg-macros",
"peg-runtime",
@@ -2326,9 +3096,9 @@
[[package]]
name = "peg-macros"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6298ab04c202fa5b5d52ba03269fb7b74550b150323038878fe6c372d8280f71"
+checksum = "ddd8ef6825cae95355031ae26a99b616a2a21f22ba2de0197c43dfb05acbe7ee"
dependencies = [
"peg-runtime",
"proc-macro2",
@@ -2337,18 +3107,17 @@
[[package]]
name = "peg-runtime"
-version = "0.8.5"
+version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "132dca9b868d927b35b5dd728167b2dee150eb1ad686008fc71ccb298b776fca"
+checksum = "7011d97b484a5ebdc4b1fdb3b12d5e4bbbea56e9d22b688f2e79e04b65a7d8a6"
[[package]]
-name = "pem"
-version = "3.0.6"
+name = "pem-rfc7468"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
+checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9"
dependencies = [
- "base64 0.22.1",
- "serde_core",
+ "base64ct",
]
[[package]]
@@ -2358,33 +3127,33 @@
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
-name = "petgraph"
-version = "0.7.1"
+name = "phc"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772"
+checksum = "44dc769b75f93afdddd8c7fa12d685292ddeff1e66f7f0f3a234cf1818afe892"
dependencies = [
- "fixedbitset",
- "indexmap 2.14.0",
+ "base64ct",
+ "ctutils",
]
[[package]]
name = "pin-project"
-version = "1.1.11"
+version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517"
+checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
-version = "1.1.11"
+version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6"
+checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2394,33 +3163,102 @@
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
+name = "piper"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1"
+dependencies = [
+ "atomic-waker",
+ "fastrand",
+ "futures-io",
+]
+
+[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
- "der",
- "pkcs8",
- "spki",
+ "der 0.7.10",
+ "pkcs8 0.10.2",
+ "spki 0.7.3",
]
[[package]]
+name = "pkcs1"
+version = "0.8.0-rc.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "986d2e952779af96ea048f160fd9194e1751b4faea78bcf3ceb456efe008088e"
+dependencies = [
+ "der 0.8.0",
+ "spki 0.8.0",
+]
+
+[[package]]
+name = "pkcs5"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "279a91971a1d8eb1260a30938eae3be9cb67b472dffecb222fbbbe2fd2dc1453"
+dependencies = [
+ "aes 0.9.1",
+ "cbc 0.2.1",
+ "der 0.8.0",
+ "pbkdf2 0.13.0",
+ "rand_core 0.10.1",
+ "scrypt 0.12.0",
+ "sha2 0.11.0",
+ "spki 0.8.0",
+]
+
+[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
- "der",
- "spki",
+ "der 0.7.10",
+ "spki 0.7.3",
]
[[package]]
+name = "pkcs8"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7"
+dependencies = [
+ "der 0.8.0",
+ "pkcs5",
+ "rand_core 0.10.1",
+ "spki 0.8.0",
+]
+
+[[package]]
name = "pkg-config"
version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
[[package]]
+name = "plain"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
+
+[[package]]
+name = "polling"
+version = "3.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
+dependencies = [
+ "cfg-if",
+ "concurrent-queue",
+ "hermit-abi",
+ "pin-project-lite",
+ "rustix 1.1.4",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
name = "poly1305"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2428,7 +3266,18 @@
dependencies = [
"cpufeatures 0.2.17",
"opaque-debug",
- "universal-hash",
+ "universal-hash 0.5.1",
+]
+
+[[package]]
+name = "poly1305"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a00baa632505d05512f48a963e16051c54fda9a95cc9acea1a4e3c90991c4a2e"
+dependencies = [
+ "cpufeatures 0.3.0",
+ "universal-hash 0.6.1",
+ "zeroize",
]
[[package]]
@@ -2440,7 +3289,18 @@
"cfg-if",
"cpufeatures 0.2.17",
"opaque-debug",
- "universal-hash",
+ "universal-hash 0.5.1",
+]
+
+[[package]]
+name = "polyval"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dfc63250416fea14f5749b90725916a6c903f599d51cb635aa7a52bfd03eede"
+dependencies = [
+ "cpubits",
+ "cpufeatures 0.3.0",
+ "universal-hash 0.6.1",
]
[[package]]
@@ -2480,10 +3340,42 @@
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
- "syn",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "primefield"
+version = "0.14.0-rc.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1d7e42f46a29abc16fb621a3466ee453358ebaae48a9e515f287e0af052ed8f"
+dependencies = [
+ "crypto-bigint",
+ "crypto-common 0.2.2",
+ "ff",
+ "rand_core 0.10.1",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "primeorder"
+version = "0.14.0-rc.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d2793f22b9b6fd11ef3ac1d59bf003c2573593e4968702341605c2748fd90bf"
+dependencies = [
+ "elliptic-curve",
]
[[package]]
+name = "proc-macro-crate"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
+dependencies = [
+ "toml_edit",
+]
+
+[[package]]
name = "proc-macro-error-attr2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2502,7 +3394,7 @@
"proc-macro-error-attr2",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -2531,77 +3423,25 @@
[[package]]
name = "prost"
-version = "0.13.5"
+version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
+checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1"
dependencies = [
"bytes",
- "prost-derive 0.13.5",
-]
-
-[[package]]
-name = "prost"
-version = "0.14.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
-dependencies = [
- "bytes",
- "prost-derive 0.14.3",
+ "prost-derive",
]
[[package]]
-name = "prost-build"
-version = "0.13.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf"
-dependencies = [
- "heck",
- "itertools 0.14.0",
- "log",
- "multimap",
- "once_cell",
- "petgraph",
- "prettyplease",
- "prost 0.13.5",
- "prost-types",
- "regex",
- "syn",
- "tempfile",
-]
-
-[[package]]
name = "prost-derive"
-version = "0.13.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
-dependencies = [
- "anyhow",
- "itertools 0.14.0",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "prost-derive"
-version = "0.14.3"
+version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
+checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf"
dependencies = [
"anyhow",
"itertools 0.14.0",
"proc-macro2",
"quote",
- "syn",
-]
-
-[[package]]
-name = "prost-types"
-version = "0.13.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16"
-dependencies = [
- "prost 0.13.5",
+ "syn 2.0.117",
]
[[package]]
@@ -2617,7 +3457,7 @@
"quinn-udp",
"rustc-hash 2.1.2",
"rustls",
- "socket2 0.6.3",
+ "socket2",
"thiserror 2.0.18",
"tokio",
"tracing",
@@ -2654,7 +3494,7 @@
"cfg_aliases",
"libc",
"once_cell",
- "socket2 0.6.3",
+ "socket2",
"tracing",
"windows-sys 0.60.2",
]
@@ -2766,32 +3606,28 @@
]
[[package]]
-name = "rcgen"
-version = "0.13.2"
+name = "redox_syscall"
+version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2"
+checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
- "pem",
- "ring",
- "rustls-pki-types",
- "time",
- "yasna",
+ "bitflags",
]
[[package]]
name = "redox_syscall"
-version = "0.5.18"
+version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
+checksum = "5b44b894f2a6e36457d665d1e08c3866add6ed5e70050c1b4ba8a8ddedb02ce7"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
-version = "1.12.3"
+version = "1.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
+checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
dependencies = [
"aho-corasick",
"memchr",
@@ -2812,18 +3648,131 @@
[[package]]
name = "regex-syntax"
-version = "0.8.10"
+version = "0.8.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
+
+[[package]]
+name = "remowt-client"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34d59c0ce311b4b3c094b0b196a1004aa438b9947c3eace2ca4d2a0ac08fac59"
+dependencies = [
+ "anyhow",
+ "bifrostlink",
+ "bifrostlink-ports",
+ "bytes",
+ "camino",
+ "futures",
+ "remowt-endpoints",
+ "remowt-link-shared",
+ "russh",
+ "russh-config",
+ "serde",
+ "serde_json",
+ "tempfile",
+ "tokio",
+ "tokio-util",
+ "tracing",
+ "uuid",
+]
+
+[[package]]
+name = "remowt-endpoints"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb203856cd5cff27504bd2023c59195b1f1ce1cf5d8ea836598993894eb1b9c0"
+dependencies = [
+ "anyhow",
+ "bifrostlink",
+ "bifrostlink-macros",
+ "camino",
+ "nix",
+ "serde",
+ "tempfile",
+ "thiserror 2.0.18",
+ "tokio",
+ "tracing",
+ "uuid",
+ "zbus",
+]
+
+[[package]]
+name = "remowt-fleet"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "bifrostlink",
+ "camino",
+ "nix-eval",
+ "remowt-client",
+ "remowt-endpoints",
+ "serde",
+ "thiserror 2.0.18",
+ "tokio",
+ "tracing",
+ "uuid",
+]
+
+[[package]]
+name = "remowt-link-shared"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98ebba5be028a2dfb7f1858bb0ff74037262753eaae4dc6e5d9ae241c4567668"
+dependencies = [
+ "bifrostlink",
+ "bytes",
+ "remowt-ui-prompt",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "remowt-plugin"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
+checksum = "ef73ef3eea5bb6152d01019b5062e51ef258a1ac1c7a6f8cdcdf6fe1eb192cdd"
+dependencies = [
+ "anyhow",
+ "bifrostlink",
+ "bifrostlink-ports",
+ "remowt-link-shared",
+ "serde_json",
+ "tokio",
+ "tracing",
+ "tracing-subscriber",
+]
[[package]]
-name = "repl-plugin-unstable"
+name = "remowt-plugin-fleet"
version = "0.1.0"
dependencies = [
- "fleet-base",
+ "anyhow",
+ "remowt-fleet",
+ "remowt-plugin",
]
[[package]]
+name = "remowt-ui-prompt"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acf28ba68e6f8087657157695e9ab42b82a21130e77f6dffd27781062109325d"
+dependencies = [
+ "anyhow",
+ "bifrostlink",
+ "bifrostlink-macros",
+ "serde",
+ "serde_json",
+ "thiserror 2.0.18",
+ "tokio",
+ "tracing",
+ "zbus",
+]
+
+[[package]]
name = "reqwest"
version = "0.12.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2854,8 +3803,8 @@
"sync_wrapper",
"tokio",
"tokio-rustls",
- "tower 0.5.3",
- "tower-http 0.6.8",
+ "tower",
+ "tower-http",
"tower-service",
"url",
"wasm-bindgen",
@@ -2864,6 +3813,16 @@
]
[[package]]
+name = "rfc6979"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5236ce872cac07e0fb3969b0cbf468c7d2f37d432f1b627dcb7b8d34563fb0c3"
+dependencies = [
+ "hmac 0.13.0",
+ "subtle",
+]
+
+[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2878,45 +3837,155 @@
]
[[package]]
-name = "rmp"
-version = "0.8.15"
+name = "rsa"
+version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c"
+checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
dependencies = [
+ "const-oid 0.9.6",
+ "digest 0.10.7",
+ "num-bigint-dig",
+ "num-integer",
"num-traits",
+ "pkcs1 0.7.5",
+ "pkcs8 0.10.2",
+ "rand_core 0.6.4",
+ "signature 2.2.0",
+ "spki 0.7.3",
+ "subtle",
+ "zeroize",
]
[[package]]
-name = "rmp-serde"
-version = "1.3.1"
+name = "rsa"
+version = "0.10.0-rc.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
+checksum = "30b2aa4ba0d89f73d1e332df05be0eeab8840351c36ca5654341dfdb57bb3caf"
dependencies = [
- "rmp",
- "serde",
+ "const-oid 0.10.2",
+ "crypto-bigint",
+ "crypto-primes",
+ "digest 0.11.3",
+ "pkcs1 0.8.0-rc.4",
+ "pkcs8 0.11.0",
+ "rand_core 0.10.1",
+ "sha2 0.11.0",
+ "signature 3.0.0",
+ "spki 0.8.0",
+ "zeroize",
]
[[package]]
-name = "rsa"
-version = "0.9.10"
+name = "russh"
+version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d"
+checksum = "bbf893f64684e58da8a68d56a5e84d1cf0440226274c515770fe267707a7d0b0"
dependencies = [
- "const-oid",
- "digest",
- "num-bigint-dig",
- "num-integer",
- "num-traits",
- "pkcs1",
- "pkcs8",
- "rand_core 0.6.4",
- "signature",
- "spki",
+ "aes 0.9.1",
+ "bitflags",
+ "block-padding 0.4.2",
+ "byteorder",
+ "bytes",
+ "cbc 0.2.1",
+ "cipher 0.5.2",
+ "crypto-bigint",
+ "ctr 0.10.1",
+ "curve25519-dalek 5.0.0-rc.0",
+ "data-encoding",
+ "delegate",
+ "der 0.8.0",
+ "digest 0.11.3",
+ "ecdsa",
+ "ed25519-dalek 3.0.0-rc.0",
+ "elliptic-curve",
+ "enum_dispatch",
+ "flate2",
+ "futures",
+ "generic-array 1.4.3",
+ "getrandom 0.4.2",
+ "ghash 0.6.0",
+ "hex-literal",
+ "hmac 0.13.0",
+ "inout 0.2.2",
+ "internal-russh-num-bigint",
+ "keccak",
+ "log",
+ "md5",
+ "ml-kem",
+ "module-lattice",
+ "num-bigint",
+ "p256",
+ "p384",
+ "p521",
+ "pageant",
+ "pbkdf2 0.13.0",
+ "pkcs1 0.8.0-rc.4",
+ "pkcs5",
+ "pkcs8 0.11.0",
+ "polyval 0.7.1",
+ "rand 0.10.1",
+ "rand_core 0.10.1",
+ "ring",
+ "rsa 0.10.0-rc.18",
+ "russh-cryptovec",
+ "russh-util",
+ "salsa20 0.11.0",
+ "scrypt 0.12.0",
+ "sec1",
+ "sha1",
+ "sha2 0.11.0",
+ "sha3",
+ "signature 3.0.0",
+ "spki 0.8.0",
+ "ssh-encoding",
+ "ssh-key",
"subtle",
+ "thiserror 2.0.18",
+ "tokio",
+ "typenum",
+ "universal-hash 0.6.1",
"zeroize",
]
[[package]]
+name = "russh-config"
+version = "0.58.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "993346101d4741a59c82bafc6b645c52ce3e7b0820f13e4b5d48cdb591e3d955"
+dependencies = [
+ "futures",
+ "globset",
+ "log",
+ "thiserror 2.0.18",
+ "tokio",
+ "whoami",
+]
+
+[[package]]
+name = "russh-cryptovec"
+version = "0.61.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "443f6bbcfacb34a1aab2b12b99bf08e0c63abdc5a0db261901365df9d57fff51"
+dependencies = [
+ "log",
+ "nix",
+ "ssh-encoding",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
+name = "russh-util"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "668424a5dde0bcb45b55ba7de8476b93831b4aa2fa6947e145f3b053e22c60b6"
+dependencies = [
+ "chrono",
+ "tokio",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+]
+
+[[package]]
name = "rust-embed"
version = "8.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2936,7 +4005,7 @@
"proc-macro2",
"quote",
"rust-embed-utils",
- "syn",
+ "syn 2.0.117",
"walkdir",
]
@@ -2946,7 +4015,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1"
dependencies = [
- "sha2",
+ "sha2 0.10.9",
"walkdir",
]
@@ -2999,11 +4068,10 @@
[[package]]
name = "rustls"
-version = "0.23.38"
+version = "0.23.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21"
+checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b"
dependencies = [
- "log",
"once_cell",
"ring",
"rustls-pki-types",
@@ -3014,30 +4082,21 @@
[[package]]
name = "rustls-native-certs"
-version = "0.8.3"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
+checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d"
dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
"security-framework",
-]
-
-[[package]]
-name = "rustls-pemfile"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
-dependencies = [
- "rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
-version = "1.14.0"
+version = "1.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
+checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
dependencies = [
"web-time",
"zeroize",
@@ -3072,7 +4131,17 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213"
dependencies = [
- "cipher",
+ "cipher 0.4.4",
+]
+
+[[package]]
+name = "salsa20"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f874456e72520ff1375a06c588eaf074b0f01f9e9e1aada45bd9b7954a6e42c"
+dependencies = [
+ "cfg-if",
+ "cipher 0.5.2",
]
[[package]]
@@ -3111,12 +4180,38 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f"
dependencies = [
- "pbkdf2",
- "salsa20",
- "sha2",
+ "pbkdf2 0.12.2",
+ "salsa20 0.10.2",
+ "sha2 0.10.9",
]
[[package]]
+name = "scrypt"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d87af57419b594aa23fa95f09f0e06d80d84ba01c26148c43844cad6ff4485f0"
+dependencies = [
+ "cfg-if",
+ "pbkdf2 0.13.0",
+ "salsa20 0.11.0",
+ "sha2 0.11.0",
+]
+
+[[package]]
+name = "sec1"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d"
+dependencies = [
+ "base16ct",
+ "ctutils",
+ "der 0.8.0",
+ "hybrid-array",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
name = "secrecy"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3177,28 +4272,9 @@
dependencies = [
"serde_core",
"serde_derive",
-]
-
-[[package]]
-name = "serde-transcode"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2"
-dependencies = [
- "serde",
]
[[package]]
-name = "serde_bytes"
-version = "0.11.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8"
-dependencies = [
- "serde",
- "serde_core",
-]
-
-[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3215,14 +4291,14 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
name = "serde_json"
-version = "1.0.149"
+version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
+checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
@@ -3232,6 +4308,17 @@
]
[[package]]
+name = "serde_repr"
+version = "0.1.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3244,6 +4331,27 @@
]
[[package]]
+name = "serdect"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e"
+dependencies = [
+ "base16ct",
+ "serde",
+]
+
+[[package]]
+name = "sha1"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.3.0",
+ "digest 0.11.3",
+]
+
+[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3251,10 +4359,31 @@
dependencies = [
"cfg-if",
"cpufeatures 0.2.17",
- "digest",
+ "digest 0.10.7",
]
[[package]]
+name = "sha2"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
+dependencies = [
+ "cfg-if",
+ "cpufeatures 0.3.0",
+ "digest 0.11.3",
+]
+
+[[package]]
+name = "sha3"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1"
+dependencies = [
+ "digest 0.11.3",
+ "keccak",
+]
+
+[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3264,16 +4393,16 @@
]
[[package]]
-name = "shell-escape"
-version = "0.1.5"
+name = "shlex"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "shlex"
-version = "1.3.0"
+version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "signal-hook-registry"
@@ -3291,11 +4420,21 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
- "digest",
+ "digest 0.10.7",
"rand_core 0.6.4",
]
[[package]]
+name = "signature"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5"
+dependencies = [
+ "digest 0.11.3",
+ "rand_core 0.10.1",
+]
+
+[[package]]
name = "simd-adler32"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3309,25 +4448,15 @@
[[package]]
name = "smallvec"
-version = "1.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
-
-[[package]]
-name = "socket2"
-version = "0.5.10"
+version = "1.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
-dependencies = [
- "libc",
- "windows-sys 0.52.0",
-]
+checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90"
[[package]]
name = "socket2"
-version = "0.6.3"
+version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
+checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51"
dependencies = [
"libc",
"windows-sys 0.61.2",
@@ -3346,10 +4475,81 @@
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
- "der",
+ "der 0.7.10",
+]
+
+[[package]]
+name = "spki"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f"
+dependencies = [
+ "base64ct",
+ "der 0.8.0",
+]
+
+[[package]]
+name = "ssh-cipher"
+version = "0.3.0-rc.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10db6f219196a8528f9ec904d9d45cdad692d65b0e57e72be4dedd1c5fddce36"
+dependencies = [
+ "aead 0.6.0",
+ "aes 0.9.1",
+ "aes-gcm 0.11.0-rc.4",
+ "cbc 0.2.1",
+ "chacha20 0.10.0",
+ "cipher 0.5.2",
+ "ctr 0.10.1",
+ "ctutils",
+ "des",
+ "poly1305 0.9.0",
+ "ssh-encoding",
+ "zeroize",
]
[[package]]
+name = "ssh-encoding"
+version = "0.3.0-rc.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7abf34aa716da5d5b4c496936d042ea282ab392092cd68a72ef6a8863ff8c96a"
+dependencies = [
+ "base64ct",
+ "bytes",
+ "crypto-bigint",
+ "ctutils",
+ "digest 0.11.3",
+ "pem-rfc7468",
+ "zeroize",
+]
+
+[[package]]
+name = "ssh-key"
+version = "0.7.0-rc.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45735ce3dea95690e4a9e414c4cfde7f79835063c3dcd35881df85a84118e74b"
+dependencies = [
+ "argon2",
+ "bcrypt-pbkdf 0.11.0",
+ "ctutils",
+ "ed25519-dalek 3.0.0-rc.0",
+ "hex",
+ "hmac 0.13.0",
+ "p256",
+ "p384",
+ "p521",
+ "rand_core 0.10.1",
+ "rsa 0.10.0-rc.18",
+ "sec1",
+ "sha1",
+ "sha2 0.11.0",
+ "signature 3.0.0",
+ "ssh-cipher",
+ "ssh-encoding",
+ "zeroize",
+]
+
+[[package]]
name = "stable_deref_trait"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3369,6 +4569,17 @@
[[package]]
name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
@@ -3395,7 +4606,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3419,7 +4630,7 @@
"proc-macro-error2",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3452,24 +4663,13 @@
dependencies = [
"rustix 1.1.4",
"windows-sys 0.61.2",
-]
-
-[[package]]
-name = "terraform-provider-fleet"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "async-trait",
- "serde",
- "tf-provider",
- "tokio",
]
[[package]]
name = "test-log"
-version = "0.2.20"
+version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f46bf474f0a4afebf92f076d54fd5e63423d9438b8c278a3d2ccb0f47f7cdb3"
+checksum = "9b9c218384242b5c89b68303ab6f6fc53a312d923f0c14dc6bb860c6aeee40f1"
dependencies = [
"env_logger",
"test-log-macros",
@@ -3478,22 +4678,22 @@
[[package]]
name = "test-log-core"
-version = "0.2.20"
+version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d4d41320b48bc4a211a9021678fcc0c99569b594ea31c93735b8e517102b4c"
+checksum = "c26ef8b00e4d382e59f6a8ddb3cd790b3a5bb29f21a358a9a69ea2f29f13f27b"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
name = "test-log-macros"
-version = "0.2.20"
+version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9beb9249a81e430dffd42400a49019bcf548444f1968ff23080a625de0d4d320"
+checksum = "944ad38adcbb71eaa682c56bceeb079e4ca82b4b3edc2a0fde5cb297b77dac8d"
dependencies = [
- "syn",
+ "syn 2.0.117",
"test-log-core",
]
@@ -3504,34 +4704,6 @@
checksum = "0f8daae29995a24f65619e19d8d31dea5b389f3d853d8bf297bbf607cd0014cc"
dependencies = [
"unicode-width",
-]
-
-[[package]]
-name = "tf-provider"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d80ea2e5f9f54717952d199888aab7e607dc99275ec5221f1259ce7a5f55f5a6"
-dependencies = [
- "anyhow",
- "async-stream",
- "async-trait",
- "base64 0.22.1",
- "futures",
- "prost 0.13.5",
- "rcgen",
- "rmp-serde",
- "serde",
- "serde_bytes",
- "serde_json",
- "time",
- "tokio",
- "tokio-stream",
- "tokio-util",
- "tonic 0.12.3",
- "tonic-build",
- "tower-http 0.5.2",
- "tracing",
- "tracing-subscriber",
]
[[package]]
@@ -3560,7 +4732,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3571,7 +4743,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3585,9 +4757,9 @@
[[package]]
name = "time"
-version = "0.3.47"
+version = "0.3.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
+checksum = "711a53c2d47bbd818258c498c8dbfe186a2526c631495cfe7e078567f86b8469"
dependencies = [
"deranged",
"num-conv",
@@ -3599,15 +4771,15 @@
[[package]]
name = "time-core"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
+checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109"
[[package]]
name = "time-macros"
-version = "0.2.27"
+version = "0.2.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
+checksum = "71c652a3727a9cbb9a02f707f530b618ce00d0ccd762009c8c23bd191df3c17d"
dependencies = [
"num-conv",
"time-core",
@@ -3641,16 +4813,16 @@
[[package]]
name = "tokio"
-version = "1.52.1"
+version = "1.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6"
+checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
dependencies = [
"bytes",
"libc",
"mio",
"pin-project-lite",
"signal-hook-registry",
- "socket2 0.6.3",
+ "socket2",
"tokio-macros",
"windows-sys 0.61.2",
]
@@ -3663,7 +4835,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3685,7 +4857,6 @@
"futures-core",
"pin-project-lite",
"tokio",
- "tokio-util",
]
[[package]]
@@ -3712,24 +4883,23 @@
[[package]]
name = "toml_datetime"
-version = "0.7.5+spec-1.1.0"
+version = "1.1.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
+checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_edit"
-version = "0.23.10+spec-1.0.0"
+version = "0.25.12+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
+checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7"
dependencies = [
- "indexmap 2.14.0",
+ "indexmap",
"toml_datetime",
"toml_parser",
- "toml_writer",
- "winnow 0.7.15",
+ "winnow",
]
[[package]]
@@ -3738,52 +4908,14 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
dependencies = [
- "winnow 1.0.2",
-]
-
-[[package]]
-name = "toml_writer"
-version = "1.1.1+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"
-
-[[package]]
-name = "tonic"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"
-dependencies = [
- "async-stream",
- "async-trait",
- "axum",
- "base64 0.22.1",
- "bytes",
- "h2",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-timeout",
- "hyper-util",
- "percent-encoding",
- "pin-project",
- "prost 0.13.5",
- "rustls-pemfile",
- "socket2 0.5.10",
- "tokio",
- "tokio-rustls",
- "tokio-stream",
- "tower 0.4.13",
- "tower-layer",
- "tower-service",
- "tracing",
+ "winnow",
]
[[package]]
name = "tonic"
-version = "0.14.5"
+version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec"
+checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef"
dependencies = [
"async-trait",
"base64 0.22.1",
@@ -3800,55 +4932,21 @@
"sync_wrapper",
"tokio",
"tokio-stream",
- "tower 0.5.3",
+ "tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
-name = "tonic-build"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11"
-dependencies = [
- "prettyplease",
- "proc-macro2",
- "prost-build",
- "prost-types",
- "quote",
- "syn",
-]
-
-[[package]]
name = "tonic-prost"
-version = "0.14.5"
+version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309"
+checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0"
dependencies = [
"bytes",
- "prost 0.14.3",
- "tonic 0.14.5",
-]
-
-[[package]]
-name = "tower"
-version = "0.4.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
-dependencies = [
- "futures-core",
- "futures-util",
- "indexmap 1.9.3",
- "pin-project",
- "pin-project-lite",
- "rand 0.8.6",
- "slab",
- "tokio",
- "tokio-util",
- "tower-layer",
- "tower-service",
- "tracing",
+ "prost",
+ "tonic",
]
[[package]]
@@ -3859,7 +4957,7 @@
dependencies = [
"futures-core",
"futures-util",
- "indexmap 2.14.0",
+ "indexmap",
"pin-project-lite",
"slab",
"sync_wrapper",
@@ -3872,37 +4970,20 @@
[[package]]
name = "tower-http"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
-dependencies = [
- "bitflags",
- "bytes",
- "http",
- "http-body",
- "http-body-util",
- "pin-project-lite",
- "tower-layer",
- "tower-service",
- "tracing",
-]
-
-[[package]]
-name = "tower-http"
-version = "0.6.8"
+version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
+checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
dependencies = [
"bitflags",
"bytes",
"futures-util",
"http",
"http-body",
- "iri-string",
"pin-project-lite",
- "tower 0.5.3",
+ "tower",
"tower-layer",
"tower-service",
+ "url",
]
[[package]]
@@ -3936,7 +5017,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -3989,16 +5070,6 @@
]
[[package]]
-name = "tracing-serde"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1"
-dependencies = [
- "serde",
- "tracing-core",
-]
-
-[[package]]
name = "tracing-subscriber"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4008,15 +5079,12 @@
"nu-ansi-term",
"once_cell",
"regex-automata",
- "serde",
- "serde_json",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
- "tracing-serde",
]
[[package]]
@@ -4036,11 +5104,22 @@
[[package]]
name = "typenum"
-version = "1.20.0"
+version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
+checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
[[package]]
+name = "uds_windows"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
+dependencies = [
+ "memoffset",
+ "tempfile",
+ "windows-sys 0.61.2",
+]
+
+[[package]]
name = "unarray"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4107,11 +5186,21 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [
- "crypto-common",
+ "crypto-common 0.1.7",
"subtle",
]
[[package]]
+name = "universal-hash"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96"
+dependencies = [
+ "crypto-common 0.2.2",
+ "ctutils",
+]
+
+[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4142,6 +5231,18 @@
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
+name = "uuid"
+version = "1.23.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
+dependencies = [
+ "getrandom 0.4.2",
+ "js-sys",
+ "serde_core",
+ "wasm-bindgen",
+]
+
+[[package]]
name = "valuable"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4204,9 +5305,9 @@
[[package]]
name = "wasip2"
-version = "1.0.3+wasi-0.2.9"
+version = "1.0.4+wasi-0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
+checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
dependencies = [
"wit-bindgen 0.57.1",
]
@@ -4221,10 +5322,16 @@
]
[[package]]
+name = "wasite"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
+
+[[package]]
name = "wasm-bindgen"
-version = "0.2.118"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89"
+checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a"
dependencies = [
"cfg-if",
"once_cell",
@@ -4235,9 +5342,9 @@
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.68"
+version = "0.4.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8"
+checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -4245,9 +5352,9 @@
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.118"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed"
+checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@@ -4255,22 +5362,22 @@
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.118"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904"
+checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.118"
+version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129"
+checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f"
dependencies = [
"unicode-ident",
]
@@ -4292,7 +5399,7 @@
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
dependencies = [
"anyhow",
- "indexmap 2.14.0",
+ "indexmap",
"wasm-encoder",
"wasmparser",
]
@@ -4305,15 +5412,15 @@
dependencies = [
"bitflags",
"hashbrown 0.15.5",
- "indexmap 2.14.0",
+ "indexmap",
"semver",
]
[[package]]
name = "web-sys"
-version = "0.3.95"
+version = "0.3.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d"
+checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -4342,6 +5449,17 @@
]
[[package]]
+name = "whoami"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d"
+dependencies = [
+ "libredox",
+ "wasite",
+ "web-sys",
+]
+
+[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4351,6 +5469,27 @@
]
[[package]]
+name = "windows"
+version = "0.62.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
+dependencies = [
+ "windows-collections",
+ "windows-core",
+ "windows-future",
+ "windows-numerics",
+]
+
+[[package]]
+name = "windows-collections"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
+dependencies = [
+ "windows-core",
+]
+
+[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4364,6 +5503,17 @@
]
[[package]]
+name = "windows-future"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
+dependencies = [
+ "windows-core",
+ "windows-link",
+ "windows-threading",
+]
+
+[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4371,7 +5521,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4382,7 +5532,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4392,6 +5542,16 @@
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
+name = "windows-numerics"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
+dependencies = [
+ "windows-core",
+ "windows-link",
+]
+
+[[package]]
name = "windows-result"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4479,6 +5639,15 @@
]
[[package]]
+name = "windows-threading"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4576,20 +5745,14 @@
[[package]]
name = "winnow"
-version = "0.7.15"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
+checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1"
dependencies = [
"memchr",
]
[[package]]
-name = "winnow"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0"
-
-[[package]]
name = "wit-bindgen"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4623,9 +5786,9 @@
dependencies = [
"anyhow",
"heck",
- "indexmap 2.14.0",
+ "indexmap",
"prettyplease",
- "syn",
+ "syn 2.0.117",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
@@ -4641,7 +5804,7 @@
"prettyplease",
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"wit-bindgen-core",
"wit-bindgen-rust",
]
@@ -4654,7 +5817,7 @@
dependencies = [
"anyhow",
"bitflags",
- "indexmap 2.14.0",
+ "indexmap",
"log",
"serde",
"serde_derive",
@@ -4673,7 +5836,7 @@
dependencies = [
"anyhow",
"id-arena",
- "indexmap 2.14.0",
+ "indexmap",
"log",
"semver",
"serde",
@@ -4701,26 +5864,17 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
dependencies = [
- "curve25519-dalek",
+ "curve25519-dalek 4.1.3",
"rand_core 0.6.4",
"serde",
"zeroize",
]
[[package]]
-name = "yasna"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd"
-dependencies = [
- "time",
-]
-
-[[package]]
name = "yoke"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca"
+checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
dependencies = [
"stable_deref_trait",
"yoke-derive",
@@ -4735,35 +5889,96 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"synstructure",
]
[[package]]
+name = "zbus"
+version = "5.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eee682d202a77e4a9f3b2c2bdf48a7b28af5c08c34ddf66f98c93e5e39464285"
+dependencies = [
+ "async-broadcast",
+ "async-executor",
+ "async-io",
+ "async-lock",
+ "async-process",
+ "async-recursion",
+ "async-task",
+ "async-trait",
+ "blocking",
+ "enumflags2",
+ "event-listener",
+ "futures-core",
+ "futures-lite",
+ "hex",
+ "libc",
+ "ordered-stream",
+ "rustix 1.1.4",
+ "serde",
+ "serde_repr",
+ "tracing",
+ "uds_windows",
+ "uuid",
+ "windows-sys 0.61.2",
+ "winnow",
+ "zbus_macros",
+ "zbus_names",
+ "zvariant",
+]
+
+[[package]]
+name = "zbus_macros"
+version = "5.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adf1bd45a81a103745b1757754762a26e8cd01e4532e4d6c8ec431624b80d1d6"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+ "zbus_names",
+ "zvariant",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zbus_names"
+version = "4.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d"
+dependencies = [
+ "serde",
+ "winnow",
+ "zvariant",
+]
+
+[[package]]
name = "zerocopy"
-version = "0.8.48"
+version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
+checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.8.48"
+version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
+checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
name = "zerofrom"
-version = "0.1.7"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df"
+checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
dependencies = [
"zerofrom-derive",
]
@@ -4776,28 +5991,28 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
"synstructure",
]
[[package]]
name = "zeroize"
-version = "1.8.2"
+version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
-version = "1.4.3"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
+checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328"
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4831,7 +6046,7 @@
dependencies = [
"proc-macro2",
"quote",
- "syn",
+ "syn 2.0.117",
]
[[package]]
@@ -4839,3 +6054,43 @@
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+
+[[package]]
+name = "zvariant"
+version = "5.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a192a0bde63360d77a7523c833d4b4ce6070a927e2c53246e4c540b1a3e27be0"
+dependencies = [
+ "endi",
+ "enumflags2",
+ "serde",
+ "winnow",
+ "zvariant_derive",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zvariant_derive"
+version = "5.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bc6cde9c01c511074be97f7ccb6c19d0da89e3f8662e812e999dcfd4638737"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zvariant_utils"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e8535915cfa75547e559d8c68e8139909a4aeee076831e4ef7fc59d8172c4d6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde",
+ "syn 2.0.117",
+ "winnow",
+]
Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,22 +6,28 @@
package.rust-version = "1.89.0"
[workspace.dependencies]
-better-command = { path = "./crates/better-command" }
fleet-base = { path = "./crates/fleet-base" }
fleet-shared = { path = "./crates/fleet-shared" }
nix-eval = { path = "./crates/nix-eval" }
nixlike = { path = "./crates/nixlike" }
opentelemetry-exporter-env = { path = "./crates/opentelemetry-exporter-env" }
+remowt-fleet = { path = "./crates/remowt-fleet" }
-abort-on-drop = "0.2"
+remowt-client = "0.1.3"
+remowt-endpoints = "0.1.3"
+remowt-link-shared = "0.1.3"
+remowt-plugin = "0.1.3"
+remowt-ui-prompt = "0.1.3"
+
+bifrostlink = "0.2.3"
+
+uuid = { version = "1", features = ["v4"] }
+
age = { version = "0.11", features = ["plugin", "ssh"] }
-age-core = "0.11"
anyhow = "1.0"
-async-trait = "0.1.88"
-axum = { version = "0.8.7", features = ["http2", "macros", "ws"] }
-axum-extra = { version = "0.12.2", features = ["typed-header"] }
base64 = "0.22.1"
bindgen = "0.72.0"
+camino = "1.2.2"
chrono = { version = "0.4.41", features = ["serde"] }
clap = { version = "4.5", features = ["derive", "env", "unicode", "wrap_help"] }
clap_complete = "4.5"
@@ -29,19 +35,16 @@
cxx-build = "1.0.168"
ed25519-dalek = "2.1"
futures = "0.3.31"
-futures-util = { version = "0.3.31", features = ["sink"] }
hex = "0.4.3"
hmac = "0.12"
hostname = "0.4.1"
human-repr = "1.1"
-hyper = "1.8.1"
indicatif = "0.18"
indoc = "2.0.6"
itertools = "0.14.0"
linked-hash-map = "0.5.6"
nix = { version = "0.31.2", features = ["fs", "user"] }
nom = "8.0.0"
-openssh = "0.11.5"
opentelemetry = "0.31.0"
opentelemetry-appender-tracing = "0.31.1"
opentelemetry-otlp = { version = "0.31.0", features = ["grpc-tonic", "gzip-tonic", "http-json", "reqwest-rustls"] }
@@ -50,21 +53,16 @@
peg = "0.8.5"
pkg-config = "0.3.30"
rand = "0.10.0"
-regex = "1.11"
serde = { version = "1.0", features = ["derive"] }
-serde-transcode = "1.1.1"
serde_json = "1.0"
sha2 = "0.10"
shlex = "1.3"
tabled = "0.20.0"
tempfile = "3.20"
test-log = { version = "0.2.19", features = ["trace"] }
-tf-provider = "0.2.2"
thiserror = "2.0.12"
time = "0.3.41"
tokio = { version = "1.45.1", features = ["fs", "macros", "rt", "rt-multi-thread", "sync", "time"] }
-tokio-util = "0.7.17"
-toml_edit = "0.23.10"
tracing = "0.1"
tracing-indicatif = "0.3.13"
tracing-opentelemetry = "0.32.1"
cmds/fleet/Cargo.tomldiffbeforeafterboth--- a/cmds/fleet/Cargo.toml
+++ b/cmds/fleet/Cargo.toml
@@ -8,15 +8,13 @@
default-run = "fleet"
[dependencies]
-age = { workspace = true, features = ["armor"] }
anyhow.workspace = true
-better-command.workspace = true
+camino.workspace = true
clap.workspace = true
clap_complete.workspace = true
fleet-base.workspace = true
-fleet-shared.workspace = true
nix-eval.workspace = true
-nixlike.workspace = true
+remowt-fleet.workspace = true
serde.workspace = true
serde_json.workspace = true
tempfile.workspace = true
@@ -24,30 +22,17 @@
tracing.workspace = true
tracing-subscriber.workspace = true
-abort-on-drop.workspace = true
-age-core.workspace = true
-async-trait.workspace = true
-base64.workspace = true
-chrono.workspace = true
futures.workspace = true
-hostname.workspace = true
itertools.workspace = true
-openssh.workspace = true
-peg.workspace = true
-regex.workspace = true
shlex.workspace = true
tabled.workspace = true
-time = { workspace = true, features = ["serde"] }
-tokio-util = { workspace = true, features = ["codec"] }
human-repr = { workspace = true, optional = true }
indicatif = { workspace = true, optional = true }
-nom.workspace = true
opentelemetry.workspace = true
opentelemetry-appender-tracing.workspace = true
opentelemetry-exporter-env.workspace = true
opentelemetry_sdk.workspace = true
-thiserror.workspace = true
tracing-indicatif = { workspace = true, optional = true }
tracing-opentelemetry.workspace = true
@@ -58,6 +43,5 @@
"dep:tracing-indicatif",
"dep:indicatif",
"dep:human-repr",
- "better-command/indicatif",
"nix-eval/indicatif",
]
cmds/fleet/src/cmds/build_systems.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/build_systems.rs
+++ b/cmds/fleet/src/cmds/build_systems.rs
@@ -1,6 +1,7 @@
use std::{env::current_dir, os::unix::fs::symlink, path::PathBuf};
use anyhow::Result;
+use camino::Utf8PathBuf;
use clap::Parser;
use fleet_base::{
deploy::{DeployAction, deploy_task, upload_task},
@@ -29,7 +30,7 @@
build_attr: String,
}
-async fn build_task(config: Config, hostname: String, build_attr: &str) -> Result<PathBuf> {
+async fn build_task(config: Config, hostname: String, build_attr: &str) -> Result<Utf8PathBuf> {
info!("building");
let host = config.host(&hostname)?;
// let action = Action::from(self.subcommand.clone());
@@ -42,17 +43,20 @@
// We already have system profiles for backups.
if !host.local {
info!("adding gc root");
- let mut cmd = config.local_host().cmd("nix").await?;
- cmd.arg("build")
- .comparg(
- "--profile",
- format!(
- "/nix/var/nix/profiles/{}-{hostname}",
- config.data.gc_root_prefix
- ),
- )
- .arg(&out_output);
- cmd.sudo().run_nix().await?;
+ let local = config.local_host();
+ let plugin_id = local.ensure_nix_plugin().await?;
+ let nix = local
+ .remowt()
+ .await?
+ .plugin_endpoints::<remowt_fleet::NixClient<_>>(plugin_id);
+ let profile = format!(
+ "/nix/var/nix/profiles/{}-{hostname}",
+ config.data.gc_root_prefix
+ );
+ nix.switch_profile(profile, out_output.clone())
+ .await
+ .map_err(|e| anyhow::anyhow!("{e:?}"))?
+ .map_err(|e| anyhow::anyhow!("{e}"))?;
}
Ok(out_output)
cmds/fleet/src/cmds/tf.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/tf.rs
+++ b/cmds/fleet/src/cmds/tf.rs
@@ -1,6 +1,7 @@
-use std::{collections::BTreeMap, ffi::OsString, path::PathBuf};
+use std::{collections::BTreeMap, ffi::OsString};
use anyhow::{Context, Result};
+use camino::Utf8PathBuf;
use clap::Parser;
use fleet_base::host::Config;
use nix_eval::nix_go;
@@ -40,7 +41,7 @@
let system = &config.local_system;
let config = &config.flake_outputs;
let data = nix_go!(config.tf({ system }));
- let data: PathBuf = spawn_blocking(move || data.build("out"))
+ let data: Utf8PathBuf = spawn_blocking(move || data.build("out"))
.await
.expect("tf.json derivation should not fail")?;
let data = fs::read(&data).await?;
cmds/fleet/src/main.rsdiffbeforeafterboth--- a/cmds/fleet/src/main.rs
+++ b/cmds/fleet/src/main.rs
@@ -4,9 +4,10 @@
// pub(crate) mod command;
pub(crate) mod extra_args;
-use std::{env, ffi::OsString, process::ExitCode, sync::Arc};
+use std::{process::ExitCode, sync::Arc};
-use anyhow::{Result, bail};
+use anyhow::{Context as _, Result, bail};
+use camino::Utf8PathBuf;
use clap::{CommandFactory, Parser};
use cmds::{
build_systems::{BuildSystems, Deploy},
@@ -23,7 +24,8 @@
#[cfg(feature = "indicatif")]
use indicatif::{ProgressState, ProgressStyle};
use nix_eval::{
- gc_register_my_thread, gc_unregister_my_thread, init_libraries, init_tokio_for_nix,
+ add_file_to_store, gc_register_my_thread, gc_unregister_my_thread, init_libraries,
+ init_tokio_for_nix,
};
use opentelemetry::trace::TracerProvider;
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
@@ -48,24 +50,21 @@
}
let tasks = FuturesUnordered::new();
for entry in std::fs::read_dir(&prefetch_dir)? {
- tasks.push(async {
- let entry = entry?;
- if !entry.metadata()?.is_file() {
- bail!("only files should exist in prefetch directory");
- }
- let span = info_span!(
- "prefetching",
- name = entry.file_name().to_string_lossy().as_ref()
- );
- let mut path = OsString::new();
- path.push("file://");
- path.push(entry.path());
-
- let mut status = config.local_host().cmd("nix").await?;
- status.args(&config.nix_args);
- status.arg("store").arg("prefetch-file").arg(path);
- status.run_nix_string().instrument(span).await?;
- Ok(())
+ let entry = entry?;
+ if !entry.metadata()?.is_file() {
+ bail!("only files should exist in prefetch directory");
+ }
+ let name = entry.file_name().to_string_lossy().into_owned();
+ let path =
+ Utf8PathBuf::try_from(entry.path()).context("prefetch path should be utf8")?;
+ let span = info_span!("prefetching", name = %name);
+ tasks.push(async move {
+ let added = tokio::task::spawn_blocking(move || add_file_to_store(&name, &path))
+ .instrument(span.clone())
+ .await??;
+ let _g = span.enter();
+ info!("{} -> {}", added.hash, added.store_path);
+ anyhow::Ok(())
});
}
tasks.try_collect::<Vec<()>>().await?;
@@ -179,9 +178,7 @@
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
let reg = tracing_subscriber::registry().with({
- let sub = tracing_subscriber::fmt::layer()
- .without_time()
- .with_target(false);
+ let sub = tracing_subscriber::fmt::layer().without_time();
#[cfg(feature = "indicatif")]
let sub = sub.with_writer(indicatif_layer.get_stderr_writer());
sub.with_filter(filter) // .without,
@@ -262,14 +259,10 @@
}
async fn main_real(opts: RootOpts) -> Result<()> {
- let nix_args = std::env::var_os("NIX_ARGS")
- .map(|a| extra_args::parse_os(&a))
- .transpose()?
- .unwrap_or_default();
- let config = opts.fleet_opts.build(
- nix_args,
- matches!(opts.command, Opts::Deploy(_) | Opts::BuildSystems(_)),
- )?;
+ let config = opts.fleet_opts.build(matches!(
+ opts.command,
+ Opts::Deploy(_) | Opts::BuildSystems(_)
+ ))?;
match run_command(&config, opts.fleet_opts, opts.command).await {
Ok(()) => {
cmds/install-secrets/src/main.rsdiffbeforeafterboth--- a/cmds/install-secrets/src/main.rs
+++ b/cmds/install-secrets/src/main.rs
@@ -227,7 +227,6 @@
.from_env_lossy(),
)
.without_time()
- .with_target(false)
.init();
let opts = Opts::parse();
cmds/nix-plugin-fleet/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/cmds/nix-plugin-fleet/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "nix-plugin-fleet"
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+
+[lib]
+crate-type = ["cdylib"]
+
+[dependencies]
+fleet-base.workspace = true
cmds/nix-plugin-fleet/src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/cmds/nix-plugin-fleet/src/lib.rs
@@ -0,0 +1,7 @@
+use fleet_base::primops::init_primops;
+
+/// SAFETY: expected plugin dynamic library entry point
+#[unsafe(no_mangle)]
+fn nix_plugin_entry() {
+ init_primops();
+}
cmds/remowt-plugin-fleet/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/cmds/remowt-plugin-fleet/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "remowt-plugin-fleet"
+description = "Remowt plugin exposing fleet's Nix endpoint to a running agent"
+version.workspace = true
+edition = "2021"
+
+[dependencies]
+remowt-fleet.workspace = true
+remowt-plugin.workspace = true
+
+anyhow.workspace = true
cmds/remowt-plugin-fleet/src/main.rsdiffbeforeafterboth--- /dev/null
+++ b/cmds/remowt-plugin-fleet/src/main.rs
@@ -0,0 +1,8 @@
+use remowt_fleet::{Nix, init_libraries};
+
+fn main() -> anyhow::Result<()> {
+ remowt_plugin::run(|rpc| {
+ init_libraries();
+ Nix.register_endpoints(rpc);
+ })
+}
cmds/repl-plugin-unstable/Cargo.tomldiffbeforeafterboth--- a/cmds/repl-plugin-unstable/Cargo.toml
+++ /dev/null
@@ -1,11 +0,0 @@
-[package]
-name = "repl-plugin-unstable"
-version.workspace = true
-edition.workspace = true
-rust-version.workspace = true
-
-[lib]
-crate-type = ["cdylib"]
-
-[dependencies]
-fleet-base.workspace = true
cmds/repl-plugin-unstable/src/lib.rsdiffbeforeafterboth--- a/cmds/repl-plugin-unstable/src/lib.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-use fleet_base::primops::init_primops;
-
-/// SAFETY: expected plugin dynamic library entry point
-#[unsafe(no_mangle)]
-fn nix_plugin_entry() {
- init_primops();
-}
cmds/terraform-provider-fleet/Cargo.tomldiffbeforeafterboth--- a/cmds/terraform-provider-fleet/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "terraform-provider-fleet"
-version.workspace = true
-edition.workspace = true
-rust-version.workspace = true
-
-[dependencies]
-anyhow.workspace = true
-serde = { workspace = true, features = ["derive"] }
-tokio.workspace = true
-
-async-trait.workspace = true
-tf-provider.workspace = true
cmds/terraform-provider-fleet/src/main.rsdiffbeforeafterboth--- a/cmds/terraform-provider-fleet/src/main.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main() {
- panic!(
- "this is a stub, real provider is in development, I just don't want to keep it in different branch."
- )
-}
crates/better-command/Cargo.tomldiffbeforeafterbothno changes
crates/better-command/src/handler.rsdiffbeforeafterboth--- a/crates/better-command/src/handler.rs
+++ /dev/null
@@ -1,335 +0,0 @@
-//! Collection of handlers, which transform program-specific stdout format to tracing
-
-use std::{
- collections::HashMap,
- sync::{Arc, LazyLock, Mutex},
-};
-
-use regex::Regex;
-use serde::Deserialize;
-use tracing::{Span, info, info_span, warn};
-#[cfg(feature = "indicatif")]
-use tracing_indicatif::span_ext::IndicatifSpanExt as _;
-
-pub trait Handler: Send {
- fn handle_line(&mut self, e: &str);
-}
-
-/// Handler wrapper, which can be cloned.
-pub struct ClonableHandler<H>(Arc<Mutex<H>>);
-impl<H> Clone for ClonableHandler<H> {
- fn clone(&self) -> Self {
- Self(self.0.clone())
- }
-}
-impl<H> ClonableHandler<H> {
- pub fn new(inner: H) -> Self {
- Self(Arc::new(Mutex::new(inner)))
- }
-}
-impl<H: Handler> Handler for ClonableHandler<H> {
- fn handle_line(&mut self, e: &str) {
- self.0.lock().unwrap().handle_line(e)
- }
-}
-
-/// Converts command output to tracing lines
-pub struct PlainHandler;
-impl Handler for PlainHandler {
- fn handle_line(&mut self, e: &str) {
- info!(target: "log", "{e}");
- }
-}
-
-/// Ignores output
-pub struct NoopHandler;
-impl Handler for NoopHandler {
- fn handle_line(&mut self, _e: &str) {}
-}
-
-/// Transform nix internal-json logs to tracing spans.
-#[derive(Default)]
-pub struct NixHandler {
- spans: HashMap<u64, Span>,
-}
-#[derive(Deserialize, Debug)]
-#[serde(untagged)]
-enum LogField {
- String(String),
- Num(u64),
-}
-
-/// Nix internal-json log line type
-#[derive(Deserialize, Debug)]
-#[serde(rename_all = "camelCase", tag = "action")]
-#[allow(dead_code)]
-enum NixLog {
- Msg {
- level: u32,
- msg: String,
- raw_msg: Option<String>,
- },
- Start {
- id: u64,
- level: u32,
- #[serde(default)]
- fields: Vec<LogField>,
- text: String,
- #[serde(rename = "type")]
- typ: u32,
- },
- Stop {
- id: u64,
- },
- Result {
- id: u64,
- #[serde(rename = "type")]
- typ: u32,
- #[serde(default)]
- fields: Vec<LogField>,
- },
-}
-fn process_message(m: &str) -> String {
- // Supposed to remove formatting characters except colors, as some programs try to reset cursor position etc.
- static OSC_CLEANER: LazyLock<Regex> =
- LazyLock::new(|| Regex::new(r"\x1B\]([^\x07\x1C]*[\x07\x1C])?|\r").unwrap());
- static DETABBER: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"\t").unwrap());
- let m = OSC_CLEANER.replace_all(m, "");
- // Indicatif can't format tabs. This is not the correct tab formatting, as correct one should be aligned,
- // and not just be replaced with the constant number of spaces, but it's ok for now, as statuses are single-line.
- DETABBER.replace_all(m.as_ref(), " ").to_string()
-}
-impl Handler for NixHandler {
- fn handle_line(&mut self, e: &str) {
- if let Some(e) = e.strip_prefix("@nix ") {
- let log: NixLog = match serde_json::from_str(e) {
- Ok(l) => l,
- Err(err) => {
- warn!("failed to parse nix log line {:?}: {}", e, err);
- return;
- }
- };
- match log {
- NixLog::Msg { msg, raw_msg, .. } => {
- #[allow(clippy::nonminimal_bool)]
- if !(msg.starts_with("\u{1b}[35;1mwarning:\u{1b}[0m Git tree '")
- && msg.ends_with("' is dirty"))
- && !msg.starts_with(
- "\u{1b}[35;1mwarning:\u{1b}[0m not writing modified lock file of flake",
- ) && msg
- != "\u{1b}[35;1mwarning:\u{1b}[0m \u{1b}[31;1merror:\u{1b}[0m SQLite database '\u{1b}[35;1m/nix/var/nix/db/db.sqlite\u{1b}[0m' is busy"
- {
- if let Some(raw_msg) = raw_msg {
- if !msg.is_empty() {
- info!(target: "nix", "{}\n{}", raw_msg.trim_end(), msg.trim_end())
- } else {
- info!(target: "nix", "{}", raw_msg.trim_end())
- }
- } else {
- info!(target: "nix", "{}", msg.trim_end())
- }
- }
- }
- NixLog::Start {
- ref fields,
- typ,
- id,
- ..
- } if typ == 105 && !fields.is_empty() => {
- if let [LogField::String(drv), ..] = &fields[..] {
- let mut drv = drv.as_str();
- if let Some(pkg) = drv.strip_prefix("/nix/store/") {
- let mut it = pkg.splitn(2, '-');
- it.next();
- if let Some(pkg) = it.next() {
- drv = pkg;
- }
- }
- info!(target: "nix","building {}", drv);
- let span = info_span!("build", drv);
- #[cfg(feature = "indicatif")]
- span.pb_start();
- self.spans.insert(id, span);
- } else {
- warn!("bad build log: {:?}", log)
- }
- }
- NixLog::Start {
- ref fields,
- typ,
- id,
- ..
- } if typ == 100 && fields.len() >= 3 => {
- if let [
- LogField::String(drv),
- LogField::String(from),
- LogField::String(to),
- ..,
- ] = &fields[..]
- {
- let mut drv = drv.as_str();
-
- if let Some(pkg) = drv.strip_prefix("/nix/store/") {
- let mut it = pkg.splitn(2, '-');
- it.next();
- if let Some(pkg) = it.next() {
- drv = pkg;
- }
- }
- info!(target: "nix","copying {} {} -> {}", drv, from, to);
- let span = info_span!("copy", from, to, drv);
- #[cfg(feature = "indicatif")]
- span.pb_start();
- self.spans.insert(id, span);
- } else {
- warn!("bad copy log: {:?}", log)
- }
- }
- NixLog::Start { text, typ, id, .. }
- if typ == 0 || typ == 102 || typ == 103 || typ == 104 =>
- {
- if !text.is_empty()
- && text != "querying info about missing paths"
- && text != "copying 0 paths"
- // Too much spam on lazy-trees branch
- && !(text.starts_with("copying '") && text.ends_with("' to the store"))
- {
- let span = info_span!("job");
- #[cfg(feature = "indicatif")]
- {
- span.pb_start();
- span.pb_set_message(&process_message(text.trim()));
- }
- self.spans.insert(id, span);
- info!(target: "nix", "{}", text);
- }
- }
- NixLog::Start {
- text,
- level: 0,
- typ: 108,
- ..
- } if text.is_empty() => {
- // Cache lookup? Coupled with copy log
- }
- NixLog::Start {
- text,
- level: 4,
- typ: 109,
- ..
- } if text.starts_with("querying info about ") => {
- // Cache lookup
- }
- NixLog::Start {
- text,
- level: 4,
- typ: 101,
- ..
- } if text.starts_with("downloading ") => {
- // NAR downloading, coupled with copy log
- }
- NixLog::Start {
- text,
- level: 1,
- typ: 111,
- ..
- } if text.starts_with("waiting for a machine to build ") => {
- // Useless repeating notification about build
- }
- NixLog::Start {
- text,
- level: 3,
- typ: 111,
- ..
- } if text.starts_with("resolved derivation: ") => {
- // CA resolved
- }
- NixLog::Start {
- text,
- level: 1,
- typ: 111,
- id,
- ..
- } if text.starts_with("waiting for lock on ") => {
- let mut drv = text.strip_prefix("waiting for lock on ").unwrap();
- if let Some(txt) = drv.strip_prefix("\u{1b}[35;1m'") {
- drv = txt;
- }
- if let Some(txt) = drv.strip_suffix("'\u{1b}[0m") {
- drv = txt;
- }
- if let Some(txt) = drv.split("', '").next() {
- drv = txt;
- }
- if let Some(pkg) = drv.strip_prefix("/nix/store/") {
- let mut it = pkg.splitn(2, '-');
- it.next();
- if let Some(pkg) = it.next() {
- drv = pkg;
- }
- }
- let span = info_span!("waiting on drv", drv);
- #[cfg(feature = "indicatif")]
- span.pb_start();
- self.spans.insert(id, span);
- // Concurrent build of the same message
- }
- NixLog::Stop { id, .. } => {
- self.spans.remove(&id);
- }
- NixLog::Result { fields, id, typ } if typ == 101 && !fields.is_empty() => {
- if let Some(span) = self.spans.get(&id) {
- if let LogField::String(s) = &fields[0] {
- #[cfg(feature = "indicatif")]
- span.pb_set_message(&process_message(s.trim()));
- #[cfg(not(feature = "indicatif"))]
- {
- let _span = span.enter();
- info!("{}", process_message(s));
- }
- } else {
- warn!("bad fields: {fields:?}");
- }
- } else {
- warn!("unknown result id: {id} {typ} {fields:?}");
- }
- // dbg!(fields, id, typ);
- }
- NixLog::Result { fields, id, typ } if typ == 105 && fields.len() >= 4 => {
- if let Some(span) = self.spans.get(&id) {
- if let [
- LogField::Num(done),
- LogField::Num(expected),
- LogField::Num(_running),
- LogField::Num(_failed),
- ] = &fields[..4]
- {
- #[cfg(feature = "indicatif")]
- {
- span.pb_set_length(*expected);
- span.pb_set_position(*done);
- }
- let _ = (span, done, expected);
- } else {
- warn!("bad fields: {fields:?}");
- }
- } else {
- // warn!("unknown result id: {id} {typ} {fields:?}");
- // Unaccounted progress.
- }
- // dbg!(fields, id, typ);
- }
- NixLog::Result { typ, .. } if typ == 104 || typ == 106 => {
- // Set phase, expected
- }
- _ => warn!("unknown log: {:?}", log),
- };
- } else {
- let e = e.trim();
- if e.starts_with("Failed tcsetattr(TCSADRAIN): ") {
- return;
- }
- info!("{e}")
- }
- }
-}
crates/better-command/src/lib.rsdiffbeforeafterboth--- a/crates/better-command/src/lib.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-mod handler;
-pub use handler::{ClonableHandler, Handler, NixHandler, NoopHandler, PlainHandler};
crates/fleet-base/Cargo.tomldiffbeforeafterboth--- a/crates/fleet-base/Cargo.toml
+++ b/crates/fleet-base/Cargo.toml
@@ -5,9 +5,15 @@
rust-version.workspace = true
[dependencies]
+remowt-client.workspace = true
+remowt-endpoints.workspace = true
+remowt-fleet.workspace = true
+remowt-link-shared.workspace = true
+remowt-ui-prompt.workspace = true
+
age.workspace = true
anyhow.workspace = true
-better-command.workspace = true
+camino.workspace = true
chrono.workspace = true
clap = { workspace = true, features = ["derive"] }
fleet-shared.workspace = true
@@ -18,15 +24,11 @@
nix-eval.workspace = true
nixlike.workspace = true
nom.workspace = true
-openssh.workspace = true
rand.workspace = true
serde.workspace = true
serde_json.workspace = true
tabled.workspace = true
tempfile.workspace = true
-thiserror.workspace = true
time = { workspace = true, features = ["parsing"] }
tokio.workspace = true
-tokio-util = { workspace = true, features = ["codec"] }
-toml_edit.workspace = true
tracing.workspace = true
crates/fleet-base/src/command.rsdiffbeforeafterboth--- a/crates/fleet-base/src/command.rs
+++ /dev/null
@@ -1,442 +0,0 @@
-use std::{ffi::OsStr, pin, process::Stdio, sync::Arc, task::Poll};
-
-use anyhow::{Result, anyhow};
-use better_command::{Handler, NixHandler, PlainHandler};
-use futures::StreamExt;
-use itertools::Either;
-use openssh::{OverSsh, OwningCommand, Session};
-use serde::de::DeserializeOwned;
-use tokio::{io::AsyncRead, process::Command, select};
-use tokio_util::codec::{BytesCodec, FramedRead, LinesCodec};
-use tracing::debug;
-
-use crate::host::EscalationStrategy;
-
-fn escape_bash(input: &str, out: &mut String) {
- const TO_ESCAPE: &str = "$ !\"#&'()*,;<>?[\\]^`{|}";
- if input.chars().all(|c| !TO_ESCAPE.contains(c)) {
- out.push_str(input);
- return;
- }
- out.push('\'');
- for (i, v) in input.split('\'').enumerate() {
- if i != 0 {
- out.push_str("'\"'\"'");
- }
- out.push_str(v);
- }
- out.push('\'');
-}
-fn ostoutf8(os: impl AsRef<OsStr>) -> String {
- os.as_ref().to_str().expect("non-utf8 data").to_owned()
-}
-
-#[derive(Clone, Debug)]
-pub struct MyCommand {
- command: String,
- args: Vec<String>,
- env: Vec<(String, String)>,
- ssh_session: Option<Arc<Session>>,
- escalation: EscalationStrategy,
- escalate: bool,
-}
-impl MyCommand {
- pub fn new_on(
- escalation: EscalationStrategy,
- cmd: impl AsRef<OsStr>,
- session: Arc<Session>,
- ) -> Self {
- assert!(!cmd.as_ref().is_empty());
- Self {
- command: ostoutf8(cmd),
- args: vec![],
- env: vec![],
- ssh_session: Some(session),
- escalation,
- escalate: false,
- }
- }
- pub fn new(escalation: EscalationStrategy, cmd: impl AsRef<OsStr>) -> Self {
- assert!(!cmd.as_ref().is_empty());
- Self {
- command: ostoutf8(cmd),
- args: vec![],
- env: vec![],
- ssh_session: None,
- escalation,
- escalate: false,
- }
- }
- fn new_here(&self, cmd: impl AsRef<OsStr>) -> Self {
- match self.ssh_session.clone() {
- Some(ssh_session) => Self::new_on(self.escalation, cmd, ssh_session),
- _ => Self::new(self.escalation, cmd),
- }
- }
-
- fn into_args(self) -> Vec<String> {
- let mut out = Vec::new();
- if !self.env.is_empty() {
- out.push("env".to_owned());
- for (k, v) in self.env {
- assert!(!k.contains('='));
- out.push(format!("{k}={v}"));
- }
- }
- out.push(self.command);
- out.extend(self.args);
- out
- }
-
- /// Translates environment variables into env command execution.
- /// Required for ssh, as ssh don't allow to send environment variables (at least by default).
- ///
- /// FIXME: Insecure, as arguments might be seen by other users on the same machine.
- /// Figure out some way to transfer environment using stdio?
- fn translate_env_into_env(self) -> Self {
- if self.env.is_empty() {
- return self;
- }
- let mut out = self.new_here("env");
- for (k, v) in self.env {
- assert!(!k.contains('='));
- out.arg(format!("{k}={v}"));
- }
- out.arg(self.command);
- out.args(self.args);
-
- out
- }
- fn into_string(self) -> String {
- let mut out = String::new();
- if !self.env.is_empty() {
- out.push_str("env");
- for (k, v) in self.env {
- out.push(' ');
- assert!(!k.contains('='));
- escape_bash(&k, &mut out);
- out.push('=');
- escape_bash(&v, &mut out);
- }
- }
- if !out.is_empty() {
- out.push(' ');
- }
- escape_bash(&self.command, &mut out);
- for arg in self.args {
- out.push(' ');
- escape_bash(&arg, &mut out);
- }
- out
- }
- fn into_command_unchecked_local(self) -> Command {
- let mut out = Command::new(self.command);
- out.args(self.args);
- for (k, v) in self.env {
- out.env(k, v);
- }
- out
- }
- fn into_command(self) -> Result<Either<Command, openssh::OwningCommand<Arc<Session>>>> {
- Ok(match self.ssh_session.clone() {
- Some(session) => {
- let cmd = self.translate_env_into_env().into_command_unchecked_local();
- Either::Right(
- cmd.over_ssh(session)
- .map_err(|e| anyhow!("ssh error: {e}"))?,
- )
- }
- _ => {
- let cmd = self.into_command_unchecked_local();
- Either::Left(cmd)
- }
- })
- }
- pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
- let arg = arg.as_ref();
- self.args.push(ostoutf8(arg));
- self
- }
- pub fn eqarg(&mut self, arg: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Self {
- let arg = arg.as_ref();
- let value = value.as_ref();
- let arg = ostoutf8(arg);
- let value = ostoutf8(value);
- self.arg(format!("{arg}={value}"));
- self
- }
- pub fn comparg(&mut self, arg: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Self {
- self.arg(arg);
- self.arg(value);
- self
- }
- pub fn env(&mut self, name: impl AsRef<str>, value: impl AsRef<str>) -> &mut Self {
- self.env
- .push((name.as_ref().to_owned(), value.as_ref().to_owned()));
- self
- }
- pub fn args<V: AsRef<OsStr>>(&mut self, args: impl IntoIterator<Item = V>) -> &mut Self {
- for arg in args.into_iter() {
- let arg = arg.as_ref();
- self.args.push(ostoutf8(arg));
- }
- self
- }
- pub fn sudo(mut self) -> Self {
- self.escalate = true;
- self
- }
- fn wrap_sudo_if_needed(self) -> Self {
- if !self.escalate {
- return self;
- }
- match self.escalation {
- EscalationStrategy::Su => {
- let mut out = self.new_here("su");
- out.arg("-c").arg(self.into_string());
- out
- }
- EscalationStrategy::Sudo => {
- let mut out = self.new_here("sudo");
- out.args(self.into_args());
- out
- }
- EscalationStrategy::Run0 => {
- // run0 wants interactive authentication by default.
- let mut run0 = self.new_here("run0");
- let mut out = self.new_here("script");
-
- // Red backgrounds messes with fleet formatting
- run0.arg("--background=");
- run0.args(self.into_args());
-
- out.arg("-q");
- out.arg("/dev/null");
- out.arg("-c");
- out.arg(run0.into_string());
- dbg!(&out);
- out
- }
- }
- }
-
- pub async fn run(self) -> Result<()> {
- let str = self.clone().into_string();
- let cmd = self.wrap_sudo_if_needed().into_command()?;
- match cmd {
- Either::Left(cmd) => run_nix_inner(str, cmd, &mut PlainHandler).await?,
- Either::Right(cmd) => run_nix_inner_ssh(str, cmd, &mut PlainHandler).await?,
- };
- Ok(())
- }
- pub async fn run_string(self) -> Result<String> {
- let bytes = self.run_bytes().await?;
- Ok(String::from_utf8(bytes)?)
- }
- pub async fn run_value<T: DeserializeOwned>(self) -> Result<T> {
- let v = self.run_string().await?;
- Ok(serde_json::from_str(&v)?)
- }
- pub async fn run_bytes(self) -> Result<Vec<u8>> {
- let str = self.clone().into_string();
- let cmd = self.wrap_sudo_if_needed().into_command()?;
- let v = match cmd {
- Either::Left(cmd) => run_nix_inner_stdout(str, cmd, &mut PlainHandler).await?,
- Either::Right(cmd) => run_nix_inner_stdout_ssh(str, cmd, &mut PlainHandler).await?,
- };
- Ok(v)
- }
-
- pub async fn run_nix_string(mut self) -> Result<String> {
- let str = self.clone().into_string();
- self.arg("--log-format").arg("internal-json");
- let cmd = self.wrap_sudo_if_needed().into_command()?;
- let bytes = match cmd {
- Either::Left(cmd) => run_nix_inner_stdout(str, cmd, &mut NixHandler::default()).await?,
- Either::Right(cmd) => {
- run_nix_inner_stdout_ssh(str, cmd, &mut NixHandler::default()).await?
- }
- };
- Ok(String::from_utf8(bytes)?)
- }
- pub async fn run_nix(mut self) -> Result<()> {
- let str = self.clone().into_string();
- self.arg("--log-format").arg("internal-json");
- let cmd = self.wrap_sudo_if_needed().into_command()?;
- match cmd {
- Either::Left(mut cmd) => {
- cmd.stdout(Stdio::inherit());
- run_nix_inner(str, cmd, &mut NixHandler::default()).await
- }
- Either::Right(mut cmd) => {
- cmd.stdout(openssh::Stdio::inherit());
- run_nix_inner_ssh(str, cmd, &mut NixHandler::default()).await
- }
- }
- }
-}
-
-struct EmptyAsyncRead;
-impl AsyncRead for EmptyAsyncRead {
- fn poll_read(
- self: std::pin::Pin<&mut Self>,
- _cx: &mut std::task::Context<'_>,
- _buf: &mut tokio::io::ReadBuf<'_>,
- ) -> Poll<std::io::Result<()>> {
- Poll::Pending
- }
-}
-
-async fn run_nix_inner_stdout(
- str: String,
- cmd: Command,
- handler: &mut dyn Handler,
-) -> Result<Vec<u8>> {
- Ok(run_nix_inner_raw(str, cmd, true, handler, None)
- .await?
- .expect("has out"))
-}
-async fn run_nix_inner(str: String, cmd: Command, handler: &mut dyn Handler) -> Result<()> {
- let v = run_nix_inner_raw(str, cmd, false, handler, None).await?;
- assert!(v.is_none());
- Ok(())
-}
-async fn run_nix_inner_stdout_ssh(
- str: String,
- cmd: OwningCommand<Arc<Session>>,
- handler: &mut dyn Handler,
-) -> Result<Vec<u8>> {
- Ok(run_nix_inner_raw_ssh(str, cmd, true, handler, None)
- .await?
- .expect("has out"))
-}
-async fn run_nix_inner_ssh(
- str: String,
- cmd: OwningCommand<Arc<Session>>,
- handler: &mut dyn Handler,
-) -> Result<()> {
- let v = run_nix_inner_raw_ssh(str, cmd, false, handler, None).await?;
- assert!(v.is_none());
- Ok(())
-}
-
-async fn run_nix_inner_raw(
- str: String,
- mut cmd: Command,
- want_stdout: bool,
- err_handler: &mut dyn Handler,
- mut out_handler: Option<&mut dyn Handler>,
-) -> Result<Option<Vec<u8>>> {
- cmd.stderr(Stdio::piped());
- cmd.stdout(Stdio::piped());
- debug!("running command {str:?} on local");
- let mut child = cmd.spawn()?;
- let mut stderr = child.stderr.take().unwrap();
- let stdout = child.stdout.take().unwrap();
- let mut err = FramedRead::new(&mut stderr, LinesCodec::new());
- let mut out: Option<Box<dyn AsyncRead + Unpin + Send>> = Some(Box::new(stdout));
- let mut ob = want_stdout
- .then(|| out.take().unwrap())
- .unwrap_or_else(|| Box::new(EmptyAsyncRead));
- let mut ol = (!want_stdout)
- .then(|| out.take().unwrap())
- .unwrap_or_else(|| Box::new(EmptyAsyncRead));
- let mut ob = FramedRead::new(&mut ob, BytesCodec::new());
- let mut ol = FramedRead::new(&mut ol, LinesCodec::new());
-
- // while let Some(line) = read.next().await? {}
-
- let mut out_buf = if want_stdout { Some(vec![]) } else { None };
- loop {
- select! {
- biased;
-
- Some(e) = err.next() => {
- let e = e?;
- err_handler.handle_line(&e);
- },
- Some(o) = ob.next() => {
- out_buf.as_mut().expect("stdout == wants_stdout").extend_from_slice(&o?);
- },
- Some(o) = ol.next() => {
- let o = o?;
- if let Some(out) = out_handler.as_mut() {
- out.handle_line(&o)
- } else {
- err_handler.handle_line(&o)
- }
- // out_handler.handle_info(&o);
- },
- code = child.wait() => {
- let code = code?;
- if !code.success() {
- anyhow::bail!("command '{str}' failed with status {}", code);
- }
- break;
- }
- }
- }
-
- Ok(out_buf)
-}
-async fn run_nix_inner_raw_ssh(
- str: String,
- mut cmd: OwningCommand<Arc<Session>>,
- want_stdout: bool,
- err_handler: &mut dyn Handler,
- mut out_handler: Option<&mut dyn Handler>,
-) -> Result<Option<Vec<u8>>> {
- debug!("running command {str:?} over ssh");
- cmd.stderr(openssh::Stdio::piped());
- cmd.stdout(openssh::Stdio::piped());
- let mut child = cmd.spawn().await?;
- let mut stderr = child.stderr().take().unwrap();
- let stdout = child.stdout().take().unwrap();
- let mut err = FramedRead::new(&mut stderr, LinesCodec::new());
- let mut out: Option<Box<dyn AsyncRead + Unpin + Send>> = Some(Box::new(stdout));
- let mut ob = want_stdout
- .then(|| out.take().unwrap())
- .unwrap_or_else(|| Box::new(EmptyAsyncRead));
- let mut ol = (!want_stdout)
- .then(|| out.take().unwrap())
- .unwrap_or_else(|| Box::new(EmptyAsyncRead));
- let mut ob = FramedRead::new(&mut ob, BytesCodec::new());
- let mut ol = FramedRead::new(&mut ol, LinesCodec::new());
-
- // while let Some(line) = read.next().await? {}
-
- let mut out_buf = if want_stdout { Some(vec![]) } else { None };
-
- let mut wait_future = pin::pin!(child.wait());
- loop {
- select! {
- biased;
-
- Some(e) = err.next() => {
- let e = e?;
- err_handler.handle_line(&e);
- },
- Some(o) = ob.next() => {
- out_buf.as_mut().expect("stdout == wants_stdout").extend_from_slice(&o?);
- },
- Some(o) = ol.next() => {
- let o = o?;
- if let Some(out) = out_handler.as_mut() {
- out.handle_line(&o)
- } else {
- err_handler.handle_line(&o)
- }
- // out_handler.handle_info(&o);
- },
- code = &mut wait_future => {
- let code = code?;
- if !code.success() {
- anyhow::bail!("command '{str}' failed with status {}", code);
- }
- break;
- }
- }
- }
-
- Ok(out_buf)
-}
crates/fleet-base/src/deploy.rsdiffbeforeafterboth--- a/crates/fleet-base/src/deploy.rs
+++ b/crates/fleet-base/src/deploy.rs
@@ -1,8 +1,13 @@
-use std::{path::PathBuf, time::Duration};
+use std::time::Duration;
use anyhow::{Context as _, Result, anyhow, bail};
+use camino::Utf8PathBuf;
use clap::ValueEnum;
use itertools::Itertools;
+use remowt_endpoints::fs::FsClient;
+use remowt_endpoints::systemd::SystemdClient;
+use remowt_fleet::NixClient;
+use remowt_link_shared::BifConfig;
use tokio::time::sleep;
use tracing::{Instrument as _, error, info, info_span, warn};
@@ -59,10 +64,11 @@
pub async fn deploy_task(
action: DeployAction,
host: &ConfigHost,
- built: PathBuf,
+ built: Utf8PathBuf,
specialisation: Option<String>,
disable_rollback: bool,
) -> Result<()> {
+ let remowt = host.remowt().await?;
let deploy_kind = host.deploy_kind().await?;
if (deploy_kind == DeployKind::NixosInstall || deploy_kind == DeployKind::NixosLustrate)
&& !matches!(action, DeployAction::Boot | DeployAction::Upload)
@@ -86,7 +92,7 @@
generation.id, generation.datetime
);
{
- let mut cmd = host.cmd("sh").await?;
+ let mut cmd = remowt.cmd("sh");
cmd.arg("-c").arg(format!("mark=$(mktemp -p /etc -t fleet_rollback_marker.XXXXX) && echo -n {} > $mark && mv --no-clobber $mark /etc/fleet_rollback_marker", generation.id));
if let Err(e) = cmd.sudo().run().await {
error!("failed to set rollback marker: {e}");
@@ -104,7 +110,7 @@
// if we fail to perform generation switch in time, then we will still call the activation script, and this may break something.
// Anyway, reboot will still help in this case.
if action.should_schedule_rollback_run() {
- let mut cmd = host.cmd("systemd-run").await?;
+ let mut cmd = remowt.cmd("systemd-run");
cmd.comparg("--on-active", "3min")
.comparg("--unit", "rollback-watchdog-run")
.arg("systemctl")
@@ -116,14 +122,20 @@
}
}
}
+
+ let remowt = host.remowt().await?;
+ let fs = remowt.endpoints::<FsClient<_>>();
if deploy_kind == DeployKind::NixosLustrate {
// Fleet could also create this file, but as this operation is potentially disruptive,
// make user do it themself.
- if !host.file_exists("/etc/NIXOS_LUSTRATE").await? {
+ if !fs
+ .file_exists(Utf8PathBuf::from("/etc/NIXOS_LUSTRATE"))
+ .await?
+ {
bail!("/etc/NIXOS_LUSTRATE should be created on remote host");
}
// Wanted by NixOS to recognize the system as NixOS.
- let mut cmd = host.cmd("touch").await?;
+ let mut cmd = remowt.cmd("touch");
cmd.arg("/etc/NIXOS");
cmd.sudo().run().await.context("creating /etc/NIXOS")?;
}
@@ -131,7 +143,7 @@
info!(
"running nixos-install to switch profile, install bootloader, and perform activation"
);
- let mut cmd = host.cmd("nixos-install").await?;
+ let mut cmd = remowt.cmd("nixos-install");
cmd.arg("--system").arg(&built).args([
// Channels here aren't fleet host system channels, but channels embedded in installation cd, which might be old.
// It is possible to copy host channels, but I would prefer non-flake nix just to be unsupported.
@@ -147,32 +159,38 @@
if action.should_switch_profile() && !failed {
info!("switching system profile generation");
- // To avoid even more problems, using nixos-install for now.
- // // nix build is unable to work with --store argument for some reason, and nix until 2.26 didn't support copy with --profile argument,
- // // falling back to using nix-env command
- // // After stable NixOS starts using 2.26 - use `nix --store /mnt copy --from /mnt --profile ...` here, and instead of nix build below.
- // let mut cmd = host.cmd("nix-env").await?;
- // cmd.args([
- // "--store",
- // "/mnt",
- // "--profile",
- // "/mnt/nix/var/nix/profiles/system",
- // "--set",
- // ])
- // .arg(&built);
- // if let Err(e) = cmd.sudo().run_nix().await {
- // error!("failed to switch system profile generation: {e}");
- // failed = true;
- // }
- // It would also be possible to update profile atomically during copy:
- // https://github.com/NixOS/nix/pull/11657
- let mut cmd = host.nix_cmd().await?;
- cmd.arg("build");
- cmd.comparg("--profile", "/nix/var/nix/profiles/system");
- cmd.arg(&built);
- if let Err(e) = cmd.sudo().run_nix().await {
- error!("failed to switch system profile generation: {e}");
- failed = true;
+ match host.ensure_nix_plugin().await {
+ Ok(plugin_id) => {
+ let nix_elevated = remowt.plugin_endpoints::<NixClient<_>>(plugin_id);
+ // To avoid even more problems, using nixos-install for now.
+ // // nix build is unable to work with --store argument for some reason, and nix until 2.26 didn't support copy with --profile argument,
+ // // falling back to using nix-env command
+ // // After stable NixOS starts using 2.26 - use `nix --store /mnt copy --from /mnt --profile ...` here, and instead of nix build below.
+ // let mut cmd = host.cmd("nix-env").await?;
+ // cmd.args([
+ // "--store",
+ // "/mnt",
+ // "--profile",
+ // "/mnt/nix/var/nix/profiles/system",
+ // "--set",
+ // ])
+ // .arg(&built);
+ // if let Err(e) = cmd.sudo().run_nix().await {
+ // error!("failed to switch system profile generation: {e}");
+ // failed = true;
+ // }
+ if let Err(e) = nix_elevated
+ .switch_profile("/nix/var/nix/profiles/system".to_owned(), built.clone())
+ .await
+ {
+ error!("failed to switch system profile generation: {e}");
+ failed = true;
+ }
+ }
+ Err(e) => {
+ failed = true;
+ error!("failed to enable nix plugin: {e:?}");
+ }
}
}
@@ -189,7 +207,7 @@
built.clone()
};
let switch_script = specialised.join("bin/switch-to-configuration");
- let mut cmd = host.cmd("systemd-run").in_current_span().await?;
+ let mut cmd = remowt.cmd("systemd-run");
if deploy_kind == DeployKind::NixosLustrate {
cmd.arg("--setenv=NIXOS_INSTALL_BOOTLOADER=1");
}
@@ -209,12 +227,14 @@
}
}
if action.should_create_rollback_marker() {
+ let elevated_systemd = remowt.run0_endpoints::<SystemdClient<BifConfig>>().await?;
+ let elevated_fs = remowt.run0_endpoints::<FsClient<BifConfig>>().await?;
if !disable_rollback {
if failed {
if action.should_schedule_rollback_run() {
info!("executing rollback");
- if let Err(e) = host
- .systemctl_start("rollback-watchdog.service")
+ if let Err(e) = elevated_systemd
+ .start("rollback-watchdog.service".to_owned())
.instrument(info_span!("rollback"))
.await
{
@@ -223,8 +243,8 @@
}
} else {
info!("trying to mark upgrade as successful");
- if let Err(e) = host
- .rm_file("/etc/fleet_rollback_marker", true)
+ if let Err(e) = elevated_fs
+ .rm_file(Utf8PathBuf::from("/etc/fleet_rollback_marker"))
.in_current_span()
.await
{
@@ -234,16 +254,22 @@
}
}
info!("disarming watchdog, just in case");
- if let Err(_e) = host.systemctl_stop("rollback-watchdog.timer").await {
+ if let Err(_e) = elevated_systemd
+ .stop("rollback-watchdog.timer".to_owned())
+ .await
+ {
// It is ok, if there was no reboot - then timer might not be running.
}
if action.should_schedule_rollback_run() {
- if let Err(e) = host.systemctl_stop("rollback-watchdog-run.timer").await {
+ if let Err(e) = elevated_systemd
+ .stop("rollback-watchdog-run.timer".to_owned())
+ .await
+ {
error!("failed to disarm rollback run: {e}");
}
}
- } else if let Err(_e) = host
- .rm_file("/etc/fleet_rollback_marker", true)
+ } else if let Err(_e) = elevated_fs
+ .rm_file(Utf8PathBuf::from("/etc/fleet_rollback_marker"))
.in_current_span()
.await
{
@@ -257,8 +283,8 @@
config: &Config,
host: &ConfigHost,
location: GenerationStorage,
- generation: PathBuf,
-) -> Result<PathBuf> {
+ generation: Utf8PathBuf,
+) -> Result<Utf8PathBuf> {
if matches!(location, GenerationStorage::Pusher) {
bail!("pusher is not enabled in this version of fleet");
}
@@ -273,11 +299,11 @@
}
Err(e) if tries < 3 => {
tries += 1;
- warn!("copy failure ({}/3): {}", tries, e);
+ warn!("copy failure ({}/3): {:#}", tries, e);
sleep(Duration::from_millis(5000)).await;
}
Err(e) => {
- bail!("upload failed: {e}");
+ bail!("upload failed: {e:#}");
}
}
}
crates/fleet-base/src/fleetdata.rsdiffbeforeafterboth--- a/crates/fleet-base/src/fleetdata.rs
+++ b/crates/fleet-base/src/fleetdata.rs
@@ -144,10 +144,6 @@
pub generation_data: Value,
}
-fn is_false(b: &bool) -> bool {
- *b == false
-}
-
#[derive(Serialize, Deserialize, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
#[repr(transparent)]
pub struct SecretOwner(String);
@@ -291,7 +287,7 @@
}
// Which one is easier to access
- return a.owners.len().cmp(&b.owners.len());
+ a.owners.len().cmp(&b.owners.len())
}
impl FleetSecretDistributions {
crates/fleet-base/src/host.rsdiffbeforeafterboth--- a/crates/fleet-base/src/host.rs
+++ b/crates/fleet-base/src/host.rs
@@ -1,30 +1,33 @@
use std::{
collections::{BTreeMap, BTreeSet, HashSet},
- ffi::{OsStr, OsString},
- fmt::Display,
+ future::Future,
io::Write,
ops::Deref,
path::PathBuf,
+ pin::Pin,
str::FromStr,
- sync::{Arc, Mutex, MutexGuard, OnceLock},
+ sync::{Arc, OnceLock},
};
use anyhow::{Context, Result, anyhow, bail, ensure};
+use camino::{Utf8Path, Utf8PathBuf};
use chrono::{DateTime, Utc};
use fleet_shared::SecretData;
-use nix_eval::{Value, nix_go, nix_go_json, util::assert_warn};
-use openssh::{ControlPersist, SessionBuilder};
-use serde::de::DeserializeOwned;
+use nix_eval::{Store, Value, nix_go, nix_go_json, util::assert_warn};
+use remowt_client::{AgentBundle, Remowt};
+use remowt_endpoints::fs::FsClient;
+use remowt_link_shared::Address;
+use remowt_ui_prompt::auto::AutoPrompter;
+use remowt_ui_prompt::bifrost::PromptEndpoints;
+use remowt_ui_prompt::{PrependSourcePrompter, Source};
use tabled::Tabled;
use tempfile::NamedTempFile;
-use time::{UtcDateTime, format_description};
-use tracing::warn;
+use time::UtcDateTime;
+use tokio::task::spawn_blocking;
+use tracing::{info, warn};
-use crate::{
- command::MyCommand,
- fleetdata::{
- FleetData, FleetSecretData, FleetSecretDistribution, FleetSecretPart, SecretOwner,
- },
+use crate::fleetdata::{
+ FleetData, FleetSecretData, FleetSecretDistribution, FleetSecretPart, SecretOwner,
};
pub struct FleetConfigInternals {
@@ -36,7 +39,6 @@
/// builtins.currentSystem
pub local_system: String,
pub data: Arc<FleetData>,
- pub nix_args: Vec<OsString>,
/// fleet_config.config
pub config_field: Value,
/// flake.output
@@ -48,6 +50,8 @@
pub default_pkgs: Value,
/// inputs.nixpkgs
pub nixpkgs: Value,
+
+ pub local_host: OnceLock<Arc<ConfigHost>>,
}
// TODO: Make field not pub
@@ -62,13 +66,6 @@
}
}
-#[derive(Clone, Copy, Debug)]
-pub enum EscalationStrategy {
- Sudo,
- Run0,
- Su,
-}
-
#[derive(Clone, PartialEq, Copy, Debug)]
pub enum DeployKind {
/// NixOS => NixOS managed by fleet
@@ -115,9 +112,26 @@
// TODO: Move command helpers away with connectivity refactor
pub local: bool,
- pub session: OnceLock<Arc<openssh::Session>>,
+ pub remowt: OnceLock<Remowt>,
+ nix_store: OnceLock<Arc<Store>>,
+ nix_plugin: tokio::sync::OnceCell<()>,
}
+const NIX_PLUGIN_ID: u16 = 2;
+
+fn agents_dir() -> Result<PathBuf> {
+ std::env::var_os("REMOWT_AGENTS_DIR")
+ .map(PathBuf::from)
+ .or_else(|| option_env!("REMOWT_AGENTS_DIR").map(PathBuf::from))
+ .ok_or_else(|| {
+ anyhow!("no remowt-agents bundle; set REMOWT_AGENTS_DIR to a remowt-agents output")
+ })
+}
+
+fn agent_bundle() -> Result<AgentBundle> {
+ AgentBundle::from_dir(agents_dir()?)
+}
+
#[derive(Debug, Clone, Copy)]
pub enum GenerationStorage {
Deployer,
@@ -143,7 +157,7 @@
#[tabled(rename = "Created at")]
pub datetime: UtcDateTime,
#[tabled(format = "{:?}")]
- pub store_path: PathBuf,
+ pub store_path: Utf8PathBuf,
#[tabled(skip)]
pub location: GenerationStorage,
}
@@ -153,68 +167,36 @@
}
}
-fn parse_generation_line(g: &str) -> Option<Generation> {
- let mut parts = g.split_whitespace();
- let id = parts.next()?;
- let id: u32 = id.parse().ok()?;
- let date = parts.next()?;
- let time = parts.next()?;
- let current = if let Some(current) = parts.next() {
- if current == "(current)" {
- Some(true)
- } else {
- None
- }
- } else {
- Some(false)
- };
- let current = current?;
- if parts.next().is_some() {
- warn!("unexpected text after generation: {g}");
- }
-
- let format = format_description::parse("[year]-[month]-[day] [hour]:[minute]:[second]")
- .expect("valid format");
- let datetime = UtcDateTime::parse(&format!("{date} {time}"), &format).ok()?;
-
- Some(Generation {
- id,
- current,
- datetime,
- store_path: PathBuf::new(),
- location: GenerationStorage::Machine,
- })
-}
-// TODO: Move command helpers away with connectivity refactor
impl ConfigHost {
pub async fn list_generations(&self, profile: &str) -> Result<Vec<Generation>> {
- let mut cmd = self.cmd("nix-env").await?;
- cmd.comparg("--profile", format!("/nix/var/nix/profiles/{profile}"))
- .arg("--list-generations")
- .env("TZ", "UTC");
- // Sudo is required because --list-generations tries to acquire profile lock
- let data = cmd.sudo().run_string().await?;
- let mut generations = data
- .split('\n')
- .map(|e| e.trim())
- .filter(|&l| !l.is_empty())
- .filter_map(|g| {
- let generation = parse_generation_line(g);
- if generation.is_none() {
- warn!("bad generation: {g}");
- };
- generation
+ let plugin_id = self.ensure_nix_plugin().await?;
+ let nix = self
+ .remowt()
+ .await?
+ .plugin_endpoints::<remowt_fleet::NixClient<_>>(plugin_id);
+ let raw = nix
+ .list_generations(profile.to_owned())
+ .await
+ .map_err(|e| anyhow!("{e:?}"))?
+ .map_err(|e| anyhow!("{e}"))?;
+ raw.into_iter()
+ .map(|g| {
+ let id: u32 =
+ g.id.try_into()
+ .with_context(|| format!("generation id {} doesn't fit in u32", g.id))?;
+ let datetime = UtcDateTime::from_unix_timestamp(g.creation_time_unix)
+ .with_context(|| {
+ format!("invalid generation timestamp {}", g.creation_time_unix)
+ })?;
+ Ok(Generation {
+ id,
+ current: g.current,
+ datetime,
+ store_path: g.store_path,
+ location: GenerationStorage::Machine,
+ })
})
- .collect::<Vec<_>>();
- for ele in generations.iter_mut() {
- let mut cmd = self.cmd("readlink").await?;
- cmd.arg("--")
- .arg(format!("/nix/var/nix/profiles/{profile}-{}-link", ele.id));
- let path = cmd.run_string().await?;
- ele.store_path = PathBuf::from(path.trim_end_matches("\n"));
- }
-
- Ok(generations)
+ .collect()
}
pub fn set_session_destination(&self, dest: String) {
@@ -236,7 +218,9 @@
if let Some(kind) = self.deploy_kind.get() {
return Ok(*kind);
}
- let is_fleet_managed = match self.file_exists("/etc/FLEET_HOST").await {
+ let remowt = self.remowt().await?;
+ let fs = remowt.endpoints::<FsClient<_>>();
+ let is_fleet_managed = match fs.file_exists(Utf8PathBuf::from("/etc/FLEET_HOST")).await {
Ok(v) => v,
Err(e) => {
bail!("failed to query remote system kind: {e}");
@@ -252,6 +236,7 @@
1. manually create /etc/FLEET_HOST file on the target host,
2. use ?deploy_kind=fleet host argument if you're upgrading from older version of fleet
3. use ?deploy_kind=upgrade_to_fleet if you're upgrading from plain nixos to fleet-managed nixos
+ for installation use ?deploy_kind=nixos_install / ?deploy_kind=nixos_lustrate
"}
);
}
@@ -259,139 +244,101 @@
let _ = self.deploy_kind.set(DeployKind::Fleet);
Ok(*self.deploy_kind.get().expect("deploy kind is just set"))
}
- pub async fn escalation_strategy(&self) -> Result<EscalationStrategy> {
- // Prefer sudo, as run0 has some gotchas with polkit
- // and too many repeating prompts.
- if (self.find_in_path("sudo").await).is_ok() {
- return Ok(EscalationStrategy::Sudo);
- }
- if (self.find_in_path("run0").await).is_ok() {
- return Ok(EscalationStrategy::Run0);
+ async fn connection(&self) -> Result<Remowt> {
+ if let Some(conn) = self.remowt.get() {
+ return Ok(conn.clone());
}
- Ok(EscalationStrategy::Su)
- }
- async fn open_session(&self) -> Result<Arc<openssh::Session>> {
- assert!(!self.local, "do not open ssh connection to local session");
- // FIXME: TOCTOU
- if let Some(session) = &self.session.get() {
- return Ok((*session).clone());
+ let bundle = agent_bundle()?;
+ let conn = if self.local {
+ Remowt::connect_local(&bundle)
+ .await
+ .context("starting local remowt agent")?
+ } else {
+ let dest = self
+ .session_destination
+ .get()
+ .cloned()
+ .unwrap_or_else(|| self.name.clone());
+ Remowt::connect(&dest, &bundle)
+ .await
+ .map_err(|e| anyhow!("remowt error while connecting to {}: {e:#?}", self.name))?
};
- let mut session = SessionBuilder::default();
- session.control_persist(ControlPersist::ClosedAfterInitialConnection);
-
- let dest = self.session_destination.get().unwrap_or(&self.name);
- let session = session
- .connect(&dest)
- .await
- .map_err(|e| anyhow!("ssh error while connecting to {}: {e:#?}", self.name))?;
- let session = Arc::new(session);
- self.session.set(session.clone()).expect("TOCTOU happened");
- Ok(session)
- }
- pub async fn mktemp_dir(&self) -> Result<String> {
- let mut cmd = self.cmd("mktemp").await?;
- cmd.arg("-d");
- let path = cmd.run_string().await?;
- Ok(path.trim_end().to_owned())
- }
- pub async fn file_exists(&self, path: impl AsRef<OsStr>) -> Result<bool> {
- let mut cmd = self.cmd("sh").await?;
- cmd.arg("-c")
- .arg("test -e \"$1\" && echo true || echo false")
- .arg("_")
- .arg(path);
- cmd.run_value().await
- }
- pub async fn read_file_bin(&self, path: impl AsRef<OsStr>) -> Result<Vec<u8>> {
- let mut cmd = self.cmd("cat").await?;
- cmd.arg(path);
- cmd.run_bytes().await
- }
- pub async fn read_file_text(&self, path: impl AsRef<OsStr>) -> Result<String> {
- let mut cmd = self.cmd("cat").await?;
- cmd.arg(path);
- cmd.run_string().await
- }
- pub async fn read_dir(&self, path: impl AsRef<OsStr>) -> Result<Vec<String>> {
- let mut cmd = self.cmd("ls").await?;
- cmd.arg(path);
- let out = cmd.run_string().await?;
- let mut lines = out.split('\n');
- if let Some(last) = lines.next_back() {
- ensure!(last.is_empty(), "output of ls should end with newline");
- }
- Ok(lines.map(ToOwned::to_owned).collect())
- }
- #[allow(dead_code)]
- pub async fn read_file_json<D: DeserializeOwned>(&self, path: impl AsRef<OsStr>) -> Result<D> {
- let text = self.read_file_text(path).await?;
- Ok(serde_json::from_str(&text)?)
- }
- pub async fn read_env(&self, env: &str) -> Result<String> {
- let mut cmd = self.cmd("printenv").await?;
- cmd.arg(env);
- cmd.run_string().await
- }
- pub async fn find_in_path(&self, command: &str) -> Result<String> {
- // // `which` is not a part of coreutils, and it might not exist on machine.
- // let path = self.read_env("PATH").await?;
- // // Assuming delimiter is :, we don't work with windows host, this check will be much
- // // more sophisticated in remowt backend (and quicker, since actual PATH search will be done on remote machine)
- // for ele in path.split(':') {
- // let test_path = format!("{ele}/{cmd}");
- // test -x etc
- // }
- // let mut cmd = self.cmd("printenv").await?;
- // cmd.arg(env);
- // Ok(cmd.run_string().await?)
- // Assuming this is an environment issue if which doesn't exist, will be fixed with remowt.
- let mut cmd = self
- .cmd_escalation(
- // Not used
- EscalationStrategy::Su,
- "which",
- )
- .await?;
- cmd.arg(command);
- cmd.run_string().await
+ PromptEndpoints(PrependSourcePrompter {
+ prompter: AutoPrompter::new().await,
+ source: if self.local {
+ vec![]
+ } else {
+ vec![Source(std::borrow::Cow::Owned(format!(
+ "ssh host: {}",
+ self.name
+ )))]
+ },
+ description: "".to_owned(),
+ })
+ .register_endpoints(&mut conn.rpc());
+ let _ = self.remowt.set(conn);
+ Ok(self.remowt.get().expect("just set").clone())
}
- pub async fn read_file_value<D: FromStr>(&self, path: impl AsRef<OsStr>) -> Result<D>
- where
- <D as FromStr>::Err: Display,
- {
- let text = self.read_file_text(path).await?;
- D::from_str(&text).map_err(|e| anyhow!("failed to parse value: {e}"))
+
+ /// Client for this host's unprivileged agent.
+ pub async fn remowt(&self) -> Result<Remowt> {
+ Ok(self.connection().await?)
}
- pub async fn cmd(&self, cmd: impl AsRef<OsStr>) -> Result<MyCommand> {
- self.cmd_escalation(self.escalation_strategy().await?, cmd)
- .await
+
+ pub fn ensure_nix_plugin(&self) -> Pin<Box<dyn Future<Output = Result<u16>> + Send + '_>> {
+ Box::pin(async {
+ self.nix_plugin
+ .get_or_try_init(|| async {
+ let pkgs = self.pkgs()?;
+ let name = "remowt-plugin-fleet";
+ let plugin = nix_go!(pkgs[{ name }]);
+ let built = plugin
+ .build("out")
+ .context("failed to build the fleet nix plugin")?;
+ let copied = self
+ .remote_derivation(&built)
+ .await
+ .context("failed to copy the fleet nix plugin to the host store")?;
+ let bin = copied.join("bin/remowt-plugin-fleet");
+ self.remowt()
+ .await?
+ .run0_load_plugin_path(NIX_PLUGIN_ID, bin.as_str())
+ .await
+ .context("failed to load the fleet nix plugin")?;
+ self.remowt()
+ .await?
+ .rpc()
+ .wait_for_connection_to(Address::Plugin(NIX_PLUGIN_ID))
+ .await
+ .map_err(|e| anyhow!("failed to wait for plugin"))?;
+ anyhow::Ok(())
+ })
+ .await?;
+ Ok(NIX_PLUGIN_ID)
+ })
}
- pub async fn cmd_escalation(
- &self,
- escalation: EscalationStrategy,
- cmd: impl AsRef<OsStr>,
- ) -> Result<MyCommand> {
- if self.local {
- Ok(MyCommand::new(escalation, cmd))
- } else {
- let session = self.open_session().await?;
- Ok(MyCommand::new_on(escalation, cmd, session))
+
+ async fn nix_store(&self) -> Result<Arc<Store>> {
+ if let Some(store) = self.nix_store.get() {
+ return Ok(store.clone());
}
- }
- pub async fn nix_cmd(&self) -> Result<MyCommand> {
- let mut nix = self.cmd("nix").await?;
- nix.args([
- "--extra-experimental-features",
- "nix-command",
- "--extra-experimental-features",
- "flakes",
- ]);
- Ok(nix)
+ let conn = self.connection().await?;
+ let socket = match self.deploy_kind().await? {
+ DeployKind::NixosInstall => {
+ remowt_fleet::nix_store_socket(conn, "/mnt?require-sigs=false").await?
+ }
+ _ => remowt_fleet::nix_store_socket(conn, "auto").await?,
+ };
+ let uri = format!("unix://{}", socket.display());
+ let store = Arc::new(Store::open(&uri)?);
+ let _ = self.nix_store.set(store);
+ Ok(self.nix_store.get().expect("just set").clone())
}
pub async fn decrypt(&self, data: SecretData) -> Result<Vec<u8>> {
ensure!(data.encrypted, "secret is not encrypted");
- let mut cmd = self.cmd("fleet-install-secrets").await?;
+ let remowt = self.remowt().await?;
+ let mut cmd = remowt.cmd("fleet-install-secrets");
cmd.arg("decrypt").eqarg("--secret", data.to_string());
let encoded = cmd
.sudo()
@@ -434,8 +381,9 @@
data: SecretData,
targets: BTreeSet<SecretOwner>,
) -> Result<SecretData> {
+ let remowt = self.remowt().await?;
ensure!(data.encrypted, "secret is not encrypted");
- let mut cmd = self.cmd("fleet-install-secrets").await?;
+ let mut cmd = remowt.cmd("fleet-install-secrets");
cmd.arg("reencrypt").eqarg("--secret", data.to_string());
for target in targets {
let key = self.config.key(&target).await?;
@@ -451,74 +399,39 @@
Ok(data)
}
/// Returns path for futureproofing, as path might change i.e on conversion to CA
- pub async fn remote_derivation(&self, path: &PathBuf) -> Result<PathBuf> {
+ pub async fn remote_derivation(&self, path: impl AsRef<Utf8Path>) -> Result<Utf8PathBuf> {
+ let path = path.as_ref().to_owned();
if self.local {
// Path is located locally, thus already trusted.
- return Ok(path.to_owned());
- }
- let mut sign = MyCommand::new(
- // TODO: Look at the current escalation strategy.
- // ... or switch to run0 right after polkit update
- EscalationStrategy::Sudo,
- "nix",
- );
- sign.arg("store")
- .arg("sign")
- .comparg("--key-file", "/etc/nix/private-key")
- .arg("-r")
- .arg(&path);
- if let Err(e) = sign.sudo().run_nix().await {
- warn!("failed to sign store paths: {e}");
+ return Ok(path);
}
- let mut nix = MyCommand::new(
- // Not used
- EscalationStrategy::Su,
- "nix",
- );
- nix.arg("copy").arg("--substitute-on-destination");
-
- let proto = if self.legacy_ssh_store.get().cloned().unwrap_or(false) {
- "ssh"
- } else {
- "ssh-ng"
+ let sign: Pin<Box<dyn Future<Output = Result<()>> + Send>> = {
+ let path = path.clone();
+ Box::pin(async move {
+ let local = self.config.local_host();
+ let plugin_id = local.ensure_nix_plugin().await?;
+ let nix = local
+ .remowt()
+ .await?
+ .plugin_endpoints::<remowt_fleet::NixClient<_>>(plugin_id);
+ nix.sign_closure(path, Utf8PathBuf::from("/etc/nix/private-key"))
+ .await
+ .map_err(|e| anyhow!("{e:?}"))?
+ .map_err(|e| anyhow!("{e}"))?;
+ Ok(())
+ })
};
-
- match self.deploy_kind().await? {
- DeployKind::Fleet | DeployKind::UpgradeToFleet | DeployKind::NixosLustrate => {
- nix.comparg("--to", format!("{proto}://{}", self.name));
- }
- DeployKind::NixosInstall => {
- nix
- // Signature checking makes no sense with remote-store store argument set, as we're not even interacting with remote nix daemon
- .arg("--no-check-sigs")
- .comparg(
- "--to",
- format!("{proto}://root@{}?remote-store=/mnt", self.name),
- );
- }
+ if let Err(e) = sign.await {
+ warn!("failed to sign store paths: {e}");
}
- nix.arg(path);
- nix.run_nix().await.context("nix copy")?;
- Ok(path.to_owned())
- }
- pub async fn systemctl_stop(&self, name: &str) -> Result<()> {
- let mut cmd = self.cmd("systemctl").await?;
- cmd.arg("stop").arg(name);
- cmd.sudo().run().await
- }
- pub async fn systemctl_start(&self, name: &str) -> Result<()> {
- let mut cmd = self.cmd("systemctl").await?;
- cmd.arg("start").arg(name);
- cmd.sudo().run().await
- }
-
- pub async fn rm_file(&self, path: impl AsRef<OsStr>, sudo: bool) -> Result<()> {
- let mut cmd = self.cmd("rm").await?;
- cmd.arg("-f").arg(path);
- if sudo {
- cmd = cmd.sudo()
+ let store = self.nix_store().await?;
+ {
+ let path = path.clone();
+ spawn_blocking(move || nix_eval::copy_closure_to(&store, path.as_ref()))
+ .await?
+ .context("copying closure to remote store")?;
}
- cmd.run().await
+ Ok(path)
}
}
@@ -630,26 +543,32 @@
}
Ok(out)
}
- pub fn local_host(&self) -> ConfigHost {
- ConfigHost {
- config: self.clone(),
- name: "<virtual localhost>".to_owned(),
- host_config: None,
- nixos_config: OnceLock::new(),
- nixos_unchecked_config: OnceLock::new(),
- groups: {
- let cell = OnceLock::new();
- let _ = cell.set(vec![]);
- cell
- },
- pkgs_override: Some(self.default_pkgs.clone()),
+ pub fn local_host(&self) -> Arc<ConfigHost> {
+ self.local_host
+ .get_or_init(|| {
+ Arc::new(ConfigHost {
+ config: self.clone(),
+ name: "<virtual localhost>".to_owned(),
+ host_config: None,
+ nixos_config: OnceLock::new(),
+ nixos_unchecked_config: OnceLock::new(),
+ groups: {
+ let cell = OnceLock::new();
+ let _ = cell.set(vec![]);
+ cell
+ },
+ pkgs_override: Some(self.default_pkgs.clone()),
- local: true,
- session: OnceLock::new(),
- deploy_kind: OnceLock::new(),
- session_destination: OnceLock::new(),
- legacy_ssh_store: OnceLock::new(),
- }
+ local: true,
+ remowt: OnceLock::new(),
+ nix_store: OnceLock::new(),
+ nix_plugin: tokio::sync::OnceCell::new(),
+ deploy_kind: OnceLock::new(),
+ session_destination: OnceLock::new(),
+ legacy_ssh_store: OnceLock::new(),
+ })
+ })
+ .clone()
}
pub fn preferred_hosts(
@@ -684,7 +603,9 @@
// TODO: Remove with connectivit refactor
local: self.localhost == name,
- session: OnceLock::new(),
+ remowt: OnceLock::new(),
+ nix_store: OnceLock::new(),
+ nix_plugin: tokio::sync::OnceCell::new(),
deploy_kind: OnceLock::new(),
session_destination: OnceLock::new(),
legacy_ssh_store: OnceLock::new(),
crates/fleet-base/src/keys.rsdiffbeforeafterboth--- a/crates/fleet-base/src/keys.rs
+++ b/crates/fleet-base/src/keys.rs
@@ -31,7 +31,8 @@
} else {
warn!("Loading key for {}", host);
let host = self.host(host)?;
- let mut cmd = host.cmd("cat").await?;
+ let remowt = host.remowt().await?;
+ let mut cmd = remowt.cmd("cat");
cmd.arg("/etc/ssh/ssh_host_ed25519_key.pub");
let key = cmd.run_string().await?;
self.update_key(&host.name, key.clone());
crates/fleet-base/src/lib.rsdiffbeforeafterboth--- a/crates/fleet-base/src/lib.rs
+++ b/crates/fleet-base/src/lib.rs
@@ -1,8 +1,6 @@
-pub mod command;
pub mod deploy;
pub mod fleetdata;
pub mod host;
mod keys;
pub mod opts;
pub mod primops;
-pub mod secret_storage;
crates/fleet-base/src/opts.rsdiffbeforeafterboth--- a/crates/fleet-base/src/opts.rs
+++ b/crates/fleet-base/src/opts.rs
@@ -1,9 +1,8 @@
use std::{
collections::{BTreeMap, BTreeSet},
env::current_dir,
- ffi::OsString,
str::FromStr,
- sync::{Arc, Mutex},
+ sync::{Arc, OnceLock},
};
use anyhow::{Context, Result, bail};
@@ -196,7 +195,7 @@
}
// TODO: Config should be detached from opts.
- pub fn build(&self, nix_args: Vec<OsString>, assert: bool) -> Result<Config> {
+ pub fn build(&self, assert: bool) -> Result<Config> {
let cwd = current_dir()?;
let mut directory = cwd.clone();
let mut fleet_data_path = directory.join("fleet.nix");
@@ -274,11 +273,11 @@
data,
flake_outputs: flake,
local_system: self.local_system.clone(),
- nix_args,
config_field,
default_pkgs,
nixpkgs,
localhost: self.localhost.to_owned(),
+ local_host: OnceLock::new(),
}));
PRIMOPS_DATA
crates/fleet-base/src/primops.rsdiffbeforeafterboth--- a/crates/fleet-base/src/primops.rs
+++ b/crates/fleet-base/src/primops.rs
@@ -1,10 +1,12 @@
use std::collections::{BTreeMap, BTreeSet, HashMap};
-use std::sync::OnceLock;
+use std::sync::{Arc, OnceLock};
use anyhow::{Context, bail, ensure};
use fleet_shared::SecretData;
use itertools::Itertools;
use nix_eval::{NativeFn, Value, await_in_nix, nix_go, nix_go_json};
+use remowt_endpoints::fs::FsClient;
+use remowt_link_shared::BifConfig;
use serde::Deserialize;
use tracing::{info, warn};
@@ -28,7 +30,7 @@
let pkgs = host_on.pkgs()?;
let default_mk_secret_generators = nix_go!(pkgs.mkSecretGenerators);
let generators = nix_go!(default_mk_secret_generators(Obj { recipients }));
- Ok(pkgs.clone().attrs_update(generators)?)
+ pkgs.clone().attrs_update(generators)
}
pub fn get_default_pkgs_and_generators(config: &Config) -> Result<Value> {
let host_on = config.local_host();
@@ -91,12 +93,18 @@
let impure_on: Option<String> = nix_go_json!(default_generator_drv.impureOn);
let host_on = if let Some(on) = &impure_on {
- config
- .host(on)
- .context("failed to get secret generation target host")?
+ Arc::new(
+ config
+ .host(on)
+ .context("failed to get secret generation target host")?,
+ )
} else {
config.local_host()
};
+
+ let remowt = host_on.remowt().await?;
+ let fs = remowt.endpoints::<FsClient<BifConfig>>();
+
let mut recipients = Vec::new();
for owner in &expectations.owners {
recipients.push(config.key(owner).await?);
@@ -116,12 +124,13 @@
.context("failed to copy generator to target host")?;
// TODO: Remove destdir after everything is done
- let out_parent = host_on
+ let out_parent = fs
.mktemp_dir()
.await
+ .map_err(|e| anyhow!("{e:?}"))
.context("failed to prepare generator output dir on target host")?;
- let out = format!("{out_parent}/out");
- let mut generator_cmd = host_on.cmd(generator).await?;
+ let out = out_parent.join("out");
+ let mut generator_cmd = remowt.cmd(generator);
generator_cmd.env("out", &out);
if impure_on.is_none() {
let project_path: String = config
@@ -138,7 +147,7 @@
.context("failed to run impure generator")?;
{
- let marker = host_on.read_file_text(format!("{out}/marker")).await?;
+ let marker = fs.read_file_text(out.join("marker")).await?;
ensure!(
marker == "SUCCESS",
"impure generator ended prematurely, secret generation failed"
@@ -147,15 +156,16 @@
let mut missing_parts = expectations.parts.clone();
let mut parts = BTreeMap::new();
- for part in host_on.read_dir(&out).await? {
+ for part in fs.read_dir(&out).await? {
+ let part = part.into_string();
if part == "created_at" || part == "expires_at" || part == "marker" {
continue;
}
let Some(part_def) = missing_parts.remove(&part) else {
bail!("secret generator has produced an unexpected part: {part}");
};
- let contents: SecretData = host_on
- .read_file_text(format!("{out}/{part}"))
+ let contents: SecretData = fs
+ .read_file_text(out.join("part"))
.await?
.parse()
.map_err(|e| anyhow!("failed to decode secret {out:?} part {part:?}: {e}"))?;
@@ -178,11 +188,12 @@
);
}
- let created_at = host_on.read_file_value(format!("{out}/created_at")).await?;
- let expires_at = host_on
- .read_file_value(format!("{out}/expires_at"))
- .await
- .ok();
+ let created_at = fs.read_file_value(out.join("created_at")).await??;
+ let expires_at = match fs.read_file_value(out.join("expires_at")).await {
+ Ok(v) => Some(v?),
+ Err(remowt_endpoints::fs::Error::NotFound) => None,
+ Err(e) => return Err(e.into()),
+ };
let new_data = FleetSecretData {
created_at,
crates/fleet-base/src/secret_storage.rsdiffbeforeafterboth--- a/crates/fleet-base/src/secret_storage.rs
+++ /dev/null
@@ -1,278 +0,0 @@
-use anyhow::{Result, bail, ensure};
-use itertools::Itertools;
-use std::fs::{File, metadata};
-use std::io::{self, ErrorKind, Read, Write};
-use std::path::PathBuf;
-use std::str::FromStr;
-use std::{env, fs};
-
-use tempfile::{TempPath, tempfile_in};
-use toml_edit::{Document, DocumentMut, Formatted, Item, Value};
-
-struct Name(String);
-
-fn encode_name(name: &str) -> Name {
- assert!(
- !name.starts_with(['_', '.']),
- "groups should not start with _ or ."
- );
- assert!(
- !name.chars().any(|c| c == '/'),
- "group name should not contain internal slash"
- );
- Name(name.to_owned())
-}
-
-enum RewriteError {
- ConcurrentCreate,
- ConcurrentDelete,
- ConcurrentModify,
- ConcurrentWrite,
- Io(io::Error),
- Persist(tempfile::PersistError),
-}
-
-fn safe_rewrite(
- path: &PathBuf,
- old_content: Option<Vec<u8>>,
- new_content: Option<Vec<u8>>,
-) -> Result<(), RewriteError> {
- let mut f = match (old_content.is_some(), new_content.is_some()) {
- (false, true) => match File::create_new(path) {
- Ok(v) => v,
- Err(e) if e.kind() == ErrorKind::AlreadyExists => {
- return Err(RewriteError::ConcurrentCreate);
- }
- Err(e) => return Err(RewriteError::Io(e)),
- },
- (true, _) => match File::open(&path) {
- Ok(v) => v,
- Err(_e) => return Err(RewriteError::ConcurrentDelete),
- },
- (false, false) => match metadata(&path) {
- Err(e) if e.kind() == ErrorKind::NotFound => {
- return Ok(());
- }
- Ok(_) => return Err(RewriteError::ConcurrentCreate),
- Err(e) => return Err(RewriteError::Io(e)),
- },
- };
- f.lock().map_err(RewriteError::Io)?;
- let mut check_content = vec![];
- f.read_to_end(&mut check_content)
- .map_err(RewriteError::Io)?;
- match &old_content {
- Some(old) => {
- if old != &check_content {
- return Err(RewriteError::ConcurrentModify);
- }
- }
- None => {
- if !check_content.is_empty() {
- return Err(RewriteError::ConcurrentDelete);
- }
- }
- }
- if let Some(new_content) = new_content {
- if Some(&new_content) == old_content.as_ref() {
- return Ok(());
- }
- let dir = path.parent().expect("file is in directory, thus not root");
- let mut tempfile = tempfile::Builder::new()
- .prefix(".rewrite-")
- .tempfile_in(dir)
- .map_err(RewriteError::Io)?;
- tempfile.write_all(&new_content).map_err(RewriteError::Io)?;
- tempfile.flush().map_err(RewriteError::Io)?;
- tempfile.persist(path).map_err(RewriteError::Persist)?;
- } else {
- fs::remove_file(path).map_err(RewriteError::Io)?;
- }
- let _ = f.unlock();
- Ok(())
-}
-fn update_string(path: PathBuf, modify: impl Fn(&mut Option<String>) -> Result<()>) -> Result<()> {
- loop {
- let orig = match fs::read_to_string(&path) {
- Ok(v) => Some(v),
- Err(e) if e.kind() == ErrorKind::NotFound => None,
- Err(e) => return Err(e.into()),
- };
- let mut edit = orig.clone();
- modify(&mut edit);
-
- match safe_rewrite(&path, orig.map(String::into), edit.map(String::into)) {
- Ok(()) => return Ok(()),
- Err(
- RewriteError::ConcurrentCreate
- | RewriteError::ConcurrentModify
- | RewriteError::ConcurrentWrite
- | RewriteError::ConcurrentDelete,
- ) => {
- continue;
- }
- Err(RewriteError::Io(io)) => return Err(io.into()),
- Err(RewriteError::Persist(io)) => return Err(io.into()),
- }
- }
-}
-fn update_toml(path: PathBuf, modify: impl Fn(&mut DocumentMut) -> Result<()>) -> Result<()> {
- update_string(path, |str| {
- let mut doc = match str {
- None => DocumentMut::new(),
- Some(v) => DocumentMut::from_str(v)?,
- };
- modify(&mut doc)?;
- if doc.is_empty() {
- *str = None
- } else {
- *str = Some(doc.to_string())
- }
- Ok(())
- })
-}
-fn update_lines(path: PathBuf, modify: impl Fn(&mut Vec<String>) -> Result<()>) -> Result<()> {
- update_string(path, |str| {
- let mut list = if let Some(str) = str {
- str.split('\n').map(|s| s.to_owned()).collect_vec()
- } else {
- vec![]
- };
- let had_end_newline = if list.last().map(|v| v.as_str()) == Some("") {
- list.pop();
- true
- } else {
- false
- };
- modify(&mut list)?;
- if list.is_empty() {
- *str = None
- } else {
- if had_end_newline {
- list.push("".to_owned())
- }
- *str = Some(list.join("\n"));
- }
- Ok(())
- })
-}
-fn update_section(
- data: &mut Vec<String>,
- start: &str,
- end: &str,
- modify: impl Fn(&mut Vec<String>) -> Result<()>,
-) -> Result<()> {
- let first = data
- .iter()
- .enumerate()
- .filter(|(_, v)| *v == start)
- .at_most_one()
- .map_err(|_| anyhow::anyhow!("there should be at most one section start"))?
- .map(|(v, _)| v);
- let last = data
- .iter()
- .enumerate()
- .filter(|(_, v)| *v == end)
- .at_most_one()
- .map_err(|_| anyhow::anyhow!("there should be at most one section end"))?
- .map(|(v, _)| v);
-
- match (first, last) {
- (None, None) => {
- let mut out = Vec::new();
- modify(&mut out)?;
- if out.is_empty() {
- return Ok(());
- }
- data.push(start.to_owned());
- data.extend(out);
- data.push(end.to_owned());
- Ok(())
- }
- (None, Some(_)) | (Some(_), None) => {
- bail!("mismatched section start/end")
- }
- (Some(first), Some(last)) => {
- ensure!(first < last, "section end should come after start");
- let mut out = data[first + 1..last]
- .iter()
- .map(|v| v.to_owned())
- .collect_vec();
- modify(&mut out)?;
- if out.is_empty() {
- data.drain(first..=last);
- } else {
- data.splice(first + 1..last, out);
- }
- Ok(())
- }
- }
-}
-
-struct Group {
- path: PathBuf,
-}
-impl Group {
- fn new(path: PathBuf) -> Self {
- Self { path }
- }
- fn manage(&self, manager: &str) {}
- fn ensure_managing(&self, manager: &str) {
- if !self.has_stored() {
- return;
- }
- let managed = match fs::read_to_string(self.path.join(".managed_by")) {
- Ok(found_manager) => found_manager.lines().any(|line| line == manager),
- Err(e) if e.kind() == ErrorKind::NotFound => true,
- Err(e) => panic!("{e}"),
- };
- assert!(managed);
- }
- fn has_stored(&self) -> bool {
- match fs::metadata(&self.path) {
- Ok(d) => d.is_dir(),
- Err(e) if e.kind() == ErrorKind::NotFound => false,
- Err(e) => panic!("{e}"),
- }
- }
-}
-
-struct Root {
- path: PathBuf,
-}
-impl Root {
- fn new(path: PathBuf) -> Self {
- Self { path }
- }
- fn subgroup(&self, name: &str) -> Group {
- Group::new(self.path.join(name))
- }
-}
-
-#[test]
-fn test() {
- let mut data = vec![
- "a".to_owned(),
- "b".to_owned(),
- "start".to_owned(),
- "c".to_owned(),
- "d".to_owned(),
- "end".to_owned(),
- "e".to_owned(),
- "f".to_owned(),
- ];
- update_section(&mut data, "start", "end", |a| {
- a.push("vv".to_owned());
- Ok(())
- })
- .unwrap();
- dbg!(&data);
- // for v in 0..1000 {
- // update_toml(PathBuf::from("./test.toml"), |e| {
- // e.as_table_mut()
- // .insert("hello", Item::Value(Value::Integer(Formatted::new(v))));
- // })
- // .expect("update")
- // }
- // v.subgroup(name)
-}
crates/nix-eval/Cargo.tomldiffbeforeafterboth--- a/crates/nix-eval/Cargo.toml
+++ b/crates/nix-eval/Cargo.toml
@@ -10,10 +10,11 @@
nixlike.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
-thiserror.workspace = true
tracing.workspace = true
+camino = { workspace = true, features = ["serde1"] }
cxx.workspace = true
+futures.workspace = true
itertools.workspace = true
test-log.workspace = true
tokio.workspace = true
crates/nix-eval/src/drv.rsdiffbeforeafterboth--- a/crates/nix-eval/src/drv.rs
+++ b/crates/nix-eval/src/drv.rs
@@ -66,7 +66,13 @@
#[derive(Debug, Deserialize)]
pub struct DrvParsed {
pub inputs: DrvInputs,
- pub outputs: HashMap<String, serde_json::Value>,
+ pub outputs: HashMap<String, DrvParsedOutput>,
+}
+
+#[derive(Debug, Deserialize)]
+pub struct DrvParsedOutput {
+ #[serde(default)]
+ pub path: Option<String>,
}
#[derive(Debug, Deserialize)]
@@ -82,18 +88,19 @@
pub outputs: Vec<String>,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct DrvGraph {
pub root: String,
pub nodes: HashMap<String, DrvNode>,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct DrvNode {
pub name: String,
pub input_drvs: HashMap<String, Vec<String>>,
pub input_srcs: Vec<String>,
- pub outputs: Vec<String>,
+ // TODO: CA outputs without a known paths are skipped
+ pub outputs: HashMap<String, String>,
}
impl DrvGraph {
@@ -124,19 +131,59 @@
}
}
+ let outputs: HashMap<String, String> = parsed
+ .outputs
+ .into_iter()
+ .filter_map(|(name, out)| out.path.map(|p| (name, to_absolute_store_path(&sd, &p))))
+ .collect();
+
nodes.insert(
path.clone(),
DrvNode {
name: extract_drv_name(&path),
input_drvs,
input_srcs: parsed.inputs.srcs,
- outputs: parsed.outputs.into_keys().collect(),
+ outputs,
},
);
}
Ok(Self { root, nodes })
}
+
+ pub fn wanted_outputs(&self, root_outputs: &[String]) -> HashMap<String, Vec<String>> {
+ let mut wanted: HashMap<String, HashSet<String>> = HashMap::new();
+ wanted.insert(self.root.clone(), root_outputs.iter().cloned().collect());
+
+ let mut queue: VecDeque<String> = VecDeque::new();
+ queue.push_back(self.root.clone());
+ while let Some(path) = queue.pop_front() {
+ let Some(node) = self.nodes.get(&path) else {
+ continue;
+ };
+ for (dep_path, dep_outputs) in &node.input_drvs {
+ let entry = wanted.entry(dep_path.clone()).or_default();
+ let mut changed = false;
+ for o in dep_outputs {
+ if entry.insert(o.clone()) {
+ changed = true;
+ }
+ }
+ if changed {
+ queue.push_back(dep_path.clone());
+ }
+ }
+ }
+
+ wanted
+ .into_iter()
+ .map(|(k, v)| {
+ let mut v: Vec<_> = v.into_iter().collect();
+ v.sort();
+ (k, v)
+ })
+ .collect()
+ }
}
fn extract_drv_name(drv_path: &str) -> String {
crates/nix-eval/src/lib.ccdiffbeforeafterboth--- a/crates/nix-eval/src/lib.cc
+++ b/crates/nix-eval/src/lib.cc
@@ -1,8 +1,25 @@
#include "nix-eval/src/lib.rs"
#include "lib.hh"
#include <nix/fetchers/fetch-settings.hh>
+#include <nix/store/build-result.hh>
+#include <nix/store/content-address.hh>
+#include <nix/store/derived-path.hh>
+#include <nix/store/local-fs-store.hh>
+#include <nix/store/outputs-spec.hh>
+#include <nix/store/path-info.hh>
+#include <nix/store/profiles.hh>
+#include <nix/store/realisation.hh>
+#include <nix/store/store-api.hh>
+#include <nix/util/file-system.hh>
+#include <nix/util/hash.hh>
+#include <nix/util/posix-source-accessor.hh>
#include <nix/util/ref.hh>
+#include <nix/util/signature/local-keys.hh>
+#include <nix/util/signature/signer.hh>
+#include <nix/util/source-path.hh>
#include <nix_api_fetchers.h>
+#include <nix_api_store_internal.h>
+#include <sstream>
struct nix_fetchers_settings {
nix::ref<nix::fetchers::Settings> settings;
@@ -15,3 +32,175 @@
bool result = settings_ref->set(setting, value);
}
}
+
+rust::String switch_profile(Store *store, rust::Str profile,
+ rust::Str store_path) {
+ try {
+ auto nixStore = store->ptr;
+ auto *lfs = dynamic_cast<nix::LocalFSStore *>(&*nixStore);
+ if (!lfs)
+ return rust::String("destination is not a local-fs store");
+ auto path = nixStore->parseStorePath(std::string(store_path));
+ std::filesystem::path prof = std::string(profile);
+ auto gen = nix::createGeneration(*lfs, prof, path);
+ nix::switchLink(prof, gen);
+ return rust::String();
+ } catch (const std::exception &e) {
+ return rust::String(e.what());
+ }
+}
+
+rust::String sign_closure(Store *store, rust::Str store_path,
+ rust::Str key_file) {
+ try {
+ auto nixStore = store->ptr;
+ nix::LocalSigner signer(
+ nix::SecretKey::parse(nix::readFile(std::string(key_file))));
+ auto root = nixStore->parseStorePath(std::string(store_path));
+ nix::StorePathSet closure;
+ nixStore->computeFSClosure(root, closure);
+ for (auto &p : closure) {
+ auto info = nixStore->queryPathInfo(p);
+ nix::ValidPathInfo info2(*info);
+ info2.sign(*nixStore, signer);
+ nixStore->addSignatures(p, info2.sigs);
+ }
+ return rust::String();
+ } catch (const std::exception &e) {
+ return rust::String(e.what());
+ }
+}
+
+CxxListGenerationsResult list_generations(rust::Str profile_path) {
+ CxxListGenerationsResult out{rust::String(), {}};
+ try {
+ auto [gens, current] =
+ nix::findGenerations(std::filesystem::path(std::string(profile_path)));
+ for (auto &g : gens) {
+ CxxProfileGeneration cg{};
+ cg.id = g.number;
+ cg.store_path = rust::String(g.path.string());
+ cg.creation_time_unix = static_cast<int64_t>(g.creationTime);
+ cg.current = current.has_value() && *current == g.number;
+ out.generations.push_back(cg);
+ }
+ } catch (const std::exception &e) {
+ out.error = rust::String(e.what());
+ }
+ return out;
+}
+
+static std::vector<std::string> split_lines(rust::Str joined) {
+ std::vector<std::string> out;
+ std::string buf;
+ std::istringstream iss((std::string(joined)));
+ while (std::getline(iss, buf)) {
+ if (!buf.empty())
+ out.push_back(buf);
+ }
+ return out;
+}
+
+CxxBuildResult build_drv_outputs(Store *store, rust::Str drv_path,
+ // TODO: Vec<str>
+ rust::Str output_names_joined) {
+ CxxBuildResult res{rust::String(), {}};
+ try {
+ auto nixStore = store->ptr;
+ auto sp = nixStore->parseStorePath(std::string(drv_path));
+
+ nix::DerivedPath::Built built{
+ .drvPath = nix::makeConstantStorePathRef(sp),
+ .outputs = nix::OutputsSpec{nix::OutputsSpec::All{}},
+ };
+ auto names = split_lines(output_names_joined);
+ if (!names.empty()) {
+ std::set<nix::OutputName, std::less<>> nameSet;
+ for (auto &n : names)
+ nameSet.insert(n);
+ built.outputs =
+ nix::OutputsSpec{nix::OutputsSpec::Names{std::move(nameSet)}};
+ }
+
+ std::vector<nix::DerivedPath> reqs;
+ reqs.push_back(built);
+
+ auto results = nixStore->buildPathsWithResults(reqs);
+ for (auto &r : results) {
+ if (auto *failure = r.tryGetFailure()) {
+ res.error = rust::String(failure->what());
+ return res;
+ }
+ }
+ for (auto &r : results) {
+ if (auto *success = r.tryGetSuccess()) {
+ for (auto &[name, real] : success->builtOutputs) {
+ res.outputs.push_back(
+ rust::String(nixStore->printStorePath(real.outPath)));
+ }
+ }
+ }
+ } catch (const std::exception &e) {
+ res.error = rust::String(e.what());
+ }
+ return res;
+}
+
+CxxBuildResult substitute_paths(Store *store, rust::Str paths_joined) {
+ CxxBuildResult res{rust::String(), {}};
+ try {
+ auto nixStore = store->ptr;
+ auto paths = split_lines(paths_joined);
+
+ std::vector<nix::DerivedPath> reqs;
+ reqs.reserve(paths.size());
+ for (auto &p : paths) {
+ reqs.push_back(nix::DerivedPath::Opaque{nixStore->parseStorePath(p)});
+ }
+
+ // Substituter miss will cause scheduler to trigger build
+ auto results = nixStore->buildPathsWithResults(reqs);
+ for (auto &r : results) {
+ if (r.tryGetSuccess() == nullptr)
+ continue;
+ if (auto *opaque = std::get_if<nix::DerivedPath::Opaque>(&r.path.raw())) {
+ res.outputs.push_back(
+ rust::String(nixStore->printStorePath(opaque->path)));
+ }
+ }
+ } catch (const std::exception &e) {
+ res.error = rust::String(e.what());
+ }
+ return res;
+}
+
+bool is_valid_path(Store *store, rust::Str path) {
+ try {
+ auto nixStore = store->ptr;
+ auto sp = nixStore->parseStorePath(std::string(path));
+ return nixStore->isValidPath(sp);
+ } catch (const std::exception &) {
+ return false;
+ }
+}
+
+AddFileToStoreResult add_file_to_store(Store *store, rust::Str name,
+ rust::Str path) {
+ AddFileToStoreResult out{rust::String(), rust::String(), rust::String()};
+ try {
+ auto nixStore = store->ptr;
+ auto src = nix::PosixSourceAccessor::createAtRoot(
+ std::filesystem::path(std::string(path)));
+ auto info = nixStore->addToStoreSlow(std::string(name), src,
+ nix::ContentAddressMethod::Raw::Flat,
+ nix::HashAlgorithm::SHA256);
+ out.store_path = rust::String(nixStore->printStorePath(info.path));
+ if (info.ca.has_value()) {
+ out.hash =
+ rust::String(info.ca->hash.to_string(nix::HashFormat::SRI, true));
+ }
+ } catch (const std::exception &e) {
+ out.error = rust::String(e.what());
+ }
+ return out;
+}
crates/nix-eval/src/lib.hhdiffbeforeafterboth--- a/crates/nix-eval/src/lib.hh
+++ b/crates/nix-eval/src/lib.hh
@@ -1,7 +1,32 @@
#pragma once
+#include "rust/cxx.h"
#include <nix_api_fetchers.h>
+struct Store;
+
+struct AddFileToStoreResult;
+struct CxxBuildResult;
+
extern "C" {
void set_fetcher_setting(nix_fetchers_settings *settings, const char *setting,
const char *value);
}
+
+rust::String switch_profile(Store *store, rust::Str profile,
+ rust::Str store_path);
+
+rust::String sign_closure(Store *store, rust::Str store_path,
+ rust::Str key_file);
+
+struct CxxListGenerationsResult;
+CxxListGenerationsResult list_generations(rust::Str profile_path);
+
+AddFileToStoreResult add_file_to_store(Store *store, rust::Str name,
+ rust::Str path);
+
+CxxBuildResult build_drv_outputs(Store *store, rust::Str drv_path,
+ rust::Str output_names_joined);
+
+CxxBuildResult substitute_paths(Store *store, rust::Str paths_joined);
+
+bool is_valid_path(Store *store, rust::Str path);
crates/nix-eval/src/lib.rsdiffbeforeafterboth--- a/crates/nix-eval/src/lib.rs
+++ b/crates/nix-eval/src/lib.rs
@@ -1,12 +1,13 @@
use std::borrow::Cow;
use std::cell::RefCell;
+use std::collections::HashMap;
use std::ffi::{CStr, CString, c_char, c_int, c_uint, c_void};
use std::ptr::{null, null_mut};
use std::sync::{Arc, LazyLock, OnceLock};
use std::{array, fmt, slice};
-use std::{collections::HashMap, path::PathBuf};
use anyhow::{Context, anyhow, bail};
+use camino::{Utf8Path, Utf8PathBuf};
use itertools::Itertools;
use serde::Serialize;
use serde::de::DeserializeOwned;
@@ -38,8 +39,9 @@
make_attrs, make_bindings_builder, make_list, make_list_builder, realised_string,
realised_string_free, realised_string_get_buffer_size, realised_string_get_buffer_start,
realised_string_get_store_path, realised_string_get_store_path_count, register_primop,
- set_err_msg, setting_set, state_free, store_open, store_parse_path, store_path_free,
- store_path_name, string_realise, value, value_call, value_decref, value_force, value_incref,
+ set_err_msg, setting_set, state_free, store_copy_closure, store_free, store_open,
+ store_parse_path, store_path_free, store_path_name, string_realise, value, value_call,
+ value_decref, value_force, value_incref,
};
// Contains macros helpers
@@ -47,6 +49,7 @@
pub mod logging;
#[doc(hidden)]
pub mod macros;
+pub mod scheduler;
#[doc(hidden)]
pub mod __macro_support {
@@ -68,8 +71,28 @@
}
#[cxx::bridge]
pub mod nix_cxx {
+ struct AddFileToStoreResult {
+ error: String,
+ store_path: String,
+ hash: String,
+ }
+ struct CxxProfileGeneration {
+ id: u64,
+ store_path: String,
+ creation_time_unix: i64,
+ current: bool,
+ }
+ struct CxxListGenerationsResult {
+ error: String,
+ generations: Vec<CxxProfileGeneration>,
+ }
+ struct CxxBuildResult {
+ error: String,
+ outputs: Vec<String>,
+ }
unsafe extern "C++" {
type nix_fetchers_settings;
+ type Store;
include!("nix-eval/src/lib.hh");
#[allow(clippy::missing_safety_doc)]
@@ -78,6 +101,34 @@
setting: *const c_char,
value: *const c_char,
);
+
+ #[allow(clippy::missing_safety_doc)]
+ unsafe fn switch_profile(store: *mut Store, profile: &str, store_path: &str) -> String;
+
+ #[allow(clippy::missing_safety_doc)]
+ unsafe fn sign_closure(store: *mut Store, store_path: &str, key_file: &str) -> String;
+
+ #[allow(clippy::missing_safety_doc)]
+ unsafe fn add_file_to_store(
+ store: *mut Store,
+ name: &str,
+ path: &str,
+ ) -> AddFileToStoreResult;
+
+ fn list_generations(profile_path: &str) -> CxxListGenerationsResult;
+
+ #[allow(clippy::missing_safety_doc)]
+ unsafe fn build_drv_outputs(
+ store: *mut Store,
+ drv_path: &str,
+ output_names_joined: &str,
+ ) -> CxxBuildResult;
+
+ #[allow(clippy::missing_safety_doc)]
+ unsafe fn substitute_paths(store: *mut Store, paths_joined: &str) -> CxxBuildResult;
+
+ #[allow(clippy::missing_safety_doc)]
+ unsafe fn is_valid_path(store: *mut Store, path: &str) -> bool;
}
}
@@ -186,7 +237,7 @@
unsafe { set_err_msg(self.0, err as c_int, msg.as_ptr()) };
}
pub fn set_err(&mut self, err: anyhow::Error) {
- let mut fmt = format!("{err:?}").replace("\0", "\\0");
+ let fmt = format!("{err:?}").replace("\0", "\\0");
self.set_err_raw(
NixErrorKind::Generic,
&CString::new(fmt).expect("NUL bytes were just replaced"),
@@ -352,6 +403,125 @@
with_default_context(|c, _| unsafe { setting_set(c, s.as_ptr(), v.as_ptr()) }).map(|_| ())
}
+#[instrument(skip(dst))]
+pub fn copy_closure_to(dst: &Store, path: &Utf8Path) -> Result<()> {
+ let path_c = CString::new(path.as_str())?;
+ with_store_context(|c, src_store, _state| -> Result<()> {
+ let sp = unsafe { store_parse_path(c, src_store, path_c.as_ptr()) };
+ if sp.is_null() {
+ bail!("failed to parse store path {path}");
+ }
+ let rc = unsafe { store_copy_closure(c, src_store, dst.0, sp) };
+ unsafe { store_path_free(sp) };
+ if rc != nix_raw::err_NIX_OK {
+ bail!("store_copy_closure failed (code {rc})");
+ }
+ Ok(())
+ })?
+}
+
+#[instrument]
+pub fn switch_profile(profile: &str, store_path: &Utf8Path) -> Result<()> {
+ let msg = with_store_context(|_c, store, _state| unsafe {
+ nix_cxx::switch_profile(store.cast(), profile, store_path.as_str())
+ })?
+ .to_string();
+ if msg.is_empty() {
+ Ok(())
+ } else {
+ bail!("failed to switch profile {profile}: {msg}");
+ }
+}
+
+// TODO: fleet operator-managed key file
+#[instrument]
+pub fn sign_closure(store_path: &str, key_file: &str) -> Result<()> {
+ let msg = with_store_context(|_c, store, _state| unsafe {
+ nix_cxx::sign_closure(store.cast(), store_path, key_file)
+ })?
+ .to_string();
+ if msg.is_empty() {
+ Ok(())
+ } else {
+ bail!("failed to sign {store_path}: {msg}");
+ }
+}
+
+#[derive(Debug)]
+pub struct AddedFile {
+ pub store_path: Utf8PathBuf,
+ pub hash: String,
+}
+
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+pub struct ProfileGeneration {
+ pub id: u64,
+ pub store_path: Utf8PathBuf,
+ pub creation_time_unix: i64,
+ pub current: bool,
+}
+
+#[instrument]
+pub fn list_generations(profile_path: &str) -> Result<Vec<ProfileGeneration>> {
+ let res = nix_cxx::list_generations(profile_path);
+ if !res.error.is_empty() {
+ bail!(
+ "failed to list generations at {profile_path}: {}",
+ res.error
+ );
+ }
+ Ok(res
+ .generations
+ .into_iter()
+ .map(|g| ProfileGeneration {
+ id: g.id,
+ store_path: Utf8PathBuf::from(g.store_path),
+ creation_time_unix: g.creation_time_unix,
+ current: g.current,
+ })
+ .collect())
+}
+
+#[instrument]
+pub fn add_file_to_store(name: &str, path: &Utf8Path) -> Result<AddedFile> {
+ let res = with_store_context(|_c, store, _state| unsafe {
+ nix_cxx::add_file_to_store(store.cast(), name, path.as_str())
+ })?;
+ if !res.error.is_empty() {
+ bail!("failed to add {path} to store: {}", res.error);
+ }
+ Ok(AddedFile {
+ store_path: Utf8PathBuf::from(res.store_path),
+ hash: res.hash,
+ })
+}
+
+pub fn build_drv_outputs(drv_path: &str, output_names: &[String]) -> Result<Vec<String>> {
+ let joined = output_names.join("\n");
+ let res = with_store_context(|_c, store, _state| unsafe {
+ nix_cxx::build_drv_outputs(store.cast(), drv_path, &joined)
+ })?;
+ if !res.error.is_empty() {
+ bail!("build of {drv_path} failed: {}", res.error);
+ }
+ Ok(res.outputs)
+}
+
+pub fn substitute_paths(paths: &[String]) -> Result<Vec<String>> {
+ let joined = paths.join("\n");
+ let res = with_store_context(|_c, store, _state| unsafe {
+ nix_cxx::substitute_paths(store.cast(), &joined)
+ })?;
+ if !res.error.is_empty() {
+ warn!("substitute_paths reported: {}", res.error);
+ }
+ Ok(res.outputs)
+}
+
+pub fn is_valid_path(path: &str) -> Result<bool> {
+ with_store_context(|_c, store, _state| unsafe { nix_cxx::is_valid_path(store.cast(), path) })
+}
+
pub struct FetchSettings(*mut fetchers_settings);
impl FetchSettings {
pub fn new() -> Self {
@@ -450,17 +620,31 @@
unsafe { *user_data.cast::<String>() = s.to_owned() };
}
-struct Store(*mut c_store);
+pub struct Store(*mut c_store);
unsafe impl Send for Store {}
unsafe impl Sync for Store {}
impl Store {
+ pub fn open(uri: &str) -> Result<Self> {
+ let uri = CString::new(uri)?;
+ let ptr = with_default_context(|c, _| unsafe { store_open(c, uri.as_ptr(), null_mut()) })?;
+ if ptr.is_null() {
+ bail!("failed to open store");
+ }
+ Ok(Store(ptr))
+ }
+
fn parse_path(&self, path: &CStr) -> Result<StorePath> {
with_default_context(|c, _| {
StorePath(unsafe { store_parse_path(c, self.0, path.as_ptr()) })
})
}
}
+impl Drop for Store {
+ fn drop(&mut self) {
+ unsafe { store_free(self.0) }
+ }
+}
#[repr(transparent)]
pub struct EvalState(*mut c_eval_state);
@@ -858,7 +1042,7 @@
Ok(out)
}
#[instrument(name = "build", skip(self), fields(output))]
- pub fn build(&self, output: &str) -> Result<PathBuf> {
+ pub fn build(&self, output: &str) -> Result<Utf8PathBuf> {
if !self.is_derivation() {
bail!("expected derivation to build")
}
@@ -880,14 +1064,15 @@
.get_field("drvPath")
.context("getting drvPath")?
.to_string()?;
- let graph = drv::DrvGraph::resolve(&drv_path)?;
+ let graph = Arc::new(drv::DrvGraph::resolve(&drv_path)?);
let _guard = logging::register_build_graph(&Span::current(), &graph);
- // to_string here blocks until the path is built
+ scheduler::build_graph_sync(graph.clone(), vec![output.to_owned()])?;
+
let s = v.builtin_to_string()?;
let rs = s.to_realised_string()?;
let out_path = rs.as_str().to_owned();
- Ok(PathBuf::from(out_path))
+ Ok(Utf8PathBuf::from(out_path))
}
pub fn as_json<T: DeserializeOwned>(&self) -> Result<T> {
let to_json = Self::eval("builtins.toJSON")?;
crates/nix-eval/src/logging.ccdiffbeforeafterboth--- a/crates/nix-eval/src/logging.cc
+++ b/crates/nix-eval/src/logging.cc
@@ -96,7 +96,9 @@
extern "C" {
void apply_tracing_logger() {
- logger = std::make_unique<TracingLogger>();
+ auto old = logger;
+ logger = new TracingLogger();
+ delete old;
// verbosity = lvlVomit;
}
rust::Box<ErrorInfoBuilder>
crates/nix-eval/src/logging.rsdiffbeforeafterboth--- a/crates/nix-eval/src/logging.rs
+++ b/crates/nix-eval/src/logging.rs
@@ -499,7 +499,9 @@
} else if level == Level::INFO {
info!(target: "nix", "{}", s)
} else if level == Level::DEBUG {
- debug!(target: "nix", "{}", s)
+ if s != "querying info about missing paths" {
+ debug!(target: "nix", "{}", s)
+ }
} else {
trace!(target: "nix", "{}", s)
}
@@ -583,7 +585,9 @@
} else if level == Level::INFO {
info!(target: "nix", "{v}")
} else if level == Level::DEBUG {
- debug!(target: "nix", "{v}")
+ if v != "querying info about missing paths" {
+ debug!(target: "nix", "{v}")
+ }
} else {
trace!(target: "nix", "{v}")
}
crates/nix-eval/src/scheduler.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/nix-eval/src/scheduler.rs
@@ -0,0 +1,372 @@
+use std::collections::{HashMap, HashSet};
+use std::sync::Arc;
+
+use anyhow::{Context, Result, bail};
+use futures::stream::{FuturesUnordered, StreamExt};
+use tokio::sync::{Semaphore, broadcast};
+use tracing::{debug, info, instrument, warn};
+
+use crate::drv::DrvGraph;
+
+#[derive(Clone, Debug)]
+pub enum BuildEvent {
+ SubstitutePrepassStarted {
+ paths: usize,
+ },
+ SubstitutePrepassFinished {
+ satisfied: usize,
+ },
+ DrvStarted {
+ drv_path: String,
+ name: String,
+ wanted: Vec<String>,
+ },
+ DrvSkipped {
+ drv_path: String,
+ name: String,
+ },
+ DrvFinished {
+ drv_path: String,
+ name: String,
+ },
+ DrvFailed {
+ drv_path: String,
+ name: String,
+ error: String,
+ },
+ DrvCancelled {
+ drv_path: String,
+ name: String,
+ failed_dep: String,
+ },
+}
+
+pub struct Scheduler {
+ parallelism: usize,
+ events: broadcast::Sender<BuildEvent>,
+}
+
+impl Scheduler {
+ pub fn new(parallelism: usize) -> Self {
+ let parallelism = parallelism.max(1);
+ let (events, _) = broadcast::channel(1024);
+ Self {
+ parallelism,
+ events,
+ }
+ }
+
+ pub fn subscribe(&self) -> broadcast::Receiver<BuildEvent> {
+ self.events.subscribe()
+ }
+
+ #[instrument(name = "scheduler", skip(self, graph), fields(root = %graph.root, nodes = graph.nodes.len()))]
+ pub async fn run(&self, graph: Arc<DrvGraph>, root_outputs: Vec<String>) -> Result<()> {
+ let wanted = graph.wanted_outputs(&root_outputs);
+
+ self.substitute_prepass(&graph, &wanted).await?;
+ self.build_topo(&graph, wanted).await
+ }
+
+ async fn substitute_prepass(
+ &self,
+ graph: &DrvGraph,
+ wanted: &HashMap<String, Vec<String>>,
+ ) -> Result<()> {
+ let paths = collect_substitute_paths(graph, wanted);
+ if paths.is_empty() {
+ return Ok(());
+ }
+ let _ = self
+ .events
+ .send(BuildEvent::SubstitutePrepassStarted { paths: paths.len() });
+ debug!("substitute pre-pass: {} paths", paths.len());
+
+ let satisfied = tokio::task::spawn_blocking(move || crate::substitute_paths(&paths))
+ .await
+ .expect("substitute pre-pass task should not panic")?;
+
+ let _ = self.events.send(BuildEvent::SubstitutePrepassFinished {
+ satisfied: satisfied.len(),
+ });
+ Ok(())
+ }
+
+ async fn build_topo(
+ &self,
+ graph: &Arc<DrvGraph>,
+ wanted: HashMap<String, Vec<String>>,
+ ) -> Result<()> {
+ let mut indeg: HashMap<String, usize> = graph
+ .nodes
+ .iter()
+ .map(|(k, n)| (k.clone(), n.input_drvs.len()))
+ .collect();
+ let mut dependents: HashMap<String, Vec<String>> = HashMap::new();
+ for (path, node) in &graph.nodes {
+ for dep in node.input_drvs.keys() {
+ dependents
+ .entry(dep.clone())
+ .or_default()
+ .push(path.clone());
+ }
+ }
+
+ let sem = Arc::new(Semaphore::new(self.parallelism));
+ let mut ready: Vec<String> = indeg
+ .iter()
+ .filter(|(_, d)| **d == 0)
+ .map(|(k, _)| k.clone())
+ .collect();
+ let mut in_flight = FuturesUnordered::new();
+ let mut failed: HashMap<String, String> = HashMap::new();
+ // Tainted = transitively depends on a failed drv
+ let mut tainted: HashMap<String, String> = HashMap::new();
+
+ loop {
+ let batch: Vec<String> = std::mem::take(&mut ready);
+ for path in batch {
+ if let Some(failed_dep) = tainted.get(&path) {
+ let name = graph
+ .nodes
+ .get(&path)
+ .map(|n| n.name.clone())
+ .unwrap_or_default();
+ let _ = self.events.send(BuildEvent::DrvCancelled {
+ drv_path: path.clone(),
+ name,
+ failed_dep: failed_dep.clone(),
+ });
+ propagate_done(&dependents, &mut indeg, &mut ready, &path);
+ continue;
+ }
+
+ let sem = sem.clone();
+ let events = self.events.clone();
+ let graph = graph.clone();
+ let wanted_here = wanted.get(&path).cloned().unwrap_or_default();
+ in_flight.push(tokio::spawn(async move {
+ let _permit = sem.acquire_owned().await.expect("semaphore not closed");
+ let node = graph
+ .nodes
+ .get(&path)
+ .expect("ready node must be in graph")
+ .clone();
+ let name = node.name.clone();
+
+ let all_valid = !wanted_here.is_empty()
+ && wanted_here.iter().all(|o| {
+ node.outputs
+ .get(o)
+ .map(|p| crate::is_valid_path(p).unwrap_or(false))
+ .unwrap_or(false)
+ });
+ if all_valid {
+ let _ = events.send(BuildEvent::DrvSkipped {
+ drv_path: path.clone(),
+ name: name.clone(),
+ });
+ return (path, name, Ok::<(), anyhow::Error>(()));
+ }
+
+ let _ = events.send(BuildEvent::DrvStarted {
+ drv_path: path.clone(),
+ name: name.clone(),
+ wanted: wanted_here.clone(),
+ });
+
+ let path_for_build = path.clone();
+ let res = tokio::task::spawn_blocking(move || {
+ crate::build_drv_outputs(&path_for_build, &wanted_here)
+ })
+ .await
+ .expect("build task should not panic");
+
+ match res {
+ Ok(_) => {
+ let _ = events.send(BuildEvent::DrvFinished {
+ drv_path: path.clone(),
+ name: name.clone(),
+ });
+ (path, name, Ok(()))
+ }
+ Err(e) => {
+ let msg = format!("{e:#}");
+ let _ = events.send(BuildEvent::DrvFailed {
+ drv_path: path.clone(),
+ name: name.clone(),
+ error: msg,
+ });
+ (path, name, Err(e))
+ }
+ }
+ }));
+ }
+
+ let Some(joined) = in_flight.next().await else {
+ break;
+ };
+ let (finished, _name, res) = match joined {
+ Ok(t) => t,
+ Err(e) => bail!("scheduler task panicked: {e}"),
+ };
+ match res {
+ Ok(()) => {
+ propagate_done(&dependents, &mut indeg, &mut ready, &finished);
+ }
+ Err(e) => {
+ failed.insert(finished.clone(), format!("{e:#}"));
+ mark_tainted(&dependents, &finished, &mut tainted);
+ propagate_done(&dependents, &mut indeg, &mut ready, &finished);
+ }
+ }
+ }
+
+ let stuck: Vec<_> = indeg
+ .iter()
+ .filter(|(_, d)| **d != 0)
+ .map(|(k, _)| k.as_str())
+ .collect();
+ if !stuck.is_empty() {
+ warn!(
+ "scheduler finished with {} nodes still pending (loop?)",
+ stuck.len()
+ );
+ }
+
+ if failed.is_empty() {
+ info!("scheduler completed");
+ Ok(())
+ } else {
+ let mut report = format!("{} drv(s) failed to build:", failed.len());
+ let mut sorted: Vec<_> = failed.iter().collect();
+ sorted.sort_by(|a, b| a.0.cmp(b.0));
+ for (path, err) in sorted {
+ let name = graph
+ .nodes
+ .get(path)
+ .map(|n| n.name.as_str())
+ .unwrap_or("?");
+ let chain = path_to_root(graph, path);
+ report.push_str(&format!(
+ "\n\n {name} ({path}):\n {err}\n needed by: {}",
+ chain.join(" => "),
+ ));
+ }
+ Err(anyhow::anyhow!(report))
+ }
+ }
+}
+
+fn propagate_done(
+ dependents: &HashMap<String, Vec<String>>,
+ indeg: &mut HashMap<String, usize>,
+ ready: &mut Vec<String>,
+ finished: &str,
+) {
+ if let Some(deps) = dependents.get(finished) {
+ for d in deps {
+ let entry = indeg.get_mut(d).expect("dependent must have indeg");
+ *entry = entry.saturating_sub(1);
+ if *entry == 0 {
+ ready.push(d.clone());
+ }
+ }
+ }
+}
+
+fn mark_tainted(
+ dependents: &HashMap<String, Vec<String>>,
+ failed: &str,
+ tainted: &mut HashMap<String, String>,
+) {
+ let mut queue: Vec<String> = dependents.get(failed).cloned().unwrap_or_default();
+ while let Some(node) = queue.pop() {
+ if tainted
+ .entry(node.clone())
+ .or_insert_with(|| failed.to_owned())
+ == failed
+ {
+ if let Some(deps) = dependents.get(&node) {
+ for d in deps {
+ if !tainted.contains_key(d) {
+ queue.push(d.clone());
+ }
+ }
+ }
+ }
+ }
+}
+
+fn path_to_root(graph: &DrvGraph, from: &str) -> Vec<String> {
+ let mut dependents: HashMap<&str, Vec<&str>> = HashMap::new();
+ for (path, node) in &graph.nodes {
+ for dep in node.input_drvs.keys() {
+ dependents
+ .entry(dep.as_str())
+ .or_default()
+ .push(path.as_str());
+ }
+ }
+
+ let mut chain: Vec<String> = vec![node_name(graph, from)];
+ let mut cur = from;
+ let mut seen: HashSet<&str> = HashSet::new();
+ seen.insert(cur);
+ while cur != graph.root.as_str() {
+ let Some(next) = dependents.get(cur).and_then(|v| v.first().copied()) else {
+ break;
+ };
+ if !seen.insert(next) {
+ break;
+ }
+ chain.push(node_name(graph, next));
+ cur = next;
+ }
+ chain
+}
+
+fn node_name(graph: &DrvGraph, path: &str) -> String {
+ graph
+ .nodes
+ .get(path)
+ .map(|n| n.name.clone())
+ .unwrap_or_else(|| path.to_owned())
+}
+
+fn collect_substitute_paths(
+ graph: &DrvGraph,
+ wanted: &HashMap<String, Vec<String>>,
+) -> Vec<String> {
+ let mut paths: HashSet<String> = HashSet::new();
+ for node in graph.nodes.values() {
+ for src in &node.input_srcs {
+ paths.insert(src.clone());
+ }
+ }
+ for (path, outs) in wanted {
+ let Some(node) = graph.nodes.get(path) else {
+ continue;
+ };
+ for o in outs {
+ if let Some(p) = node.outputs.get(o) {
+ paths.insert(p.clone());
+ }
+ }
+ }
+ let mut v: Vec<_> = paths.into_iter().collect();
+ v.sort();
+ v
+}
+
+// TODO: Parallelism as a metric works poorly with multiple machines, but I haven't thought about bringing
+// hercy here yet. In case of remote machines - they will handle parallelism on their own, and this one
+// will work as a hard cap.
+pub fn build_graph_sync(graph: Arc<DrvGraph>, root_outputs: Vec<String>) -> Result<()> {
+ let parallelism = std::thread::available_parallelism()
+ .map(|p| p.get())
+ .unwrap_or(4);
+ let scheduler = Scheduler::new(parallelism);
+ crate::await_in_nix(async move { scheduler.run(graph, root_outputs).await })
+ .context("scheduler run")
+}
crates/nixlike/Cargo.tomldiffbeforeafterboth--- a/crates/nixlike/Cargo.toml
+++ b/crates/nixlike/Cargo.toml
@@ -11,5 +11,3 @@
linked-hash-map.workspace = true
peg.workspace = true
serde.workspace = true
-serde-transcode.workspace = true
-serde_json.workspace = true
crates/remowt-fleet/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/crates/remowt-fleet/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "remowt-fleet"
+description = "Remowt endpoints for fleet"
+version.workspace = true
+edition = "2021"
+
+[dependencies]
+bifrostlink.workspace = true
+
+remowt-client.workspace = true
+remowt-endpoints.workspace = true
+
+anyhow.workspace = true
+camino.workspace = true
+nix-eval.workspace = true
+serde = { workspace = true }
+thiserror.workspace = true
+tokio = { workspace = true, features = ["io-util", "net", "process", "rt"] }
+tracing.workspace = true
+uuid.workspace = true
crates/remowt-fleet/src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/remowt-fleet/src/lib.rs
@@ -0,0 +1,120 @@
+use std::path::PathBuf;
+
+use anyhow::{Context as _, Result};
+use bifrostlink::Config;
+use bifrostlink::declarative::endpoints;
+use camino::Utf8PathBuf;
+use remowt_client::Remowt;
+use remowt_endpoints::nix_daemon::NixDaemonClient;
+use serde::{Deserialize, Serialize};
+use tokio::net::UnixListener;
+use tracing::error;
+
+pub struct Nix;
+pub use nix_eval::{init_libraries, init_tokio_for_nix};
+
+#[derive(Serialize, Deserialize, Debug, thiserror::Error)]
+pub enum NixError {
+ #[error("nix daemon unavailable: {0}")]
+ DaemonUnavailable(String),
+ #[error("tunnel socket unavailable: {0}")]
+ Tunnel(String),
+ #[error("profile switch failed: {0}")]
+ Profile(String),
+ #[error("signing failed: {0}")]
+ Sign(String),
+ #[error("listing generations failed: {0}")]
+ ListGenerations(String),
+}
+
+#[endpoints(ns = 91)]
+impl Nix {
+ #[endpoints(id = 3)]
+ async fn switch_profile(
+ &self,
+ profile: String,
+ store_path: Utf8PathBuf,
+ ) -> Result<(), NixError> {
+ tokio::task::spawn_blocking(move || nix_eval::switch_profile(&profile, &store_path))
+ .await
+ .map_err(|e| NixError::Profile(e.to_string()))?
+ .map_err(|e| NixError::Profile(e.to_string()))
+ }
+
+ #[endpoints(id = 4)]
+ async fn sign_closure(
+ &self,
+ store_path: Utf8PathBuf,
+ key_file: Utf8PathBuf,
+ ) -> Result<(), NixError> {
+ tokio::task::spawn_blocking(move || {
+ nix_eval::sign_closure(store_path.as_str(), key_file.as_str())
+ })
+ .await
+ .map_err(|e| NixError::Sign(e.to_string()))?
+ .map_err(|e| NixError::Sign(e.to_string()))
+ }
+
+ #[endpoints(id = 5)]
+ async fn list_generations(
+ &self,
+ profile: String,
+ ) -> Result<Vec<nix_eval::ProfileGeneration>, NixError> {
+ tokio::task::spawn_blocking(move || {
+ nix_eval::list_generations(&format!("/nix/var/nix/profiles/{profile}"))
+ })
+ .await
+ .map_err(|e| NixError::ListGenerations(e.to_string()))?
+ .map_err(|e| NixError::ListGenerations(e.to_string()))
+ }
+}
+
+pub async fn nix_store_socket(conn: Remowt, store: &str) -> Result<PathBuf> {
+ let store = store.to_owned();
+ let path = std::env::temp_dir().join(format!("fleet-nix-{}.sock", uuid::Uuid::new_v4()));
+ let _ = std::fs::remove_file(&path);
+ let listener = UnixListener::bind(&path)?;
+ tokio::spawn(async move {
+ if let Err(e) = serve(conn, listener, store).await {
+ error!("nix daemon proxy failed: {e}");
+ }
+ });
+ Ok(path)
+}
+
+async fn serve(conn: Remowt, listener: UnixListener, store: String) -> Result<()> {
+ let nix = conn.endpoints::<NixDaemonClient<_>>();
+ loop {
+ let (mut local, _) = listener.accept().await?;
+
+ let (rx, remote_sock) = match conn.bind_runtime_unix("nix-daemon").await {
+ Ok(rx) => rx,
+ Err(e) => {
+ error!("streamlocal_forward failed: {e}");
+ continue;
+ }
+ };
+ let sock_str = remote_sock.as_str().to_owned();
+ match nix.serve_store(store.clone(), sock_str).await {
+ Ok(Ok(())) => {}
+ Ok(Err(e)) => {
+ error!("nix bridge: {e}");
+ continue;
+ }
+ Err(e) => {
+ error!("nix bridge rpc failed: {e}");
+ continue;
+ }
+ }
+
+ let mut channel = rx
+ .accept()
+ .await
+ .context("failed to accept remote nix connection")?;
+ tokio::spawn(async move {
+ if let Err(e) = tokio::io::copy_bidirectional(&mut local, &mut channel).await {
+ tracing::debug!("nix tunnel ended: {e}");
+ }
+ });
+ }
+}
flake.lockdiffbeforeafterboth--- a/flake.lock
+++ b/flake.lock
@@ -2,10 +2,10 @@
"nodes": {
"crane": {
"locked": {
- "lastModified": 1773189535,
+ "lastModified": 1780532242,
"owner": "ipetkov",
"repo": "crane",
- "rev": "6fa2fb4cf4a89ba49fc9dd5a3eb6cde99d388269",
+ "rev": "59a82a1222dd3b2080b5cc52a1a2e8d5f1b77f37",
"type": "github"
},
"original": {
@@ -37,10 +37,10 @@
]
},
"locked": {
- "lastModified": 1772408722,
+ "lastModified": 1778716662,
"owner": "hercules-ci",
"repo": "flake-parts",
- "rev": "f20dc5d9b8027381c474144ecabc9034d6a839a3",
+ "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb",
"type": "github"
},
"original": {
@@ -62,10 +62,10 @@
]
},
"locked": {
- "lastModified": 1759080490,
+ "lastModified": 1780160585,
"owner": "CertainLach",
"repo": "fleet-tf",
- "rev": "878bd8c23933d628bf750378bbe527b841901c3d",
+ "rev": "aa2200a3f8f93a8c0d3b87bb29f11d9d9b0a23e6",
"type": "github"
},
"original": {
@@ -111,10 +111,10 @@
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
- "lastModified": 1768702010,
+ "lastModified": 1781448983,
"owner": "deltarocks",
"repo": "nix",
- "rev": "b05b52670b9c7affff5b9be3edb539a1603c39e6",
+ "rev": "bb8784f285658e77642437409824619f5c34a854",
"type": "github"
},
"original": {
@@ -126,10 +126,10 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1773268153,
+ "lastModified": 1781402740,
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "63ca4f465b79edbaa9ff113ea7ff48fb49ea0db0",
+ "rev": "49145c5aba740948d6da1265f584826bd27619ad",
"type": "github"
},
"original": {
@@ -171,6 +171,34 @@
"type": "github"
}
},
+ "remowt-agents": {
+ "inputs": {
+ "crane": [
+ "crane"
+ ],
+ "flake-parts": [
+ "flake-parts"
+ ],
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "rust-overlay": "rust-overlay",
+ "shelly": [
+ "shelly"
+ ]
+ },
+ "locked": {
+ "lastModified": 1781471358,
+ "rev": "c69dddc33f8e2081ef685ae20a7278f92cfcd32e",
+ "revCount": 37,
+ "type": "git",
+ "url": "file:/home/lach/build/remowt-agents"
+ },
+ "original": {
+ "type": "git",
+ "url": "file:/home/lach/build/remowt-agents"
+ }
+ },
"root": {
"inputs": {
"crane": "crane",
@@ -178,7 +206,8 @@
"fleet-tf": "fleet-tf",
"nix": "nix",
"nixpkgs": "nixpkgs",
- "rust-overlay": "rust-overlay",
+ "remowt-agents": "remowt-agents",
+ "rust-overlay": "rust-overlay_2",
"shelly": "shelly",
"treefmt-nix": "treefmt-nix"
}
@@ -186,14 +215,15 @@
"rust-overlay": {
"inputs": {
"nixpkgs": [
+ "remowt-agents",
"nixpkgs"
]
},
"locked": {
- "lastModified": 1773216618,
+ "lastModified": 1769309768,
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "07d7dc6fcc5eae76b4fb0e19d4afd939437bec97",
+ "rev": "140c9dc582cb73ada2d63a2180524fcaa744fad5",
"type": "github"
},
"original": {
@@ -202,6 +232,25 @@
"type": "github"
}
},
+ "rust-overlay_2": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1781320681,
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "rev": "5b929d8c854149d926d05ea0cd6469bf4e54db27",
+ "type": "github"
+ },
+ "original": {
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "type": "github"
+ }
+ },
"shelly": {
"locked": {
"lastModified": 1756323923,
@@ -223,10 +272,10 @@
]
},
"locked": {
- "lastModified": 1772660329,
+ "lastModified": 1780220602,
"owner": "numtide",
"repo": "treefmt-nix",
- "rev": "3710e0e1218041bbad640352a0440114b1e10428",
+ "rev": "db947814a175b7ca6ded66e21383d938df01c227",
"type": "github"
},
"original": {
flake.nixdiffbeforeafterboth--- a/flake.nix
+++ b/flake.nix
@@ -23,6 +23,13 @@
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
+ remowt-agents = {
+ url = "git+file:/home/lach/build/remowt-agents";
+ inputs.nixpkgs.follows = "nixpkgs";
+ inputs.flake-parts.follows = "flake-parts";
+ inputs.crane.follows = "crane";
+ inputs.shelly.follows = "shelly";
+ };
# DeterminateSystem's nix fork is controversial, but I don't mind it,
# and it has lazy-trees support which is useful for fleet.
nix = {
@@ -147,7 +154,7 @@
packages = lib.mkIf deployerSystem (
let
packages = pkgs.callPackages ./pkgs {
- inherit craneLib inputs';
+ inherit craneLib inputs;
};
in
packages // { default = packages.fleet; }
lib/flakePart.nixdiffbeforeafterboth--- a/lib/flakePart.nix
+++ b/lib/flakePart.nix
@@ -57,7 +57,7 @@
modules = (import ../modules/module-list.nix) ++ [
module
(
- { inputs', ... }:
+ { inputs, ... }:
{
config = {
data = if isPath data then import data else data;
@@ -66,12 +66,13 @@
(final: prev: {
inherit
(import ../pkgs {
- inherit (prev) callPackage;
- inherit inputs';
+ inherit (final) callPackage;
+ inherit inputs;
craneLib = crane.mkLib prev;
})
fleet-install-secrets
fleet-generator-helper
+ remowt-plugin-fleet
;
})
];
modules/nixpkgs.nixdiffbeforeafterboth--- a/modules/nixpkgs.nix
+++ b/modules/nixpkgs.nix
@@ -42,10 +42,12 @@
default = config.nixpkgs.buildUsing;
defaultText = literalExpression "config.nixpkgs.buildUsing";
};
- config.nixos = {
- inherit _file;
- nixpkgs.overlays = config.nixpkgs.overlays;
- };
+ config.nixos =
+ { inputs', ... }:
+ {
+ inherit _file;
+ nixpkgs.overlays = config.nixpkgs.overlays;
+ };
};
};
}
pkgs/default.nixdiffbeforeafterboth--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,10 +1,11 @@
{
callPackage,
craneLib,
- inputs',
+ inputs,
}:
{
- fleet = callPackage ./fleet.nix { inherit craneLib inputs'; };
+ fleet = callPackage ./fleet.nix { inherit craneLib inputs; };
+ remowt-plugin-fleet = callPackage ./remowt-plugin-fleet.nix { inherit craneLib inputs; };
fleet-install-secrets = callPackage ./fleet-install-secrets.nix { inherit craneLib; };
fleet-generator-helper = callPackage ./fleet-generator-helper.nix { inherit craneLib; };
}
pkgs/fleet.nixdiffbeforeafterboth--- a/pkgs/fleet.nix
+++ b/pkgs/fleet.nix
@@ -2,10 +2,16 @@
lib,
craneLib,
installShellFiles,
- inputs',
+ inputs,
+
+ stdenv,
pkg-config,
rustPlatform,
+ rofi,
}:
+let
+ system = stdenv.hostPlatform.system;
+in
craneLib.buildPackage rec {
pname = "fleet";
src = lib.cleanSourceWith {
@@ -20,10 +26,15 @@
cargoExtraArgs = "--locked -p ${pname}";
+ REMOWT_AGENTS_DIR = "${inputs.remowt-agents.packages.${system}.remowt-agents}";
+ # TODO: built-in fleet prompter should be a prodash widget, or it should require
+ # tty remowt prompter running on host machine idk.
+ ROFI = "${rofi}/bin/rofi";
+
buildInputs = [
- inputs'.nix.packages.nix-expr-c
- inputs'.nix.packages.nix-flake-c
- inputs'.nix.packages.nix-fetchers-c
+ inputs.nix.packages.${system}.nix-expr-c
+ inputs.nix.packages.${system}.nix-flake-c
+ inputs.nix.packages.${system}.nix-fetchers-c
];
nativeBuildInputs = [
installShellFiles
pkgs/remowt-plugin-fleet.nixdiffbeforeafterboth--- /dev/null
+++ b/pkgs/remowt-plugin-fleet.nix
@@ -0,0 +1,36 @@
+{
+ lib,
+ craneLib,
+ inputs,
+
+ stdenv,
+ pkg-config,
+ rustPlatform,
+}:
+let
+ system = stdenv.hostPlatform.system;
+in
+craneLib.buildPackage rec {
+ pname = "remowt-plugin-fleet";
+ src = lib.cleanSourceWith {
+ src = ../.;
+ filter =
+ path: type:
+ (lib.hasSuffix "\.cc" path)
+ || (lib.hasSuffix "\.hh" path)
+ || (craneLib.filterCargoSources path type);
+ };
+ strictDeps = true;
+
+ cargoExtraArgs = "--locked -p ${pname}";
+
+ buildInputs = [
+ inputs.nix.packages.${system}.nix-expr-c
+ inputs.nix.packages.${system}.nix-flake-c
+ inputs.nix.packages.${system}.nix-fetchers-c
+ ];
+ nativeBuildInputs = [
+ pkg-config
+ rustPlatform.bindgenHook
+ ];
+}