difftreelog
feat on-demand secret generation
in: trunk
24 files changed
Cargo.lockdiffbeforeafterboth462 packageslockfile v4
Might be heavy and slow!
abort-on-drop
0.2.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5dd6d700ad9af641490c1f7d67980d2de4d1433016e5b12f819448d3c832142adepends onused byaddr2line
0.25.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4bdepends onused byadler2
2.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefaused byaead
0.5.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0depends onaes
0.8.4crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0depends onused byaes-gcm
0.10.3crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1used byage
0.11.1crates.io↘ 29↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum57fc171f4874fa10887e47088f81a55fcf030cd421aa31ec2b370cafebcc608adepends on- aes
0.8.4 - aes-gcm
0.10.3 - age-core
0.11.0 - base64
0.21.7 - bcrypt-pbkdf
0.10.0 - bech32
0.9.1 - cbc
0.1.2 - chacha20poly1305
0.10.1 - cipher
0.4.4 - cookie-factory
0.3.3 - ctr
0.9.2 - curve25519-dalek
4.1.3 - hmac
0.12.1 - i18n-embed
0.15.4 - i18n-embed-fl
0.9.4 - lazy_static
1.5.0 - nom
7.1.3 - num-traits
0.2.19 - pin-project
1.1.10 - rand
0.8.5 - rsa
0.9.8 - rust-embed
8.7.2 - scrypt
0.11.0 - sha2
0.10.9 - subtle
2.6.1 - which
4.4.2 - wsl
0.1.0 - x25519-dalek
2.0.1 - zeroize
1.8.2
- aes
age-core
0.11.0crates.io↘ 10↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume2bf6a89c984ca9d850913ece2da39e1d200563b0a94b002b253beee4c5acf99depends onused byaho-corasick
1.1.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916depends onandroid_system_properties
0.1.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311depends onused byanstream
0.6.21crates.io↘ 7↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4adepends onanstyle
1.0.13crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78anstyle-parse
0.2.7crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2depends onused byanstyle-query
1.1.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2depends onused byanstyle-wincon
3.0.10crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2aused byanyhow
1.0.100crates.io↘ 0↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61arc-swap
1.7.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457used byasync-stream
0.3.6crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476used byasync-stream-impl
0.3.6crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574ddepends onused byasync-trait
0.1.89crates.io↘ 3↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbbdepends onatomic-waker
1.1.2crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0used byautocfg
1.5.0crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8axum
0.7.9crates.io↘ 19↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumedca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71fdepends onused byaxum
0.8.7crates.io↘ 29↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425depends on- axum-core
0.5.5 - axum-macros
0.5.0 - base64
0.22.1 - bytes
1.10.1 - form_urlencoded
1.2.2 - futures-util
0.3.31 - http
1.3.1 - http-body
1.0.1 - http-body-util
0.1.3 - hyper
1.8.1 - hyper-util
0.1.17 - itoa
1.0.15 - matchit
0.8.4 - memchr
2.7.6 - mime
0.3.17 - percent-encoding
2.3.2 - pin-project-lite
0.2.16 - serde_core
1.0.228 - serde_json
1.0.145 - serde_path_to_error
0.1.20 - serde_urlencoded
0.7.1 - sha1
0.10.6 - sync_wrapper
1.0.2 - tokio
1.47.1 - tokio-tungstenite
0.28.0 - tower
0.5.2 - tower-layer
0.3.3 - tower-service
0.3.3 - tracing
0.1.41
used by- axum-core
axum-core
0.4.5crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199depends onused byaxum-core
0.5.5crates.io↘ 11↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22depends onused byaxum-extra
0.12.2crates.io↘ 14↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdbfe9f610fe4e99cf0cfcd03ccf8c63c28c616fe714d80475ef731f3b13dd21bdepends onused byaxum-macros
0.5.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05cdepends onused bybacktrace
0.3.76crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6depends onused bybase64
0.21.7crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567used bybase64
0.22.1crates.io↘ 0↖ 13sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6basic-toml
0.1.10crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178adepends onused bybcrypt-pbkdf
0.10.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2depends onused bybetter-command
0.1.0workspace↘ 5↖ 2bindgen
0.72.1crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895depends onused bybitflags
2.9.4crates.io↘ 1↖ 10sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394depends onblock-buffer
0.10.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71depends onused byblock-padding
0.3.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93depends onused byblowfish
0.9.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7depends onused bybumpalo
3.19.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43used bybytecount
0.6.9crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365eused bybyteorder
1.5.0crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64bbytes
1.10.1crates.io↘ 0↖ 22sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6aused bycbc
0.1.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6depends onused bycc
1.2.41crates.io↘ 2↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7depends oncexpr
0.6.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766depends onused bycfg_aliases
0.2.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724used bycfg-if
1.0.3crates.io↘ 0↖ 19sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9chacha20
0.9.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818depends onused bychacha20poly1305
0.10.1crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35used bychrono
0.4.42crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2depends onused bycipher
0.4.4crates.io↘ 3↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3daddepends onclang-sys
1.8.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4depends onused byclap
4.5.48crates.io↘ 2↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5faedepends onclap_builder
4.5.48crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9depends onused byclap_complete
4.5.58crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum75bf0b32ad2e152de789bb635ea4d3078f6b838ad7974143e99b99f45a04af4adepends onused byclap_derive
4.5.47crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9cused byclap_lex
0.7.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675used bycodespan-reporting
0.12.0crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81colorchoice
1.0.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75used byconsole
0.16.1crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4used byconst-oid
0.9.6crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8cookie-factory
0.3.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2depends onused bycore-foundation-sys
0.8.7crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888bused bycpufeatures
0.2.17crates.io↘ 1↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280depends oncrc32fast
1.5.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511depends onused bycrypto-common
0.1.6crates.io↘ 3↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3ctr
0.9.2crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835depends onused bycursor-icon
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732fused bycurve25519-dalek
4.1.3crates.io↘ 8↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2bedepends oncurve25519-dalek-derive
0.1.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3depends onused bycxx
1.0.186crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4e9c4fe7f2f5dc5c62871a1b43992d197da6fa1394656a94276ac2894a90a6fedepends onused bycxx-build
1.0.186crates.io↘ 7↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb5cf2909d37d80633ddd208676fc27c2608a7f035fff69c882421168038b26dddepends onused bycxxbridge-cmd
1.0.186crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum077f5ee3d3bfd8d27f83208fdaa96ddd50af7f096c77077cc4b94da10bfacefdused bycxxbridge-flags
1.0.186crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb0108748615125b9f2e915dfafdffcbdabbca9b15102834f6d7e9a768f2f2864used bycxxbridge-macro
1.0.186crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume6e896681ef9b8dc462cfa6961d61909704bde0984b30bcb4082fe102b478890used bydata-encoding
2.9.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476used byder
0.7.10crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcbdepends onderanged
0.5.4crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071depends onused bydigest
0.10.7crates.io↘ 4↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292displaydoc
0.2.5crates.io↘ 3↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0depends oned25519
2.2.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53depends onused byed25519-dalek
2.2.0crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9used byeither
1.15.0crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719encode_unicode
1.0.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0used byenv_filter
0.1.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0depends onused byenv_logger
0.11.8crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069fused byequivalent
1.0.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0fused byerrno
0.3.14crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efebdepends onused byfastrand
2.3.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411beused byfiat-crypto
0.2.9crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811dused byfind-crate
0.6.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2depends onfind-msvc-tools
0.1.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127used byfixedbitset
0.5.7crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99used byflate2
1.1.4crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9depends onused byfleet
0.2.0workspace↘ 38↖ 0depends on- abort-on-drop
0.2.2 - age
0.11.1 - age-core
0.11.0 - anyhow
1.0.100 - async-trait
0.1.89 - base64
0.22.1 - better-command
0.1.0 - chrono
0.4.42 - clap
4.5.48 - clap_complete
4.5.58 - fleet-base
0.1.0 - fleet-shared
0.1.0 - futures
0.3.31 - hostname
0.4.1 - human-repr
1.1.0 - indicatif
0.18.0 - itertools
0.14.0 - nix-eval
0.1.0 - nixlike
0.1.0 - nom
8.0.0 - openssh
0.11.5 - opentelemetry
0.30.0 - opentelemetry_sdk
0.30.0 - peg
0.8.5 - regex
1.12.1 - serde
1.0.228 - serde_json
1.0.145 - shlex
1.3.0 - tabled
0.20.0 - tempfile
3.23.0 - thiserror
2.0.17 - time
0.3.44 - tokio
1.47.1 - tokio-util
0.7.17 - tracing
0.1.41 - tracing-indicatif
0.3.13 - tracing-opentelemetry
0.31.0 - tracing-subscriber
0.3.19
- abort-on-drop
fleet-base
0.1.0workspace↘ 25↖ 2depends on- age
0.11.1 - anyhow
1.0.100 - better-command
0.1.0 - chrono
0.4.42 - clap
4.5.48 - fleet-shared
0.1.0 - futures
0.3.31 - hostname
0.4.1 - indoc
2.0.6 - itertools
0.14.0 - nix-eval
0.1.0 - nixlike
0.1.0 - nom
8.0.0 - openssh
0.11.5 - rand
0.9.2 - serde
1.0.228 - serde_json
1.0.145 - tabled
0.20.0 - tempfile
3.23.0 - thiserror
2.0.17 - time
0.3.44 - tokio
1.47.1 - tokio-util
0.7.17 - toml_edit
0.23.7 - tracing
0.1.41
- age
fleet-generator-helper
0.1.0workspace↘ 9↖ 0fleet-install-secrets
0.1.0workspace↘ 10↖ 0fluent
0.16.1crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555adepends onfluent-bundle
0.15.3crates.io↘ 8↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493depends onused byfluent-langneg
0.13.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94depends onfluent-syntax
0.11.1crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33ddepends onfnv
1.0.7crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1foldhash
0.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdbused byform_urlencoded
1.2.2crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcfdepends onfutures
0.3.31crates.io↘ 7↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876depends onfutures-channel
0.3.31crates.io↘ 2↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10depends onfutures-core
0.3.31crates.io↘ 0↖ 18sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663efutures-executor
0.3.31crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9ffutures-io
0.3.31crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6futures-macro
0.3.31crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650depends onused byfutures-sink
0.3.31crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7futures-task
0.3.31crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988futures-util
0.3.31crates.io↘ 10↖ 14sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81depends ongeneric-array
0.14.8crates.io↘ 2↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1dc8f7d2ded5f9209535e4b3fd4d39c002f30902ff5ce9f64e2c33d549576500depends ongetrandom
0.2.16crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592used bygetrandom
0.3.3crates.io↘ 4↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4used byghash
0.5.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1depends onused bygimli
0.32.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7used byglob
0.3.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280used byh2
0.4.12crates.io↘ 11↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386depends onused byhashbrown
0.12.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888used byhashbrown
0.16.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748dused byheaders
0.4.1crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24ebused byheaders-core
0.3.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4depends onused byheck
0.5.0crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55eahex
0.4.3crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70hkdf
0.12.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7depends onused byhmac
0.12.1crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5edepends onhome
0.5.11crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcfdepends onused byhostname
0.4.1crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65depends onused byhttp
1.3.1crates.io↘ 3↖ 20sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565depends onhttp-body
1.0.1crates.io↘ 2↖ 13sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184depends onhttp-body-util
0.1.3crates.io↘ 5↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64ahttparse
1.10.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87used byhttpdate
1.0.3crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdf3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9used byhuman-repr
1.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf58b778a5761513caf593693f8951c97a5b610841e754788400f32102eefdff1used byhyper
1.8.1crates.io↘ 15↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11depends onhyper-timeout
0.5.2crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0used byhyper-util
0.1.17crates.io↘ 16↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8depends oni18n-config
0.4.8crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3e06b90c8a0d252e203c94344b21e35a30f3a3a85dc7db5af8f8df9f3e0c63efi18n-embed
0.15.4crates.io↘ 12↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum669ffc2c93f97e6ddf06ddbe999fcd6782e3342978bb85f7d3c087c7978404c4depends onused byi18n-embed-fl
0.9.4crates.io↘ 11↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum04b2969d0b3fc6143776c535184c19722032b43e6a642d710fa3f88faec53c2ddepends onused byi18n-embed-impl
0.8.4crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0f2cc0e0523d1fe6fc2c6f66e5038624ea8091b3e7748b5e8e0c84b1698db6c2used byiana-time-zone
0.1.64crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fbdepends onused byiana-time-zone-haiku
0.1.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269fdepends onused byicu_collections
2.0.0crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47icu_locale_core
2.0.0crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00aicu_normalizer
2.0.0crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979depends onused byicu_normalizer_data
2.0.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3used byicu_properties
2.0.1crates.io↘ 8↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32bdepends onicu_properties_data
2.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632used byicu_provider
2.0.0crates.io↘ 9↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5afdepends onidna
1.1.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4deused byidna_adapter
1.2.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344depends onused byindexmap
1.9.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99depends onused byindexmap
2.11.4crates.io↘ 2↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5depends onindicatif
0.18.0crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum70a646d946d06bedbbc4cac4c218acf4bbf2d87757a784857025f4d447e4e1cddepends onindoc
2.0.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bdused byinout
0.1.4crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01depends onused byintl_pluralrules
7.0.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972depends onused byintl-memoizer
0.5.3crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163fdepends onio_tee
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4b3f7cef34251886990511df1c61443aa928499d598a9473929ab5a90a527304used byio-uring
0.7.10crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727bdepends onused byipnet
2.11.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130used byiri-string
0.7.8crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2depends onused byis_terminal_polyfill
1.70.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecfused byitertools
0.13.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186depends onused byitertools
0.14.0crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285depends onitoa
1.0.15crates.io↘ 0↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2cjs-sys
0.3.81crates.io↘ 2↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305depends onlazy_static
1.5.0crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fedepends onlibc
0.2.177crates.io↘ 0↖ 23sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976used by- android_system_properties
0.1.5 - backtrace
0.3.76 - clang-sys
1.8.1 - console
0.16.1 - cpufeatures
0.2.17 - errno
0.3.14 - getrandom
0.2.16 - getrandom
0.3.3 - hostname
0.4.1 - hyper-util
0.1.17 - io-uring
0.7.10 - mio
1.0.4 - nix
0.30.1 - openssh
0.11.5 - parking_lot_core
0.9.12 - rand
0.8.5 - ring
0.17.14 - rustix
0.38.44 - rustix
1.1.2 - signal-hook-registry
1.4.6 - socket2
0.5.10 - socket2
0.6.0 - tokio
1.47.1
- android_system_properties
libloading
0.8.9crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55depends onused bylibm
0.2.15crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97delink-cplusplus
1.0.12crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82depends onused bylinked-hash-map
0.5.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770fused bylinux-raw-sys
0.4.15crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807abused bylinux-raw-sys
0.11.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdf1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039used bylitemap
0.8.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956used bylock_api
0.4.14crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965depends onused bylog
0.4.28crates.io↘ 0↖ 16sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432matchers
0.1.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558depends onused bymemchr
2.7.6crates.io↘ 0↖ 13sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273mime
0.3.17crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139aminimal-lexical
0.2.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79aused byminiz_oxide
0.8.9crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316depends onused bymio
1.0.4crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761cused bymultimap
0.10.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084used bynix
0.30.1crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6used bynixlike
0.1.0workspace↘ 8↖ 3nom
7.1.3crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4adepends onnom
8.0.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdf9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405depends onused bynu-ansi-term
0.46.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84depends onused bynum-bigint-dig
0.8.4crates.io↘ 9↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151depends onused bynum-conv
0.1.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9used bynum-integer
0.1.46crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858fdepends onnum-iter
0.1.45crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bfused bynum-traits
0.2.19crates.io↘ 2↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841depends onobject
0.37.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fedepends onused byonce_cell
1.21.3crates.io↘ 0↖ 13sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2donce_cell_polyfill
1.70.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0adused byopaque-debug
0.3.1crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381openssh
0.11.5crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumea0bb128ba90e86bc55dae66031935f361cda4cbc1f011547c55a7d80079bc3eused byopentelemetry
0.30.0crates.io↘ 6↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumaaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6depends onopentelemetry_sdk
0.30.0crates.io↘ 8↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4bdepends onopentelemetry-exporter-env
0.1.0workspace↘ 3↖ 0opentelemetry-http
0.30.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36dused byopentelemetry-otlp
0.30.0crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852bdepends onopentelemetry-proto
0.30.0crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2e046fd7660710fe5a05e8748e70d9058dc15c94ba914e7c4faa7c728f0e8ddcdepends onused byoverload
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39used bypapergrid
0.17.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6978128c8b51d8f4080631ceb2302ab51e32cc6e8615f735ee2f83fd269ae3f1depends onused byparking_lot
0.12.5crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1adepends onused byparking_lot_core
0.9.12crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1used bypbkdf2
0.12.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2depends onpeg
0.8.5crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9928cfca101b36ec5163e70049ee5368a8a1c3c6efc9ca9c5f9cc2f816152477depends onused bypeg-macros
0.8.5crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6298ab04c202fa5b5d52ba03269fb7b74550b150323038878fe6c372d8280f71used bypeg-runtime
0.8.5crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum132dca9b868d927b35b5dd728167b2dee150eb1ad686008fc71ccb298b776fcaused bypem
3.0.6crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291bedepends onused bypercent-encoding
2.3.2crates.io↘ 0↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220petgraph
0.7.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772depends onused bypin-project
1.1.10crates.io↘ 1↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8adepends onpin-project-internal
1.1.10crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861depends onused bypin-project-lite
0.2.16crates.io↘ 0↖ 21sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9bused by- async-stream
0.3.6 - axum
0.7.9 - axum
0.8.7 - axum-core
0.4.5 - axum-core
0.5.5 - axum-extra
0.12.2 - futures-util
0.3.31 - http-body-util
0.1.3 - hyper
1.8.1 - hyper-timeout
0.5.2 - hyper-util
0.1.17 - opentelemetry
0.30.0 - reqwest
0.12.23 - tokio
1.47.1 - tokio-stream
0.1.17 - tokio-util
0.7.17 - tower
0.4.13 - tower
0.5.2 - tower-http
0.5.2 - tower-http
0.6.6 - tracing
0.1.41
- async-stream
pin-utils
0.1.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184used bypkcs1
0.7.5crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47fdepends onused bypkcs8
0.10.2crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7pkg-config
0.3.32crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904cused bypoly1305
0.8.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abfused bypolyval
0.6.2crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25used byportable-atomic
1.11.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483used bypotential_utf
0.1.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08adepends onpowerfmt
0.2.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391used byppv-lite86
0.2.21crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9depends onprettyplease
0.2.37crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62bdepends onproc-macro-error-attr2
2.0.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5depends onused byproc-macro-error2
2.0.1crates.io↘ 4↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802proc-macro2
1.0.101crates.io↘ 1↖ 41sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732dedepends onused by- async-stream-impl
0.3.6 - async-trait
0.1.89 - axum-macros
0.5.0 - bindgen
0.72.1 - clap_derive
4.5.47 - curve25519-dalek-derive
0.1.1 - cxx-build
1.0.186 - cxxbridge-cmd
1.0.186 - cxxbridge-macro
1.0.186 - displaydoc
0.2.5 - futures-macro
0.3.31 - i18n-embed-fl
0.9.4 - i18n-embed-impl
0.8.4 - peg-macros
0.8.5 - pin-project-internal
1.1.10 - prettyplease
0.2.37 - proc-macro-error-attr2
2.0.0 - proc-macro-error2
2.0.1 - prost-derive
0.13.5 - quote
1.0.41 - rust-embed-impl
8.7.2 - serde_derive
1.0.228 - syn
2.0.106 - synstructure
0.13.2 - tabled_derive
0.11.0 - test-log-macros
0.2.18 - thiserror-impl
1.0.69 - thiserror-impl
2.0.17 - tokio-macros
2.5.0 - tonic-build
0.12.3 - tracing-attributes
0.1.30 - vte_generate_state_changes
0.1.2 - wasm-bindgen-backend
0.2.104 - wasm-bindgen-macro-support
0.2.104 - windows-implement
0.60.2 - windows-interface
0.59.3 - yoke-derive
0.8.0 - zerocopy-derive
0.8.27 - zerofrom-derive
0.1.6 - zeroize_derive
1.4.2 - zerovec-derive
0.11.1
- async-stream-impl
prost
0.13.5crates.io↘ 2↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5depends onprost-build
0.13.5crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbe769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bfdepends onused byprost-derive
0.13.5crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4dused byprost-types
0.13.5crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16depends onpusher
0.1.0workspace↘ 8↖ 0quote
1.0.41crates.io↘ 1↖ 40sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1depends onused by- async-stream-impl
0.3.6 - async-trait
0.1.89 - axum-macros
0.5.0 - bindgen
0.72.1 - clap_derive
4.5.47 - curve25519-dalek-derive
0.1.1 - cxx-build
1.0.186 - cxxbridge-cmd
1.0.186 - cxxbridge-macro
1.0.186 - displaydoc
0.2.5 - futures-macro
0.3.31 - i18n-embed-fl
0.9.4 - i18n-embed-impl
0.8.4 - peg-macros
0.8.5 - pin-project-internal
1.1.10 - proc-macro-error-attr2
2.0.0 - proc-macro-error2
2.0.1 - prost-derive
0.13.5 - rust-embed-impl
8.7.2 - serde_derive
1.0.228 - syn
2.0.106 - synstructure
0.13.2 - tabled_derive
0.11.0 - test-log-macros
0.2.18 - thiserror-impl
1.0.69 - thiserror-impl
2.0.17 - tokio-macros
2.5.0 - tonic-build
0.12.3 - tracing-attributes
0.1.30 - vte_generate_state_changes
0.1.2 - wasm-bindgen-backend
0.2.104 - wasm-bindgen-macro
0.2.104 - wasm-bindgen-macro-support
0.2.104 - windows-implement
0.60.2 - windows-interface
0.59.3 - yoke-derive
0.8.0 - zerocopy-derive
0.8.27 - zerofrom-derive
0.1.6 - zeroize_derive
1.4.2 - zerovec-derive
0.11.1
- async-stream-impl
r-efi
5.3.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0fused byrand
0.8.5crates.io↘ 3↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404rand
0.9.2crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1depends onrand_chacha
0.3.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88depends onused byrand_chacha
0.9.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cbdepends onused byrand_core
0.6.4crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922cdepends onrand_core
0.9.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38depends onused byrcgen
0.13.2crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2used byredox_syscall
0.5.18crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362ddepends onused byregex
1.12.1crates.io↘ 4↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4a52d8d02cacdb176ef4678de6c052efb4b3da14b78e4db683a4252762be5433regex-automata
0.1.10crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132depends onused byregex-automata
0.4.12crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum722166aa0d7438abbaa4d5cc2c649dac844e8c56d82fb3d33e9c34b5cd268fc6used byregex-syntax
0.6.29crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1used byregex-syntax
0.8.7crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc3160422bbd54dd5ecfdca71e5fd59b7b8fe2b1697ab2baf64f6d05dcc66d298repl-plugin-unstable
0.1.0workspace↘ 1↖ 0depends onreqwest
0.12.23crates.io↘ 26↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7cebdepends on- base64
0.22.1 - bytes
1.10.1 - futures-channel
0.3.31 - futures-core
0.3.31 - futures-util
0.3.31 - http
1.3.1 - http-body
1.0.1 - http-body-util
0.1.3 - hyper
1.8.1 - hyper-util
0.1.17 - js-sys
0.3.81 - log
0.4.28 - percent-encoding
2.3.2 - pin-project-lite
0.2.16 - serde
1.0.228 - serde_json
1.0.145 - serde_urlencoded
0.7.1 - sync_wrapper
1.0.2 - tokio
1.47.1 - tower
0.5.2 - tower-http
0.6.6 - tower-service
0.3.3 - url
2.5.7 - wasm-bindgen
0.2.104 - wasm-bindgen-futures
0.4.54 - web-sys
0.3.81
- base64
ring
0.17.14crates.io↘ 6↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7rmp
0.8.14crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4used byrmp-serde
1.3.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4dbdepends onused byron
0.11.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdb09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468used byrsa
0.9.8crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691bdepends onused byrust-embed
8.7.2crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178aused byrust-embed-impl
8.7.2crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349cused byrust-embed-utils
8.7.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594depends onrustc_version
0.4.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92depends onused byrustc-demangle
0.1.26crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4aceused byrustc-hash
1.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2used byrustc-hash
2.1.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0dused byrustix
0.38.44crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154used byrustix
1.1.2crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3erustls
0.23.32crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40depends onused byrustls-pemfile
2.2.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50depends onused byrustls-pki-types
1.12.0crates.io↘ 1↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79depends onrustls-webpki
0.103.7crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bfused byrustversion
1.0.22crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46dryu
1.0.20crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481fsalsa20
0.10.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213depends onused bysame-file
1.0.6crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502depends onused byscopeguard
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49used byscratch
1.0.9crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2used byscrypt
0.11.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1fdepends onused bysecrecy
0.10.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5adepends onused byself_cell
0.10.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915ddepends onused byself_cell
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749used bysemver
1.0.27crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2used byserde
1.0.228crates.io↘ 2↖ 34sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9edepends onused by- axum
0.7.9 - basic-toml
0.1.10 - better-command
0.1.0 - bitflags
2.9.4 - chrono
0.4.42 - codespan-reporting
0.12.0 - ed25519-dalek
2.2.0 - fleet
0.2.0 - fleet-base
0.1.0 - fleet-install-secrets
0.1.0 - fleet-shared
0.1.0 - i18n-config
0.4.8 - iri-string
0.7.8 - nix-eval
0.1.0 - nixlike
0.1.0 - opentelemetry-proto
0.30.0 - reqwest
0.12.23 - rmp-serde
1.3.0 - ron
0.11.0 - serde-transcode
1.1.1 - serde_bytes
0.11.19 - serde_json
1.0.145 - serde_path_to_error
0.1.20 - serde_urlencoded
0.7.1 - terraform-provider-fleet
0.1.0 - tf-provider
0.2.2 - time
0.3.44 - toml
0.5.11 - tracing-serde
0.2.0 - tracing-subscriber
0.3.19 - unic-langid-impl
0.9.6 - url
2.5.7 - x25519-dalek
2.0.1 - yoke
0.8.0
- axum
serde_bytes
0.11.19crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8depends onused byserde_core
1.0.228crates.io↘ 1↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67addepends onserde_derive
1.0.228crates.io↘ 3↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79depends onserde_json
1.0.145crates.io↘ 5↖ 12sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79cserde_path_to_error
0.1.20crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457depends onused byserde_urlencoded
0.7.1crates.io↘ 4↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fdused byserde-transcode
1.1.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2depends onused bysha1
0.10.6crates.io↘ 3↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6badepends onsha2
0.10.9crates.io↘ 3↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283depends onsharded-slab
0.1.7crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6depends onused byshell-escape
0.1.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184fused byshlex
1.3.0crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64signal-hook-registry
1.4.6crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28bdepends onused bysignature
2.2.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329dedepends onused bysimd-adler32
0.3.7crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078feused byslab
0.4.11crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589smallvec
1.15.1crates.io↘ 0↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03socket2
0.5.10crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678depends onused bysocket2
0.6.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807depends onused byspin
0.9.8crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67used byspki
0.7.3crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29ddepends onstable_deref_trait
1.2.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596used bystrsim
0.11.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4fsubtle
2.6.1crates.io↘ 0↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292syn
2.0.106crates.io↘ 3↖ 37sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6used by- async-stream-impl
0.3.6 - async-trait
0.1.89 - axum-macros
0.5.0 - bindgen
0.72.1 - clap_derive
4.5.47 - curve25519-dalek-derive
0.1.1 - cxx-build
1.0.186 - cxxbridge-cmd
1.0.186 - cxxbridge-macro
1.0.186 - displaydoc
0.2.5 - futures-macro
0.3.31 - i18n-embed-fl
0.9.4 - i18n-embed-impl
0.8.4 - pin-project-internal
1.1.10 - prettyplease
0.2.37 - proc-macro-error2
2.0.1 - prost-build
0.13.5 - prost-derive
0.13.5 - rust-embed-impl
8.7.2 - serde_derive
1.0.228 - synstructure
0.13.2 - tabled_derive
0.11.0 - test-log-macros
0.2.18 - thiserror-impl
1.0.69 - thiserror-impl
2.0.17 - tokio-macros
2.5.0 - tonic-build
0.12.3 - tracing-attributes
0.1.30 - wasm-bindgen-backend
0.2.104 - wasm-bindgen-macro-support
0.2.104 - windows-implement
0.60.2 - windows-interface
0.59.3 - yoke-derive
0.8.0 - zerocopy-derive
0.8.27 - zerofrom-derive
0.1.6 - zeroize_derive
1.4.2 - zerovec-derive
0.11.1
- async-stream-impl
sync_wrapper
1.0.2crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263depends onsynstructure
0.13.2crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2depends ontabled
0.20.0crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume39a2ee1fbcd360805a771e1b300f78cc88fec7b8d3e2f71cd37bbf23e725c7dused bytabled_derive
0.11.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0ea5d1b13ca6cff1f9231ffd62f15eefd72543dab5e468735f1a456728a02846used bytempfile
3.23.0crates.io↘ 5↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16termcolor
1.4.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755depends onused byterminal_size
0.4.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0depends onused byterraform-provider-fleet
0.1.0workspace↘ 5↖ 0test-log
0.2.18crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1e33b98a582ea0be1168eba097538ee8dd4bbe0f2b01b22ac92ea30054e5be7bused bytest-log-macros
0.2.18crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum451b374529930d7601b1eef8d32bc79ae870b6079b069401709c2a8bf9e75f36depends onused bytesting_table
0.3.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0f8daae29995a24f65619e19d8d31dea5b389f3d853d8bf297bbf607cd0014ccdepends onused bytf-provider
0.2.2crates.io↘ 20↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd80ea2e5f9f54717952d199888aab7e607dc99275ec5221f1259ce7a5f55f5a6depends onthiserror
1.0.69crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52depends onthiserror
2.0.17crates.io↘ 1↖ 10sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8depends onthiserror-impl
1.0.69crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1depends onused bythiserror-impl
2.0.17crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913depends onused bythread_local
1.1.9crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185depends onused bytime
0.3.44crates.io↘ 6↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9dtime-core
0.1.6crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6bused bytime-macros
0.2.24crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3depends onused bytinystr
0.8.1crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8bdepends ontokio
1.47.1crates.io↘ 11↖ 22sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038depends onused by- abort-on-drop
0.2.2 - axum
0.8.7 - fleet
0.2.0 - fleet-base
0.1.0 - h2
0.4.12 - hyper
1.8.1 - hyper-timeout
0.5.2 - hyper-util
0.1.17 - openssh
0.11.5 - opentelemetry-otlp
0.30.0 - pusher
0.1.0 - reqwest
0.12.23 - terraform-provider-fleet
0.1.0 - tf-provider
0.2.2 - tokio-rustls
0.26.4 - tokio-stream
0.1.17 - tokio-tungstenite
0.28.0 - tokio-util
0.7.17 - tonic
0.12.3 - tonic
0.13.1 - tower
0.4.13 - tower
0.5.2
- abort-on-drop
tokio-macros
2.5.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8depends onused bytokio-rustls
0.26.4crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61depends onused bytokio-stream
0.1.17crates.io↘ 4↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumeca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047tokio-tungstenite
0.28.0crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857used bytokio-util
0.7.17crates.io↘ 5↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594toml
0.5.11crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234depends onused bytoml_datetime
0.7.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533depends onused bytoml_edit
0.23.7crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8dused bytoml_parser
1.0.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800edepends onused bytoml_writer
1.0.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdf8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2used bytonic
0.12.3crates.io↘ 24↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52depends on- async-stream
0.3.6 - async-trait
0.1.89 - axum
0.7.9 - base64
0.22.1 - bytes
1.10.1 - h2
0.4.12 - http
1.3.1 - http-body
1.0.1 - http-body-util
0.1.3 - hyper
1.8.1 - hyper-timeout
0.5.2 - hyper-util
0.1.17 - percent-encoding
2.3.2 - pin-project
1.1.10 - prost
0.13.5 - rustls-pemfile
2.2.0 - socket2
0.5.10 - tokio
1.47.1 - tokio-rustls
0.26.4 - tokio-stream
0.1.17 - tower
0.4.13 - tower-layer
0.3.3 - tower-service
0.3.3 - tracing
0.1.41
used by- async-stream
tonic
0.13.1crates.io↘ 19↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9depends ontonic-build
0.12.3crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11depends onused bytower
0.4.13crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1cdepends onused bytower
0.5.2crates.io↘ 11↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9depends ontower-http
0.5.2crates.io↘ 9↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5depends onused bytower-http
0.6.6crates.io↘ 10↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumadc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2depends onused bytower-layer
0.3.3crates.io↘ 0↖ 11sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780etower-service
0.3.3crates.io↘ 0↖ 14sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3tracing
0.1.41crates.io↘ 4↖ 22sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0used by- axum
0.8.7 - axum-core
0.5.5 - axum-extra
0.12.2 - better-command
0.1.0 - fleet
0.2.0 - fleet-base
0.1.0 - fleet-install-secrets
0.1.0 - h2
0.4.12 - hyper-util
0.1.17 - nix-eval
0.1.0 - opentelemetry
0.30.0 - opentelemetry-otlp
0.30.0 - pusher
0.1.0 - tf-provider
0.2.2 - tonic
0.12.3 - tonic
0.13.1 - tower
0.4.13 - tower
0.5.2 - tower-http
0.5.2 - tracing-indicatif
0.3.13 - tracing-opentelemetry
0.31.0 - tracing-subscriber
0.3.19
- axum
tracing-attributes
0.1.30crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903depends onused bytracing-core
0.1.34crates.io↘ 2↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678depends ontracing-indicatif
0.3.13crates.io↘ 4↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum04d4e11e0e27acef25a47f27e9435355fecdc488867fa2bc90e75b0700d2823dtracing-log
0.2.0crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3tracing-opentelemetry
0.31.0crates.io↘ 10↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumddcf5959f39507d0d04d6413119c04f33b623f4f951ebcbdddddfad2d0623a9cdepends onused bytracing-serde
0.2.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1depends onused bytracing-subscriber
0.3.19crates.io↘ 13↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008depends ontungstenite
0.28.0crates.io↘ 9↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442depends onused bytype-map
0.5.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90depends onused bytypenum
1.19.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bbunic-langid
0.9.6crates.io↘ 1↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05depends onunic-langid-impl
0.9.6crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658depends onused byunicase
2.8.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539used byunicode_categories
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14eused byunicode-ident
1.0.19crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9dunicode-width
0.1.14crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6afused byunicode-width
0.2.2crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254unit-prefix
0.5.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817used byuniversal-hash
0.5.1crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07eadepends onused byuntrusted
0.9.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1url
2.5.7crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5bused byutf-8
0.7.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9used byutf8parse
0.2.2crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821valuable
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65used byversion_check
0.9.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105aused byvt100
0.15.2crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum84cd863bf0db7e392ba3bd04994be3473491b31e66340672af5d11943c6274deused byvte
0.11.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197used byvte
0.15.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma5924018406ce0063cd67f8e008104968b74b563ee1b85dde3ed1f7cb87d3dbdused byvte_generate_state_changes
0.1.2crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2edepends onused bywalkdir
2.5.0crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4bdepends onwant
0.3.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0edepends onused bywasi
0.11.1+wasi-snapshot-preview1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44bused bywasi
0.14.7+wasi-0.2.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8cdepends onused bywasip2
1.0.1+wasi-0.2.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7depends onused bywasm-bindgen
0.2.104crates.io↘ 5↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2ddepends onwasm-bindgen-backend
0.2.104crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19wasm-bindgen-futures
0.4.54crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5cused bywasm-bindgen-macro
0.2.104crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119used bywasm-bindgen-macro-support
0.2.104crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7depends onused byweb-sys
0.3.81crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120depends onweb-time
1.1.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bbdepends onwhich
4.4.2crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7used bywinapi
0.3.9crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419used bywinapi-i686-pc-windows-gnu
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6used bywinapi-util
0.1.11crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22depends onwinapi-x86_64-pc-windows-gnu
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183fused bywindows_aarch64_gnullvm
0.52.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3used bywindows_aarch64_gnullvm
0.53.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53used bywindows_aarch64_msvc
0.52.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469used bywindows_aarch64_msvc
0.53.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006used bywindows_i686_gnu
0.52.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0bused bywindows_i686_gnu
0.53.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3used bywindows_i686_gnullvm
0.52.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66used bywindows_i686_gnullvm
0.53.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180cused bywindows_i686_msvc
0.52.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66used bywindows_i686_msvc
0.53.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2used bywindows_x86_64_gnu
0.52.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78used bywindows_x86_64_gnu
0.53.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499used bywindows_x86_64_gnullvm
0.52.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0dused bywindows_x86_64_gnullvm
0.53.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1used bywindows_x86_64_msvc
0.52.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ecused bywindows_x86_64_msvc
0.53.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650used bywindows-core
0.62.2crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9debdepends onused bywindows-implement
0.60.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddfdepends onused bywindows-interface
0.59.3crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358depends onused bywindows-link
0.1.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798aused bywindows-link
0.2.1crates.io↘ 0↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5windows-result
0.4.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5depends onused bywindows-strings
0.5.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091depends onused bywindows-sys
0.52.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33ddepends onused bywindows-sys
0.59.0crates.io↘ 1↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853bdepends onwindows-sys
0.60.2crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcbdepends onwindows-sys
0.61.2crates.io↘ 1↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fcdepends onwindows-targets
0.52.6crates.io↘ 8↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973depends onwindows-targets
0.53.5crates.io↘ 9↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3depends onused bywinnow
0.7.13crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cfdepends onwit-bindgen
0.46.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59used bywriteable
0.6.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bbx25519-dalek
2.0.1crates.io↘ 4↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277yasna
0.5.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cddepends onused byyoke
0.8.0crates.io↘ 4↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695ccyoke-derive
0.8.0crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6used byz85
3.0.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9b3a41ce106832b4da1c065baa4c31cf640cf965fa1483816402b7f6b96f0a64used byzerocopy
0.8.27crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282cdepends onused byzerocopy-derive
0.8.27crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831depends onused byzerofrom
0.1.6crates.io↘ 1↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5depends onzerofrom-derive
0.1.6crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502used byzeroize
1.8.2crates.io↘ 1↖ 12sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0depends onzeroize_derive
1.4.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69depends onused byzerotrie
0.2.2crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595depends onzerovec
0.11.4crates.io↘ 3↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73bzerovec-derive
0.11.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58fdepends onused by
cmds/fleet/src/cmds/build_systems.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/build_systems.rs
+++ b/cmds/fleet/src/cmds/build_systems.rs
@@ -7,8 +7,9 @@
host::{Config, DeployKind, GenerationStorage},
opts::FleetOpts,
};
+use futures::{StreamExt as _, stream::FuturesUnordered};
use nix_eval::nix_go;
-use tokio::task::{LocalSet, spawn_blocking};
+use tokio::task::spawn_blocking;
use tracing::{Instrument, error, field, info, info_span, warn};
#[derive(Parser)]
@@ -47,7 +48,7 @@
"--profile",
format!(
"/nix/var/nix/profiles/{}-{hostname}",
- config.data().gc_root_prefix
+ config.data.gc_root_prefix
),
)
.arg(&out_output);
@@ -60,14 +61,14 @@
impl BuildSystems {
pub async fn run(self, config: &Config, opts: &FleetOpts) -> Result<()> {
let hosts = opts.filter_skipped(config.list_hosts()?)?;
- let set = LocalSet::new();
+ let mut tasks = FuturesUnordered::new();
let build_attr = self.build_attr.clone();
for host in hosts {
let config = config.clone();
let span = info_span!("build", host = field::display(&host.name));
let hostname = host.name;
let build_attr = build_attr.clone();
- set.spawn_local(
+ tasks.push(
(async move {
let built = match build_task(config, hostname.clone(), &build_attr).await {
Ok(path) => path,
@@ -88,7 +89,7 @@
.instrument(span),
);
}
- set.await;
+ for _task in tasks.next().await {}
Ok(())
}
}
@@ -96,7 +97,7 @@
impl Deploy {
pub async fn run(self, config: &Config, opts: &FleetOpts) -> Result<()> {
let hosts = opts.filter_skipped(config.list_hosts()?)?;
- let set = LocalSet::new();
+ let mut tasks = FuturesUnordered::new();
for host in hosts.into_iter() {
let config = config.clone();
let span = info_span!("deploy", host = field::display(&host.name));
@@ -112,7 +113,7 @@
host.set_legacy_ssh_store(legacy);
};
- set.spawn_local(
+ tasks.push(
(async move {
let built = match build_task(config.clone(), hostname.clone(), "toplevel-fleet")
.await
@@ -170,7 +171,7 @@
.instrument(span),
);
}
- set.await;
+ for _task in tasks.next().await {}
Ok(())
}
}
cmds/fleet/src/cmds/rollback.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/rollback.rs
+++ b/cmds/fleet/src/cmds/rollback.rs
@@ -56,7 +56,7 @@
.collect::<HashSet<_>>();
let mut stored_locally = config
.local_host()
- .list_generations(&format!("{}-{}", config.data().gc_root_prefix, host.name))
+ .list_generations(&format!("{}-{}", config.data.gc_root_prefix, host.name))
.await
.inspect_err(|e| {
warn!("failed to list generations available locally: {e}");
cmds/fleet/src/cmds/secrets/mod.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/secrets/mod.rs
+++ b/cmds/fleet/src/cmds/secrets/mod.rs
@@ -412,7 +412,7 @@
if opts.should_skip(&host)? {
continue;
}
- config.key(&host.name).await?;
+ config.host_key(&host.name).await?;
}
}
Secret::Read {
@@ -421,6 +421,7 @@
part: part_name,
mut prefer_identities,
} => {
+ /*
let Some(secret) = config.shared_secret(&name) else {
bail!("secret doesn't exists");
};
@@ -460,6 +461,8 @@
part.raw.data.clone()
};
stdout().write_all(&data)?;
+ */
+ todo!()
}
Secret::Regenerate {
prefer_identities,
@@ -605,6 +608,7 @@
todo!()
}
Secret::List {} => {
+ /*
let _span = info_span!("loading secrets").entered();
let configured = config.list_configured_shared()?;
#[derive(Tabled)]
@@ -638,6 +642,8 @@
*/
}
// info!("loaded\n{}", Table::new(table).to_string())
+ */
+ todo!()
}
Secret::Edit {
name,
@@ -645,7 +651,7 @@
part,
add,
} => {
- let secret = config
+ /*let secret = config
.host_secret(&machine, &name)
.context("secret not found")?;
if let Some(data) = secret.secret.parts.get(&part) {
@@ -656,7 +662,8 @@
String::new()
} else {
bail!("part {part} not found in secret {name}. Did you mean to `--add` it?");
- };
+ };*/
+ todo!()
}
}
Ok(())
cmds/fleet/src/cmds/tf.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/tf.rs
+++ b/cmds/fleet/src/cmds/tf.rs
@@ -72,9 +72,9 @@
let tf_data: TfData = serde_json::from_slice(&data.stdout)
.context("failed to parse terraform fleet output")?;
- let mut data = config.data();
debug!("synchronized done = {tf_data:?}");
- data.extra.insert(
+ let mut extra = config.data.extra.write().expect("no poisoning");
+ extra.insert(
"terraformHosts".to_owned(),
serde_json::to_value(tf_data.hosts).expect("should be valid extra"),
);
cmds/fleet/src/main.rsdiffbeforeafterboth--- a/cmds/fleet/src/main.rs
+++ b/cmds/fleet/src/main.rs
@@ -4,7 +4,7 @@
// pub(crate) mod command;
pub(crate) mod extra_args;
-use std::{env, ffi::OsString, process::ExitCode};
+use std::{env, ffi::OsString, process::ExitCode, sync::Arc};
use anyhow::{Result, bail};
use clap::{CommandFactory, Parser};
@@ -23,7 +23,9 @@
use human_repr::HumanCount;
#[cfg(feature = "indicatif")]
use indicatif::{ProgressState, ProgressStyle};
-use nix_eval::{gc_register_my_thread, gc_unregister_my_thread, init_libraries};
+use nix_eval::{
+ gc_register_my_thread, gc_unregister_my_thread, init_libraries, init_tokio_for_nix,
+};
use tracing::{Instrument, error, info, info_span};
#[cfg(feature = "indicatif")]
use tracing_indicatif::IndicatifLayer;
@@ -39,9 +41,9 @@
info!("nothing to prefetch: no prefetch directory");
return Ok(());
}
- let tasks = <FuturesUnordered<LocalBoxFuture<Result<()>>>>::new();
+ let tasks = FuturesUnordered::new();
for entry in std::fs::read_dir(&prefetch_dir)? {
- tasks.push(Box::pin(async {
+ tasks.push(async {
let entry = entry?;
if !entry.metadata()?.is_file() {
bail!("only files should exist in prefetch directory");
@@ -59,7 +61,7 @@
status.arg("store").arg("prefetch-file").arg(path);
status.run_nix_string().instrument(span).await?;
Ok(())
- }));
+ });
}
tasks.try_collect::<Vec<()>>().await?;
Ok(())
@@ -190,7 +192,7 @@
init_libraries();
- tokio::runtime::Builder::new_multi_thread()
+ let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.on_thread_start(|| {
gc_register_my_thread();
@@ -199,8 +201,13 @@
gc_unregister_my_thread();
})
.build()
- .expect("failed to build runtime")
- .block_on(async {
+ .expect("failed to build runtime");
+ let runtime = Arc::new(runtime);
+
+ init_tokio_for_nix(runtime.clone());
+
+ runtime.block_on(async {
+ tokio::task::spawn(async move {
if let Err(e) = main_real(opts).await {
error!("{e:#}");
ExitCode::FAILURE
@@ -208,6 +215,9 @@
ExitCode::SUCCESS
}
})
+ .await
+ .expect("primary task panicked")
+ })
// async_main(opts)
}
crates/fleet-base/src/command.rsdiffbeforeafterboth--- a/crates/fleet-base/src/command.rs
+++ b/crates/fleet-base/src/command.rs
@@ -334,7 +334,7 @@
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>> = Some(Box::new(stdout));
+ 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));
@@ -397,7 +397,7 @@
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>> = Some(Box::new(stdout));
+ 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));
crates/fleet-base/src/deploy.rsdiffbeforeafterboth--- a/crates/fleet-base/src/deploy.rs
+++ b/crates/fleet-base/src/deploy.rs
@@ -78,7 +78,7 @@
// unit name conflict in systemd-run
// This code is tied to rollback.nix
if !disable_rollback && action.should_create_rollback_marker() {
- let _span = info_span!("preparing").entered();
+ // let _span = info_span!("preparing").entered();
info!("preparing for rollback");
let generation = get_current_generation(host).await?;
info!(
@@ -179,7 +179,7 @@
// FIXME: Connection might be disconnected after activation run
if action.should_activate() && !failed {
- let _span = info_span!("activating").entered();
+ // let _span = info_span!("activating").entered();
info!("executing activation script");
let specialised = if let Some(specialisation) = specialisation {
let mut specialised = built.join("specialisation");
crates/fleet-base/src/fleetdata.rsdiffbeforeafterboth--- a/crates/fleet-base/src/fleetdata.rs
+++ b/crates/fleet-base/src/fleetdata.rs
@@ -1,10 +1,12 @@
use std::{
+ cmp::Ordering,
collections::{
BTreeMap, BTreeSet,
btree_map::{self, Entry},
},
+ fmt,
io::{self, Cursor},
- ops::Deref,
+ sync::RwLock,
};
use age::Recipient;
@@ -77,19 +79,18 @@
pub manager_keys: Vec<ManagerKey>,
#[serde(default)]
- pub hosts: BTreeMap<String, HostData>,
+ pub hosts: RwLock<BTreeMap<String, HostData>>,
#[serde(default, alias = "shared_secrets")]
- pub secrets: FleetSecrets,
+ pub secrets: RwLock<FleetSecrets>,
// extra_name => anything
#[serde(default)]
- #[serde(skip_serializing_if = "BTreeMap::is_empty")]
- pub extra: BTreeMap<String, Value>,
+ pub extra: RwLock<BTreeMap<String, Value>>,
#[serde(default)]
- #[serde(skip_serializing_if = "BTreeMap::is_empty")]
- host_secrets: BTreeMap<String, BTreeMap<String, FleetSecretDistribution>>,
+ #[serde(skip_serializing)]
+ host_secrets: BTreeMap<SecretOwner, BTreeMap<String, FleetSecretDistribution>>,
}
impl FleetData {
pub fn from_str(s: &str) -> anyhow::Result<Self> {
@@ -97,6 +98,8 @@
if !data.host_secrets.is_empty() {
info!("migrating host secrets into shared secrets structure");
data.secrets
+ .write()
+ .expect("no poisoning")
.merge_from_hosts(std::mem::take(&mut data.host_secrets));
}
Ok(data)
@@ -130,128 +133,431 @@
#[serde(rename_all = "camelCase")]
#[must_use]
pub struct FleetSecretData {
- #[serde(default = "Utc::now")]
pub created_at: DateTime<Utc>,
- #[serde(default)]
- #[serde(skip_serializing_if = "Option::is_none", alias = "expire_at")]
+ #[serde(default, skip_serializing_if = "Option::is_none", alias = "expire_at")]
pub expires_at: Option<DateTime<Utc>>,
#[serde(flatten)]
pub parts: BTreeMap<String, FleetSecretPart>,
- #[serde(default)]
- #[serde(skip_serializing_if = "Value::is_null")]
+ #[serde(default, skip_serializing_if = "Value::is_null")]
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);
+
+impl fmt::Display for SecretOwner {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "host:{}", self.0)
+ }
+}
+
+impl SecretOwner {
+ pub fn host(s: impl AsRef<str>) -> SecretOwner {
+ SecretOwner(s.as_ref().to_owned())
+ }
+ pub fn as_host(&self) -> Option<&str> {
+ Some(&self.0)
+ }
+}
+
#[derive(Serialize, Deserialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
#[must_use]
pub struct FleetSecretDistribution {
#[serde(default)]
- pub owners: BTreeSet<String>,
+ owners: BTreeSet<SecretOwner>,
+ #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
+ owners_pending_prune: BTreeMap<SecretOwner, String>,
+
#[serde(flatten)]
pub secret: FleetSecretData,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pending_prune: Option<String>,
#[serde(default, skip_serializing, alias = "managed")]
- pub _deprecated_managed: bool,
+ _deprecated_managed: bool,
+}
+
+const EMPTY_PENDING_PRUNE: &BTreeMap<SecretOwner, String> = &BTreeMap::new();
+impl FleetSecretDistribution {
+ pub fn new(owners: BTreeSet<SecretOwner>, secret: FleetSecretData, now: DateTime<Utc>) -> Self {
+ assert!(
+ !owners.is_empty(),
+ "distribution should have at least one owner"
+ );
+ if let Some(expires_at) = &secret.expires_at {
+ assert!(
+ *expires_at > now,
+ "secret should not be expired on creation"
+ );
+ }
+ Self {
+ owners,
+ secret,
+ owners_pending_prune: BTreeMap::new(),
+ pending_prune: None,
+ _deprecated_managed: true,
+ }
+ }
+
+ fn owners_ex(&self, including_pruned: bool) -> impl Iterator<Item = &SecretOwner> {
+ let pending_prune = if including_pruned {
+ &self.owners_pending_prune
+ } else {
+ EMPTY_PENDING_PRUNE
+ };
+ self.owners.iter().chain(pending_prune.keys())
+ }
+ pub fn owners(&self) -> impl Iterator<Item = &SecretOwner> {
+ self.owners_ex(false)
+ }
+
+ pub fn prune(&mut self, reason: String) {
+ assert!(
+ self.pending_prune.is_none(),
+ "it shouldn't be possible to prune the same distribution twice using public api"
+ );
+ self.pending_prune = Some(reason);
+ }
+ pub fn prune_owners(&mut self, owners: &BTreeSet<SecretOwner>, reason: String) {
+ // if self.owners.iter().all(|o| owners.contains(o)) && self.owners_pending_prune.is_empty() {
+ // self.prune(format!("all owners were pruned: {reason}"));
+ // return;
+ // }
+ for owner in owners {
+ if self.owners.remove(owner) {
+ self.owners_pending_prune
+ .insert(owner.to_owned(), reason.clone());
+ }
+ }
+ // if self.owners.is_empty() {
+ // self.prune("no owners left".to_owned());
+ // }
+ }
+ pub fn unprune_owner(&mut self, owner: SecretOwner) {
+ if self.owners_pending_prune.remove(&owner).is_some() {
+ self.owners.insert(owner);
+ }
+ }
}
-#[derive(Clone)]
+#[derive(Clone, Debug, Default)]
#[must_use]
-pub struct FleetSecretDistributions(Vec<FleetSecretDistribution>);
+pub struct FleetSecretDistributions {
+ stored: Vec<FleetSecretDistribution>,
+}
-impl Deref for FleetSecretDistributions {
- type Target = [FleetSecretDistribution];
-
- fn deref(&self) -> &Self::Target {
- self.0.as_slice()
+fn compare_dists(
+ a: &FleetSecretDistribution,
+ b: &FleetSecretDistribution,
+ prefer_identities: &BTreeSet<SecretOwner>,
+ include_pruned_owners: bool,
+) -> Ordering {
+ use Ordering::*;
+ if prefer_identities.is_empty() {
+ let a_has = a
+ .owners_ex(include_pruned_owners)
+ .any(|o| prefer_identities.contains(o));
+ let b_has = b
+ .owners_ex(include_pruned_owners)
+ .any(|o| prefer_identities.contains(o));
+ match (a_has, b_has) {
+ (true, false) => return Greater,
+ (false, true) => return Less,
+ _ => {}
+ }
+ }
+ match (a.secret.expires_at, b.secret.expires_at) {
+ (None, Some(_)) => return Greater,
+ (Some(_), None) => return Less,
+ (Some(a), Some(b)) => {
+ // Later is better
+ return a.cmp(&b);
+ }
+ (None, None) => {}
}
+
+ // Which one is easier to access
+ return a.owners.len().cmp(&b.owners.len());
}
impl FleetSecretDistributions {
- pub fn owners(&self) -> impl Iterator<Item = &String> {
- self.0.iter().flat_map(|v| v.owners.iter())
+ /// Drop expired distributions
+ fn prune_expired(&mut self, now: DateTime<Utc>) {
+ for ele in self.distributions_mut() {
+ if let Some(expires_at) = ele.secret.expires_at {
+ if expires_at < now {
+ ele.prune(format!("expired during check at {now}"));
+ }
+ }
+ }
+ }
+ /// Perform all pruning relevant to shared secrets
+ /// Also see expected_owner_removed
+ pub fn prune_shared(
+ &mut self,
+ expected_owners: &BTreeSet<SecretOwner>,
+ unique: bool,
+ expected_parts: &BTreeMap<String, GeneratorPart>,
+ expected_generation_data: &Value,
+ regenerate_on_owner_removed: bool,
+ regenerate_on_owner_added: bool,
+ prefer_identities: &BTreeSet<SecretOwner>,
+ now: DateTime<Utc>,
+ ) {
+ self.prune_expired(now);
+ self.prune_generation_data(expected_generation_data, None);
+ self.prune_missing_parts(expected_parts, None);
+
+ let current_owners = self.owners().cloned().collect::<BTreeSet<SecretOwner>>();
+
+ let mut to_add = expected_owners.difference(¤t_owners);
+ if to_add.next().is_some() && unique && regenerate_on_owner_added {
+ for dist in self.distributions_mut() {
+ dist.prune(format!(
+ "owners missing, can't add new distribution, regeneration preferred"
+ ));
+ }
+ return;
+ }
+
+ for to_remove in current_owners.difference(&expected_owners) {
+ self.entry(to_remove.clone()).remove(
+ regenerate_on_owner_removed,
+ "owner was removed from expected owners list, regenerate_on_owner_removed is set"
+ .to_string(),
+ );
+ }
+ if unique {
+ self.prune_nonunique(prefer_identities);
+ }
+ }
+ pub fn prune_host(
+ &mut self,
+ owner: SecretOwner,
+ expected_parts: &BTreeMap<String, GeneratorPart>,
+ expected_generation_data: &Value,
+ now: DateTime<Utc>,
+ ) {
+ self.prune_expired(now);
+ self.prune_generation_data(expected_generation_data, Some(&owner));
+ // TODO: Owner-based pruning is warranted (e.g host no longer has secret defined)
+ self.prune_missing_parts(expected_parts, Some(&owner));
+ }
+ /// Position of best distributions as in iterator returned by distributions()
+ /// None if distributions not found
+ fn best_idx(
+ &self,
+ prefer_identities: &BTreeSet<SecretOwner>,
+ include_pruned_owners: bool,
+ ) -> Option<usize> {
+ self.distributions()
+ .enumerate()
+ .max_by(|(_, a), (_, b)| {
+ compare_dists(&a, &b, prefer_identities, include_pruned_owners)
+ })
+ .map(|(p, _)| p)
+ }
+ /// Secret wants to be the same on all hosts, leave only one unpruned version of it
+ fn prune_nonunique(&mut self, prefer_identities: &BTreeSet<SecretOwner>) {
+ if self.distributions().next().is_none() {
+ return;
+ }
+ let best = self.best_idx(prefer_identities, false).expect("not empty");
+ for (i, dist) in self.distributions_mut().enumerate() {
+ if i != best {
+ dist.prune(
+ "secret wants to be the same on all hosts, only the best one was left"
+ .to_owned(),
+ );
+ }
+ }
+ }
+
+ pub fn try_unprune(&mut self, owner: SecretOwner) -> Option<&FleetSecretDistribution> {
+ assert!(self.get(&owner).is_none(), "secret is not pruned for host");
+ if let Some(dist) = self
+ .distributions_mut()
+ .find(|v| v.owners_pending_prune.contains_key(&owner))
+ {
+ dist.unprune_owner(owner);
+ Some(dist)
+ } else {
+ None
+ }
+ }
+
+ pub fn best_distribution_for_reencryption(
+ &mut self,
+ prefer_identities: &BTreeSet<SecretOwner>,
+ ) -> Option<&mut FleetSecretDistribution> {
+ let best_idx = self.best_idx(prefer_identities, true)?;
+ self.distributions_mut().nth(best_idx)
+ }
+
+ fn prune_missing_parts(
+ &mut self,
+ expected_parts: &BTreeMap<String, GeneratorPart>,
+ filter_owner: Option<&SecretOwner>,
+ ) {
+ 'dist: for ele in self.distributions_mut() {
+ if let Some(filter_owner) = filter_owner {
+ if !ele.owners.contains(filter_owner) {
+ continue;
+ }
+ // Note: secret still can have multiple owners even if it is host-owned
+ // in this case we expect that all owners using the same generator, so we can prune distribution for all of them
+ }
+ for (name, part) in expected_parts {
+ let Some(stored_part) = ele.secret.parts.get(name) else {
+ ele.prune(format!("secret definition added new part: {name}"));
+ continue 'dist;
+ };
+ if part.encrypted != stored_part.raw.encrypted {
+ ele.prune(format!(
+ "secret definition now requires part to be {}",
+ if part.encrypted {
+ "encrypted"
+ } else {
+ "non-encrypted"
+ }
+ ));
+ continue 'dist;
+ }
+ }
+ }
+ }
+ fn prune_generation_data(
+ &mut self,
+ expected_generation_data: &Value,
+ filter_owner: Option<&SecretOwner>,
+ ) {
+ for ele in self.distributions_mut() {
+ if let Some(filter_owner) = filter_owner {
+ if !ele.owners.contains(filter_owner) {
+ continue;
+ }
+ // Note: secret still can have multiple owners even if it is host-owned
+ // in this case we expect that all owners using the same generator, so we can prune distribution for all of them
+ }
+ if ele.secret.generation_data != *expected_generation_data {
+ ele.prune(format!(
+ "expected generation data mismatch: {expected_generation_data:?}"
+ ));
+ }
+ }
}
+
+ /// Prune all distributions with no unpruned owners.
+ /// For ease of reencryption where possible, it is only called on persistence, when in memory - pruned owners are kept and
+ /// can decrypt their secrets.
+ fn prune_dead(&mut self) {
+ for ele in self.distributions_mut() {
+ if ele.owners.is_empty() {
+ ele.prune("no owners left".to_owned());
+ }
+ }
+ }
+
+ pub fn distributions(&self) -> impl Iterator<Item = &FleetSecretDistribution> {
+ self.stored.iter().filter(|v| v.pending_prune.is_none())
+ }
+ pub fn distributions_mut(&mut self) -> impl Iterator<Item = &mut FleetSecretDistribution> {
+ self.stored.iter_mut().filter(|v| v.pending_prune.is_none())
+ }
+ pub fn owners(&self) -> impl Iterator<Item = &SecretOwner> {
+ self.distributions().flat_map(|v| v.owners.iter())
+ }
#[allow(
clippy::len_without_is_empty,
reason = "should not be empty for a long time"
)]
pub fn len(&self) -> usize {
- self.0.len()
+ self.distributions().count()
}
- pub fn get(&self, owner: &str) -> Option<&FleetSecretDistribution> {
- self.0.iter().find(|d| d.owners.contains(owner))
+ pub fn get(&self, owner: &SecretOwner) -> Option<&FleetSecretDistribution> {
+ self.distributions().find(|d| d.owners.contains(owner))
}
- fn entry(&mut self, owner: String) -> DistEntry<'_> {
- let Some(idx) = self.0.iter().position(|d| d.owners.contains(&owner)) else {
+ fn entry(&mut self, owner: SecretOwner) -> DistEntry<'_> {
+ let Some((idx, dist)) = self
+ .distributions()
+ .enumerate()
+ .find(|(_, d)| d.owners.contains(&owner))
+ else {
return DistEntry::Vacant(VacantDistEntry {
distributions: self,
- owner,
+ owners: BTreeSet::from([owner]),
});
};
DistEntry::Occupied(OccupiedDistEntry {
+ owners: dist.owners.clone(),
distributions: self,
idx,
- owner,
})
}
- fn extend(&mut self, dist: FleetSecretDistribution) {
- for owner in &dist.owners {
- self.entry(owner.to_owned()).remove();
+ pub fn extend(&mut self, dist: FleetSecretDistribution, reason: String) {
+ for ele in self.distributions_mut() {
+ ele.prune_owners(&dist.owners, reason.clone());
}
- self.0.push(dist);
+ self.stored.push(dist);
}
- pub fn contains(&self, owner: &str) -> bool {
- self.0.iter().any(|d| d.owners.contains(owner))
+ pub fn contains(&self, owner: &SecretOwner) -> bool {
+ self.distributions().any(|d| d.owners.contains(owner))
}
}
struct OccupiedDistEntry<'d> {
distributions: &'d mut FleetSecretDistributions,
idx: usize,
- owner: String,
+ owners: BTreeSet<SecretOwner>,
}
impl<'d> OccupiedDistEntry<'d> {
- fn remove(self) -> VacantDistEntry<'d> {
- let dist = &mut self.distributions.0[self.idx];
- assert!(
- dist.owners.remove(&self.owner),
- "entry exists, as we have its reference"
- );
- if dist.owners.is_empty() {
- self.distributions.0.remove(self.idx);
+ fn remove(self, whole_dist: bool, reason: String) -> VacantDistEntry<'d> {
+ let dist = &mut self.distributions.stored[self.idx];
+ if whole_dist {
+ dist.prune(reason);
+ } else {
+ dist.prune_owners(&self.owners, reason);
}
VacantDistEntry {
distributions: self.distributions,
- owner: self.owner,
+ owners: self.owners,
}
}
- fn set(self, secret: FleetSecretData) -> Self {
- self.remove().set(secret)
+ fn set(self, secret: FleetSecretData, reason: String) -> Self {
+ self.remove(false, reason).set(secret)
}
}
struct VacantDistEntry<'d> {
distributions: &'d mut FleetSecretDistributions,
- owner: String,
+ owners: BTreeSet<SecretOwner>,
}
impl<'d> VacantDistEntry<'d> {
fn set(self, secret: FleetSecretData) -> OccupiedDistEntry<'d> {
let Self {
distributions,
- owner,
+ owners,
} = self;
- let idx = distributions.0.len();
- distributions.0.push(FleetSecretDistribution {
- owners: BTreeSet::from_iter([owner.clone()]),
+ let idx = distributions.stored.len();
+ distributions.stored.push(FleetSecretDistribution {
+ owners: owners.clone(),
secret,
+ owners_pending_prune: BTreeMap::new(),
+ pending_prune: None,
_deprecated_managed: true,
});
OccupiedDistEntry {
distributions,
- owner,
+ owners,
idx,
}
}
@@ -262,16 +568,16 @@
Occupied(OccupiedDistEntry<'d>),
}
impl DistEntry<'_> {
- fn remove(self) -> Self {
+ fn remove(self, whole_dist: bool, reason: String) -> Self {
match self {
DistEntry::Vacant(_) => self,
- DistEntry::Occupied(o) => Self::Vacant(o.remove()),
+ DistEntry::Occupied(o) => Self::Vacant(o.remove(whole_dist, reason)),
}
}
- fn set(self, secret: FleetSecretData) -> Self {
+ fn set(self, secret: FleetSecretData, reason: String) -> Self {
Self::Occupied(match self {
DistEntry::Vacant(e) => e.set(secret),
- DistEntry::Occupied(e) => e.set(secret),
+ DistEntry::Occupied(e) => e.set(secret, reason),
})
}
}
@@ -281,8 +587,13 @@
where
S: serde::Serializer,
{
+ let mut v = self.clone();
+ v.prune_dead();
let mut found_hosts = BTreeSet::new();
- for ele in self.0.iter() {
+ for ele in v.distributions() {
+ if ele.pending_prune.is_some() {
+ continue;
+ }
if ele.owners.is_empty() {
panic!("consistency: secret distribution has no defined owners");
}
@@ -294,10 +605,15 @@
}
}
}
- match self.0.len() {
+ match v.stored.len() {
0 => panic!("consistency: empty distributions"),
- 1 => self.0[0].serialize(serializer),
- _ => self.0.serialize(serializer),
+ 1 => v.stored[0].serialize(serializer),
+ _ => {
+ let mut sorted = v.stored.clone();
+ // Store outdated distributions last
+ sorted.sort_by_key(|v| v.pending_prune.is_some() as u32);
+ sorted.serialize(serializer)
+ }
}
}
}
@@ -313,15 +629,18 @@
Many(Vec<FleetSecretDistribution>),
}
let d = Distributions::deserialize(deserializer)?;
- let ds = match d {
+ let stored = match d {
Distributions::One(d) => vec![d],
Distributions::Many(ds) => ds,
};
- if ds.is_empty() {
+ if stored.is_empty() {
return Err(de::Error::custom("consistency: empty distributions"));
}
let mut found_hosts = BTreeSet::new();
- for ele in ds.iter() {
+ for ele in stored.iter() {
+ if ele.pending_prune.is_some() {
+ continue;
+ }
if ele.owners.is_empty() {
return Err(de::Error::custom(
"consistency: secret distribution has no defined owners",
@@ -335,73 +654,65 @@
}
}
}
- Ok(Self(ds))
+ Ok(Self { stored })
}
}
-#[derive(Serialize, Deserialize, Default)]
+#[derive(Deserialize, Default)]
pub struct FleetSecrets(BTreeMap<String, FleetSecretDistributions>);
+impl Serialize for FleetSecrets {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ let data: BTreeMap<String, FleetSecretDistributions> = self
+ .0
+ .iter()
+ .filter(|(_, v)| !v.stored.is_empty())
+ .map(|(k, v)| (k.clone(), v.clone()))
+ .collect();
+
+ data.serialize(serializer)
+ }
+}
+
impl FleetSecrets {
pub fn keys(&self) -> btree_map::Keys<String, FleetSecretDistributions> {
self.0.keys()
}
- pub fn keys_for_owner(&self, owner: &str) -> impl Iterator<Item = &String> {
+ pub fn keys_for_owner(&self, owner: &SecretOwner) -> impl Iterator<Item = &String> {
self.0
.iter()
.filter(|(_, d)| d.contains(owner))
.map(|(n, _)| n)
}
- pub fn drop_owner_no_reencrypt(&mut self, secret: &str, owner: &str) -> bool {
- let Entry::Occupied(mut dists) = self.0.entry(secret.to_owned()) else {
- return false;
- };
- let DistEntry::Occupied(dist) = dists.get_mut().entry(owner.to_owned()) else {
- return false;
- };
-
- dist.remove();
-
- if dists.get().0.is_empty() {
- dists.remove();
- };
-
- true
- }
- pub fn set_single_data(&mut self, secret: String, owner: String, data: FleetSecretData) {
- let e = self
- .0
- .entry(secret.to_owned())
- .or_insert_with(|| FleetSecretDistributions(Default::default()));
- e.entry(owner.to_owned()).set(data);
- }
pub fn set_data(&mut self, secret: String, data: FleetSecretDistribution) {
match self.0.entry(secret) {
Entry::Vacant(e) => {
- e.insert(FleetSecretDistributions(vec![data]));
+ e.insert(FleetSecretDistributions { stored: vec![data] });
}
Entry::Occupied(mut e) => {
let dists = e.get_mut();
- dists.extend(data)
+ dists.extend(data, "secret data was replaced".to_owned())
}
}
- }
- pub fn get_single(&self, secret: &str, owner: &str) -> Option<&FleetSecretDistribution> {
- let secret = self.0.get(secret)?;
- secret.get(owner)
}
pub fn get(&self, secret: &str) -> Option<&FleetSecretDistributions> {
self.0.get(secret)
}
+ pub fn get_mut(&mut self, secret: &str) -> Option<&mut FleetSecretDistributions> {
+ self.0.get_mut(secret)
+ }
- pub fn contains_for_owner(&self, secret: &str, owner: &str) -> bool {
- let Some(secret) = self.0.get(secret) else {
- return false;
- };
- secret.contains(owner)
+ pub fn get_or_create(&mut self, secret: &str) -> &mut FleetSecretDistributions {
+ self.0
+ .entry(secret.to_owned())
+ .or_insert(FleetSecretDistributions::default())
}
+
pub fn contains(&self, secret: &str) -> bool {
self.0.contains_key(secret)
}
@@ -411,7 +722,7 @@
fn merge_from_hosts(
&mut self,
- host_secrets: BTreeMap<String, BTreeMap<String, FleetSecretDistribution>>,
+ host_secrets: BTreeMap<SecretOwner, BTreeMap<String, FleetSecretDistribution>>,
) {
for (host, host_secrets) in host_secrets {
for (secret_name, mut secret_data) in host_secrets {
@@ -420,11 +731,27 @@
}
}
}
+
+ pub fn prune_host(&mut self, host: &SecretOwner, expected_nonshared: BTreeSet<String>) {
+ for (name, dists) in self.0.iter_mut() {
+ if expected_nonshared.contains(name) {
+ continue;
+ }
+ for dist in dists.distributions_mut() {
+ if dist.owners.contains(host) {
+ dist.prune_owners(
+ &BTreeSet::from([host.to_owned()]),
+ "host no longer defines this secret".to_owned(),
+ );
+ }
+ }
+ }
+ }
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct Expectations {
- pub owners: BTreeSet<String>,
+ pub owners: BTreeSet<SecretOwner>,
pub generation_data: serde_json::Value,
pub parts: BTreeMap<String, GeneratorPart>,
}
@@ -432,3 +759,26 @@
pub struct GeneratorPart {
pub encrypted: bool,
}
+
+#[derive(Debug, Clone, Copy)]
+pub struct RegenerationConstraints {
+ pub allow_different: bool,
+ pub regenerate_on_owner_added: bool,
+ pub regenerate_on_owner_removed: bool,
+}
+impl RegenerationConstraints {
+ pub fn host_personal() -> Self {
+ Self {
+ allow_different: false,
+ regenerate_on_owner_added: true,
+ regenerate_on_owner_removed: true,
+ }
+ }
+ pub fn without_preferences(self) -> Self {
+ Self {
+ allow_different: self.allow_different,
+ regenerate_on_owner_added: false,
+ regenerate_on_owner_removed: false,
+ }
+ }
+}
crates/fleet-base/src/host.rsdiffbeforeafterboth--- a/crates/fleet-base/src/host.rs
+++ b/crates/fleet-base/src/host.rs
@@ -1,6 +1,5 @@
use std::{
- cell::OnceCell,
- collections::BTreeSet,
+ collections::{BTreeMap, BTreeSet},
ffi::{OsStr, OsString},
fmt::Display,
io::Write,
@@ -11,6 +10,7 @@
};
use anyhow::{Context, Result, anyhow, bail, ensure};
+use chrono::{DateTime, Utc};
use fleet_shared::SecretData;
use nix_eval::{Value, nix_go, nix_go_json, util::assert_warn};
use openssh::{ControlPersist, SessionBuilder};
@@ -22,15 +22,20 @@
use crate::{
command::MyCommand,
- fleetdata::{FleetData, FleetSecretData, FleetSecretDistribution, FleetSecretDistributions},
+ fleetdata::{
+ FleetData, FleetSecretData, FleetSecretDistribution, FleetSecretPart, SecretOwner,
+ },
};
pub struct FleetConfigInternals {
+ pub prefer_identities: BTreeSet<SecretOwner>,
+ pub now: DateTime<Utc>,
+
/// Fleet project directory, containing fleet.nix file.
pub directory: PathBuf,
/// builtins.currentSystem
pub local_system: String,
- pub data: Arc<Mutex<FleetData>>,
+ pub data: Arc<FleetData>,
pub nix_args: Vec<OsString>,
/// fleet_config.config
pub config_field: Value,
@@ -96,16 +101,16 @@
pub struct ConfigHost {
config: Config,
pub name: String,
- groups: OnceCell<Vec<String>>,
+ groups: OnceLock<Vec<String>>,
// TODO: Both of those values are taken from host opts, there should be a cleaner way to specify it
- deploy_kind: OnceCell<DeployKind>,
- session_destination: OnceCell<String>,
- legacy_ssh_store: OnceCell<bool>,
+ deploy_kind: OnceLock<DeployKind>,
+ session_destination: OnceLock<String>,
+ legacy_ssh_store: OnceLock<bool>,
pub host_config: Option<Value>,
- pub nixos_config: OnceCell<Value>,
- pub nixos_unchecked_config: OnceCell<Value>,
+ pub nixos_config: OnceLock<Value>,
+ pub nixos_unchecked_config: OnceLock<Value>,
pub pkgs_override: Option<Value>,
// TODO: Move command helpers away with connectivity refactor
@@ -397,7 +402,38 @@
ensure!(!data.encrypted, "secret came out encrypted");
Ok(data.data)
}
- pub async fn reencrypt(&self, data: SecretData, targets: Vec<String>) -> Result<SecretData> {
+ pub async fn reencrypt_distribution(
+ &self,
+ data: &FleetSecretDistribution,
+ targets: BTreeSet<SecretOwner>,
+ now: DateTime<Utc>,
+ ) -> Result<FleetSecretDistribution> {
+ let mut parts = BTreeMap::new();
+ for (part_name, part) in &data.secret.parts {
+ parts.insert(
+ part_name.clone(),
+ if part.raw.encrypted {
+ FleetSecretPart {
+ raw: self.reencrypt(part.raw.clone(), targets.clone()).await?,
+ }
+ } else {
+ part.clone()
+ },
+ );
+ }
+ let secret = FleetSecretData {
+ created_at: data.secret.created_at,
+ expires_at: data.secret.expires_at,
+ generation_data: data.secret.generation_data.clone(),
+ parts,
+ };
+ Ok(FleetSecretDistribution::new(targets, secret, now))
+ }
+ pub async fn reencrypt(
+ &self,
+ data: SecretData,
+ targets: BTreeSet<SecretOwner>,
+ ) -> Result<SecretData> {
ensure!(data.encrypted, "secret is not encrypted");
let mut cmd = self.cmd("fleet-install-secrets").await?;
cmd.arg("reencrypt").eqarg("--secret", data.to_string());
@@ -537,12 +573,25 @@
}
}
+#[derive(Clone)]
pub struct SharedSecretDefinition(Value);
impl SharedSecretDefinition {
- pub fn expected_owners(&self) -> Result<BTreeSet<String>> {
+ pub fn expected_owners(&self) -> Result<BTreeSet<SecretOwner>> {
let secret = &self.0;
Ok(nix_go_json!(secret.expectedOwners))
}
+ pub fn allow_different(&self) -> Result<bool> {
+ let secret = &self.0;
+ Ok(nix_go_json!(secret.allowDifferent))
+ }
+ pub fn regenerate_on_owner_added(&self) -> Result<bool> {
+ let secret = &self.0;
+ Ok(nix_go_json!(secret.regenerateOnOwnerAdded))
+ }
+ pub fn regenerate_on_owner_removed(&self) -> Result<bool> {
+ let secret = &self.0;
+ Ok(nix_go_json!(secret.regenerateOnOwnerRemoved))
+ }
pub fn generator(&self) -> Result<Value> {
let secret = &self.0;
Ok(nix_go!(secret.generator))
@@ -572,10 +621,10 @@
config: self.clone(),
name: "<virtual localhost>".to_owned(),
host_config: None,
- nixos_config: OnceCell::new(),
- nixos_unchecked_config: OnceCell::new(),
+ nixos_config: OnceLock::new(),
+ nixos_unchecked_config: OnceLock::new(),
groups: {
- let cell = OnceCell::new();
+ let cell = OnceLock::new();
let _ = cell.set(vec![]);
cell
},
@@ -583,9 +632,9 @@
local: true,
session: OnceLock::new(),
- deploy_kind: OnceCell::new(),
- session_destination: OnceCell::new(),
- legacy_ssh_store: OnceCell::new(),
+ deploy_kind: OnceLock::new(),
+ session_destination: OnceLock::new(),
+ legacy_ssh_store: OnceLock::new(),
}
}
@@ -597,17 +646,17 @@
config: self.clone(),
name: name.to_owned(),
host_config: Some(host_config),
- nixos_config: OnceCell::new(),
- nixos_unchecked_config: OnceCell::new(),
- groups: OnceCell::new(),
+ nixos_config: OnceLock::new(),
+ nixos_unchecked_config: OnceLock::new(),
+ groups: OnceLock::new(),
pkgs_override: None,
// TODO: Remove with connectivit refactor
local: self.localhost == name,
session: OnceLock::new(),
- deploy_kind: OnceCell::new(),
- session_destination: OnceCell::new(),
- legacy_ssh_store: OnceCell::new(),
+ deploy_kind: OnceLock::new(),
+ session_destination: OnceLock::new(),
+ legacy_ssh_store: OnceLock::new(),
})
}
pub fn list_hosts(&self) -> Result<Vec<ConfigHost>> {
@@ -623,55 +672,6 @@
pub fn system_config(&self, host: &str) -> Result<Value> {
let fleet_field = &self.config_field;
Ok(nix_go!(fleet_field.hosts[{ host }].nixos.config))
- }
-
- /// Shared secrets configured in fleet.nix or in flake
- pub fn list_configured_shared(&self) -> Result<Vec<String>> {
- let config_field = &self.config_field;
- nix_go!(config_field.sharedSecrets).list_fields()
- }
- pub fn has_shared(&self, name: &str) -> bool {
- let data = self.data();
- data.secrets.contains(name)
- }
- pub fn replace_shared(&self, name: String, shared: FleetSecretDistribution) {
- let mut data = self.data_mut();
- data.secrets.set_data(name, shared);
- }
- pub fn remove_shared(&self, secret: &str) {
- let mut data = self.data_mut();
- data.secrets.remove(secret);
- }
-
- pub fn list_secrets_for_owner(&self, host: &str) -> Vec<String> {
- let data = self.data_mut();
- data.secrets.keys_for_owner(host).cloned().collect()
- }
- pub fn list_secrets(&self) -> Vec<String> {
- let data = self.data_mut();
- data.secrets.keys().cloned().collect()
- }
-
- pub fn has_secret(&self, host: &str, secret: &str) -> bool {
- let data = self.data();
- data.secrets.contains_for_owner(secret, host)
- }
- pub fn insert_secret(&self, host: String, secret: String, value: FleetSecretData) {
- let mut data = self.data_mut();
- data.secrets.set_single_data(secret, host, value);
- }
- pub fn remove_secret(&self, host: &str, secret: &str) {
- let mut data = self.data_mut();
- data.secrets.drop_owner_no_reencrypt(secret, host);
- }
-
- pub fn host_secret(&self, host: &str, secret: &str) -> Option<FleetSecretDistribution> {
- let data = self.data();
- data.secrets.get_single(secret, host).cloned()
- }
- pub fn shared_secret(&self, secret: &str) -> Option<FleetSecretDistributions> {
- let data = self.data();
- data.secrets.get(secret).cloned()
}
pub fn secret_definition(&self, secret: &str) -> Result<Option<SharedSecretDefinition>> {
@@ -685,22 +685,9 @@
))))
}
- // TODO: Should this be something modifiable from other processes?
- // E.g terraform provider might want to update FleetData (e.g secrets),
- // and current implementation assumes only one process holds current fleet.nix
- // Given that it is no longer needs to be a file for nix evaluation,
- // maybe it can be a .nix file for persistence, but accessible only
- // thru some shared state controller? Might it be stored in terraform
- // state provider?
- pub fn data(&'_ self) -> MutexGuard<'_, FleetData> {
- self.data.lock().unwrap()
- }
- pub fn data_mut(&'_ self) -> MutexGuard<'_, FleetData> {
- self.data.lock().unwrap()
- }
pub fn save(&self) -> Result<()> {
let mut tempfile = NamedTempFile::new_in(self.directory.clone()).context("failed to create updated version of fleet.nix in the same directory as original.\nDo you have write access to it? Access only to the fleet.nix won't be enough, the directory is used for atomic overwrite operation.\nIt is not recommended to use fleet by root anyway, move fleet project to your home directory.")?;
- let data = nixlike::serialize(&self.data() as &FleetData)?;
+ let data = nixlike::serialize(&*self.data)?;
tempfile.write_all(
format!(
"# This file contains fleet state and shouldn't be edited by hand\n\n{data}\n\n# vim: ts=2 et nowrap\n"
crates/fleet-base/src/keys.rsdiffbeforeafterboth--- a/crates/fleet-base/src/keys.rs
+++ b/crates/fleet-base/src/keys.rs
@@ -1,17 +1,17 @@
use std::str::FromStr as _;
use age::Recipient;
-use anyhow::{Result, anyhow};
+use anyhow::{Result, anyhow, bail};
use futures::{StreamExt as _, TryStreamExt as _};
use itertools::Itertools as _;
use tracing::warn;
-use crate::host::Config;
+use crate::{fleetdata::SecretOwner, host::Config};
impl Config {
- pub fn cached_key(&self, host: &str) -> Option<String> {
- let data = self.data();
- let key = data.hosts.get(host).map(|h| &h.encryption_key);
+ fn cached_host_key(&self, host: &str) -> Option<String> {
+ let hosts = self.data.hosts.read().expect("no poisoning");
+ let key = hosts.get(host).map(|h| &h.encryption_key);
if let Some(key) = key
&& key.is_empty()
{
@@ -20,13 +20,13 @@
key.cloned()
}
pub fn update_key(&self, host: &str, key: String) {
- let mut data = self.data_mut();
- let host = data.hosts.entry(host.to_string()).or_default();
+ let mut hosts = self.data.hosts.write().expect("no poisoning");
+ let host = hosts.entry(host.to_string()).or_default();
host.encryption_key = key.trim().to_string();
}
- pub async fn key(&self, host: &str) -> anyhow::Result<String> {
- if let Some(key) = self.cached_key(host) {
+ pub async fn host_key(&self, host: &str) -> anyhow::Result<String> {
+ if let Some(key) = self.cached_host_key(host) {
Ok(key)
} else {
warn!("Loading key for {}", host);
@@ -38,18 +38,24 @@
Ok(key)
}
}
+ pub async fn key(&self, owner: &SecretOwner) -> anyhow::Result<String> {
+ if let Some(host) = owner.as_host() {
+ self.host_key(host).await
+ } else {
+ bail!("only host keys supported for now")
+ }
+ }
/// Insecure, requires root
- pub async fn recipient(&self, host: &str) -> anyhow::Result<Box<dyn Recipient>> {
+ pub async fn recipient(&self, host: &SecretOwner) -> anyhow::Result<Box<dyn Recipient>> {
let key = self.key(host).await?;
age::ssh::Recipient::from_str(&key)
.map_err(|e| anyhow!("parse recipient error: {e:?}"))
.map(|v| Box::new(v) as Box<dyn Recipient>)
}
- pub async fn recipients(&self, hosts: Vec<String>) -> Result<Vec<Box<dyn Recipient>>> {
- let hosts = self.expand_owner_set(hosts)?;
+ pub async fn recipients(&self, hosts: Vec<SecretOwner>) -> Result<Vec<Box<dyn Recipient>>> {
futures::stream::iter(hosts.iter())
- .then(|m| self.recipient(m.as_ref()))
+ .then(|m| self.recipient(m))
.try_collect::<Vec<_>>()
.await
}
@@ -58,9 +64,8 @@
pub async fn orphaned_data(&self) -> Result<Vec<String>> {
let mut out = Vec::new();
let host_names = self.list_hosts()?.into_iter().map(|h| h.name).collect_vec();
- for hostname in self
- .data()
- .hosts
+ let hosts = self.data.hosts.read().expect("no poisoning");
+ for hostname in hosts
.iter()
.filter(|(_, host)| !host.encryption_key.is_empty())
.map(|(n, _)| n)
crates/fleet-base/src/lib.rsdiffbeforeafterboth--- a/crates/fleet-base/src/lib.rs
+++ b/crates/fleet-base/src/lib.rs
@@ -5,5 +5,4 @@
mod keys;
pub mod opts;
pub mod primops;
-pub mod secret;
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,5 +1,5 @@
use std::{
- collections::BTreeMap,
+ collections::{BTreeMap, BTreeSet},
env::current_dir,
ffi::OsString,
str::FromStr,
@@ -7,6 +7,7 @@
};
use anyhow::{Context, Result, bail};
+use chrono::Utc;
use nix_eval::{
FetchSettings, FlakeLockFlags, FlakeReference, FlakeReferenceParseFlags, FlakeSettings, Value,
gc_now, nix_go, util::assert_warn,
@@ -212,7 +213,7 @@
}
let bytes =
std::fs::read_to_string(&fleet_data_path).context("reading fleet state (fleet.nix)")?;
- let data = Arc::new(Mutex::new(FleetData::from_str(&bytes)?));
+ let data = Arc::new(FleetData::from_str(&bytes)?);
init_primops();
@@ -265,6 +266,10 @@
gc_now();
}
let config = Config(Arc::new(FleetConfigInternals {
+ // TODO: Load from somewhere
+ prefer_identities: BTreeSet::new(),
+ now: Utc::now(),
+
directory,
data,
flake_outputs: flake,
crates/fleet-base/src/primops.rsdiffbeforeafterboth--- a/crates/fleet-base/src/primops.rs
+++ b/crates/fleet-base/src/primops.rs
@@ -4,19 +4,16 @@
use anyhow::{Context, bail, ensure};
use fleet_shared::SecretData;
use itertools::Itertools;
-use nix_eval::{NativeFn, Value, nix_go, nix_go_json};
+use nix_eval::{NativeFn, Value, await_in_nix, nix_go, nix_go_json};
use serde::Deserialize;
use tracing::{info, warn};
use crate::fleetdata::{
Expectations, FleetSecretData, FleetSecretDistribution, FleetSecretPart, GeneratorPart,
+ RegenerationConstraints, SecretOwner,
};
use crate::host::{Config, ConfigHost};
-use crate::secret::{RegenerationReason, secret_needs_regeneration};
use anyhow::{Result, anyhow};
-
-#[derive(thiserror::Error, Debug)]
-enum Error {}
pub static PRIMOPS_DATA: OnceLock<Config> = OnceLock::new();
@@ -28,7 +25,6 @@
}
pub fn get_pkgs_and_generators(host_on: &ConfigHost, recipients: Vec<String>) -> Result<Value> {
- info!("get pkgs");
let pkgs = host_on.pkgs()?;
let default_mk_secret_generators = nix_go!(pkgs.mkSecretGenerators);
let generators = nix_go!(default_mk_secret_generators(Obj { recipients }));
@@ -57,6 +53,31 @@
Ok(default_generator_drv)
}
+fn secret_to_parts(
+ secret_name: &str,
+ secret: &BTreeMap<String, FleetSecretPart>,
+ expected: &BTreeMap<String, GeneratorPart>,
+) -> Value {
+ let mut out = HashMap::new();
+ for (part_name, part) in secret {
+ if !expected.contains_key(part_name) {
+ warn!(
+ "secret {secret_name} part {part_name} is stored, but not defined in nixos config, it will not be passed to nix"
+ );
+ continue;
+ };
+ out.insert(
+ part_name.as_str(),
+ Value::new_attrs(HashMap::from_iter([(
+ "raw",
+ Value::new_str(&part.raw.to_string()),
+ )])),
+ );
+ }
+
+ Value::new_attrs(out)
+}
+
pub async fn generate(
config: &Config,
expectations: Expectations,
@@ -76,9 +97,12 @@
} else {
config.local_host()
};
- let pkgs_and_generators =
- get_pkgs_and_generators(&host_on, expectations.owners.iter().cloned().collect())
- .context("failed to get pkgs for target host")?;
+ let mut recipients = Vec::new();
+ for owner in &expectations.owners {
+ recipients.push(config.key(owner).await?);
+ }
+ let pkgs_and_generators = get_pkgs_and_generators(&host_on, recipients)
+ .context("failed to get pkgs for target host")?;
let generator = call_package(config, &pkgs_and_generators, generator)
.context("failed to evaluate generator for target host")?;
@@ -147,15 +171,8 @@
generation_data: expectations.generation_data.clone(),
};
- let new_data = FleetSecretDistribution {
- secret: new_data,
- owners: expectations.owners.clone(),
- _deprecated_managed: true,
- };
-
- if let Some(reason) = secret_needs_regeneration(&new_data, &expectations) {
- bail!("newly generated secret needs to be regenerated: {reason}")
- }
+ let new_data =
+ FleetSecretDistribution::new(expectations.owners.clone(), new_data, config.now);
Ok(new_data)
}
@@ -166,18 +183,41 @@
}
pub fn init_primops() {
- info!("initializing primops");
NativeFn::new(
+ c"__fleetEnsureHostSecrets",
+ c"Ensure no extra secrets are stored for the host, pruning unknown",
+ [c"host", c"expectedNonshared", c"expectedShared", c"rest"],
+ |_es, [host, expected_nonshared, expected_shared, rest]| {
+ let host = SecretOwner::host(host.to_string()?);
+ let expected_nonshared: BTreeSet<String> = expected_nonshared.as_json()?;
+ let expected_shared: BTreeSet<String> = expected_shared.as_json()?;
+
+ let mut expected = expected_nonshared;
+ expected.extend(expected_shared);
+
+ let config = PRIMOPS_DATA
+ .get()
+ .expect("primops data should be set on init");
+
+ config
+ .data
+ .secrets
+ .write()
+ .expect("no poisoning")
+ .prune_host(&host, expected);
+
+ Ok(rest.clone())
+ },
+ )
+ .register();
+ NativeFn::new(
c"__fleetEnsureHostSecret",
c"Ensure secret existence for a host, regenerating it in case of some mismatch",
[c"host", c"secret", c"generator"],
|es, [host, secret, generator]| {
- info!("get host");
- let host = host.to_string()?;
- info!("get secret");
+ let host = SecretOwner::host(&host.to_string()?);
let secret = secret.to_string()?;
- info!("get config");
let config = PRIMOPS_DATA
.get()
.expect("primops data should be set on init");
@@ -193,50 +233,101 @@
ensure!(expected_owners.contains(&host), "secret {secret} does not define {host} as expected owner");
- (true, shared_def.generator()?, expected_owners)
+ (Some(shared_def.clone()), shared_def.generator()?, expected_owners)
} else {
if shared_def.is_some() {
bail!("hosts can only have their own generators for non-shared secrets, either set host secret generator to \"shared\", or remove shared secret generator at fleetConfiguration.secrets.{secret}.generator")
}
- (false, generator.clone(), BTreeSet::from_iter([host.clone()]))
+ (None, generator.clone(), BTreeSet::from_iter([host.clone()]))
};
- let default_generator_drv = get_default_generator_drv(config, &generator).context("failed to evaluate default generator")?;
- let expectations = Expectations {
+ let default_generator_drv = get_default_generator_drv(config, &generator)?;
+ let mut expectations = Expectations {
parts: nix_go_json!(default_generator_drv.parts),
generation_data: nix_go_json!(default_generator_drv.generationData),
- owners: expected_owners,
+ owners: expected_owners.clone(),
+ };
+ let constraints = if let Some(shared) = &shared{
+ RegenerationConstraints {
+ allow_different: nix_go_json!(default_generator_drv.allowDifferent) && shared.allow_different()?,
+ regenerate_on_owner_added: shared.regenerate_on_owner_added()?,
+ regenerate_on_owner_removed: shared.regenerate_on_owner_added()?,
+ }
+ } else {
+ RegenerationConstraints::host_personal()
};
- let reason: RegenerationReason = 'regenerate: {
- let Some(existing) = config
- .host_secret(&host, &secret) else {
- break 'regenerate RegenerationReason::Missing;
+ let mut secrets = config.data.secrets.write().expect("no poisoning");
+ let dists = secrets.get_or_create(&secret);
+
+ if shared.is_some() {
+ dists.prune_shared(&expected_owners, !constraints.allow_different, &expectations.parts, &expectations.generation_data, constraints.regenerate_on_owner_removed, constraints.regenerate_on_owner_added, &config.prefer_identities, config.now);
+ } else {
+ dists.prune_host(host.clone(), &expectations.parts, &expectations.generation_data, config.now);
+ };
+
+ if let Some(dist) = dists.get(&host) {
+ return Ok(secret_to_parts(&secret, &dist.secret.parts, &expectations.parts));
};
- if let Some(reason) = secret_needs_regeneration(&existing, &expectations) {
- break 'regenerate reason;
+
+ let mut reencrypt_targets = expectations.owners.clone();
+ for dist in dists.distributions() {
+ for own in dist.owners() {
+ reencrypt_targets.remove(own);
+ }
}
+ if !constraints.regenerate_on_owner_added {
+ if let Some(unpruned) = dists.try_unprune(host.clone()) {
+ return Ok(secret_to_parts(&secret, &unpruned.secret.parts, &expectations.parts));
+ } else if let Some(best) = dists.best_distribution_for_reencryption(&config.prefer_identities) {
+ let new_owners = reencrypt_targets.clone();
+ let mut reencrypt_targets = reencrypt_targets;
+ reencrypt_targets.extend(best.owners().cloned());
- let mut parts = expectations.parts.clone();
+ let mut preferred = best.owners().collect_vec();
+ preferred.sort_by_key(|v| !config.prefer_identities.contains(*v));
+
+ warn!("reencrypting secret {secret} as it is missing for host {host}");
- let mut out = HashMap::new();
- for (part_name, part) in &existing.secret.parts {
- let Some(definition) = parts.remove(part_name) else {
- warn!("secret {secret} part {part_name} is stored, but not defined in nixos config, it will not be passed to nix");
- continue;
+ for owner in preferred {
+ if let Some(hostname) = owner.as_host() && let Ok(host) = config.host(hostname) {
+ let best = best.clone();
+ let reencrypt_targets = reencrypt_targets.clone();
+ let reencrypted = match await_in_nix(async move {
+ host.reencrypt_distribution(&best, reencrypt_targets.clone(), config.now).await
+ }) {
+ Ok(r) => r,
+ Err(e) => {
+ warn!("reencryption failed on {hostname}: {e:?}");
+ continue;
+ }
+ };
+ dists.extend(reencrypted.clone(), format!("secret was reencrypted to extend with new owners: {new_owners:?}"));
+ return Ok(secret_to_parts(&secret, &reencrypted.secret.parts, &expectations.parts));
+ };
+ }
+ warn!("failed to reencrypt using any host")
};
- assert!(definition.encrypted != part.raw.encrypted, "encryption status is checked by secret_needs_regeneration");
- out.insert(part_name.as_str(), Value::new_attrs(HashMap::from_iter([("raw", Value::new_str(&part.raw.to_string()))])));
- }
- assert!(parts.is_empty(), "secret part is missing, secret_needs_regeneration should check that");
+ };
- return Ok(Value::new_attrs(out))
- };
+ if constraints.allow_different {
+ for dist in dists.distributions() {
+ for own in dist.owners() {
+ expectations.owners.remove(own);
+ }
+ }
+ }
+ info!("secret {secret} is being generated for {:?}", expectations.owners);
- todo!()
+ let expectations_ = expectations.clone();
+ let generated = await_in_nix(async move {
+ generate(config, expectations_, &generator, &default_generator_drv).await
+ })?;
+ dists.extend(generated.clone(), format!("secret was generated"));
+ return Ok(secret_to_parts(&secret, &generated.secret.parts, &expectations.parts));
},
)
.register();
crates/fleet-base/src/secret.rsdiffbeforeafterboth--- a/crates/fleet-base/src/secret.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-use std::collections::{BTreeMap, BTreeSet};
-
-use chrono::{DateTime, Utc};
-
-use crate::fleetdata::{Expectations, FleetSecretData, FleetSecretDistribution, GeneratorPart};
-
-#[derive(thiserror::Error, Debug)]
-pub enum RegenerationReason {
- #[error("owners added: {0:?}")]
- OwnersAdded(BTreeSet<String>),
- #[error("owners added: {0:?}")]
- OwnersRemoved(BTreeSet<String>),
- #[error("unexpected generation data, expected: {expected:?}, found: {found:?}")]
- GenerationData {
- expected: serde_json::Value,
- found: serde_json::Value,
- },
- #[error("unexpected part list, expected: {expected:?}, found: {found:?}")]
- PartList {
- expected: BTreeSet<String>,
- found: BTreeSet<String>,
- },
- #[error("part {0} is expected to be encrypted")]
- ExpectedPrivate(String),
- #[error("part {0} is not expected to be encrypted")]
- ExpectedPublic(String),
- #[error("secret is expired at {0}")]
- Expired(DateTime<Utc>),
-
- #[error("secret is not generated for this host")]
- Missing,
-}
-
-pub fn secret_needs_regeneration(
- secret: &FleetSecretDistribution,
- expectations: &Expectations,
-) -> Option<RegenerationReason> {
- let added: BTreeSet<String> = expectations
- .owners
- .difference(&secret.owners)
- .cloned()
- .collect();
- if !added.is_empty() {
- return Some(RegenerationReason::OwnersAdded(added));
- }
-
- let removed: BTreeSet<String> = secret
- .owners
- .difference(&expectations.owners)
- .cloned()
- .collect();
- if !removed.is_empty() {
- return Some(RegenerationReason::OwnersRemoved(removed));
- }
-
- if secret.secret.generation_data != expectations.generation_data {
- return Some(RegenerationReason::GenerationData {
- expected: expectations.generation_data.clone(),
- found: secret.secret.generation_data.clone(),
- });
- }
-
- let expected: BTreeSet<String> = expectations.parts.keys().cloned().collect();
- let found: BTreeSet<String> = secret.secret.parts.keys().cloned().collect();
-
- if found != expected {
- return Some(RegenerationReason::PartList { expected, found });
- }
-
- for (name, value) in secret.secret.parts.iter() {
- let expectation = expectations
- .parts
- .get(name)
- .expect("found == expected checked");
- if value.raw.encrypted {
- if !expectation.encrypted {
- return Some(RegenerationReason::ExpectedPrivate(name.clone()));
- }
- } else if expectation.encrypted {
- return Some(RegenerationReason::ExpectedPublic(name.clone()));
- }
- }
-
- if let Some(expiration) = secret.secret.expires_at {
- // TODO: Leeway?
- if expiration < Utc::now() {
- return Some(RegenerationReason::Expired(expiration));
- }
- }
-
- None
-}
crates/fleet-shared/Cargo.tomldiffbeforeafterboth--- a/crates/fleet-shared/Cargo.toml
+++ b/crates/fleet-shared/Cargo.toml
@@ -8,4 +8,3 @@
base64 = "0.22.1"
serde = "1.0.219"
unicode_categories = "0.1.1"
-z85 = "3.0.6"
crates/fleet-shared/src/encoding.rsdiffbeforeafterboth--- a/crates/fleet-shared/src/encoding.rs
+++ b/crates/fleet-shared/src/encoding.rs
@@ -1,5 +1,4 @@
use std::{
- collections::BTreeMap,
fmt::{self, Display},
str::FromStr,
};
@@ -15,7 +14,6 @@
}
const BASE64_ENCODED_PREFIX: &str = "<BASE64-ENCODED>\n";
-const Z85_ENCODED_PREFIX: &str = "<Z85-ENCODED>\n";
// Multiline text in Nix can only end with \n, which is not cool for actual single-line strings.
const PLAINTEXT_NEWLINE_PREFIX: &str = "<PLAINTEXT-NL>\n";
const PLAINTEXT_PREFIX: &str = "<PLAINTEXT>";
@@ -54,18 +52,12 @@
STANDARD_NO_PAD
.decode(unprefixed.replace(['\n', '\t', ' '], ""))
.map_err(|e| format!("base64-encoded failed: {e}"))?
- } else if let Some(unprefixed) = string.strip_prefix(Z85_ENCODED_PREFIX) {
- z85::decode(unprefixed.replace(['\n', '\t', ' '], ""))
- .map_err(|e| format!("z85-encoded failed: {e}"))?
} else if let Some(unprefixed) = string.strip_prefix(PLAINTEXT_NEWLINE_PREFIX) {
unprefixed.as_bytes().to_owned()
} else if let Some(unprefixed) = string.strip_prefix(PLAINTEXT_PREFIX) {
unprefixed.as_bytes().to_owned()
} else {
- let secret_prefix = format!("{SECRET_PREFIX}{Z85_ENCODED_PREFIX}");
- return Err(format!(
- "unknown secret encoding. If you're migrating from old version of fleet, prefix public secret fields with {PLAINTEXT_PREFIX:?}, and encrypted data with {secret_prefix:?}: {string}"
- ));
+ return Err(format!("unknown secret encoding"));
};
Ok(Self { data, encrypted })
}
crates/nix-eval/Cargo.tomldiffbeforeafterboth--- a/crates/nix-eval/Cargo.toml
+++ b/crates/nix-eval/Cargo.toml
@@ -18,6 +18,7 @@
test-log = { version = "0.2.18", features = ["trace"] }
tracing-indicatif = { version = "0.3.13", optional = true }
vte = { version = "0.15.0", features = ["ansi"] }
+tokio.workspace = true
[build-dependencies]
bindgen = "0.72.0"
crates/nix-eval/src/lib.rsdiffbeforeafterboth--- a/crates/nix-eval/src/lib.rs
+++ b/crates/nix-eval/src/lib.rs
@@ -2,7 +2,7 @@
use std::cell::RefCell;
use std::ffi::{CStr, CString, c_char, c_int, c_uint, c_void};
use std::ptr::{null, null_mut};
-use std::sync::LazyLock;
+use std::sync::{Arc, LazyLock, OnceLock};
use std::{array, fmt, slice};
use std::{collections::HashMap, path::PathBuf};
@@ -10,9 +10,10 @@
use itertools::Itertools;
use serde::Serialize;
use serde::de::DeserializeOwned;
+use std::mem::transmute;
pub use anyhow::Result;
-use tracing::{info, instrument, warn};
+use tracing::{Instrument, info, instrument, warn};
use self::logging::{ErrorInfoBuilder, nix_logging_cxx};
use self::nix_cxx::set_fetcher_setting;
@@ -172,9 +173,16 @@
#[repr(transparent)]
pub struct NixContext(*mut c_context);
impl NixContext {
- pub fn set_err(&mut self, err: NixErrorKind, msg: &CStr) {
+ pub fn set_err_raw(&mut self, err: NixErrorKind, msg: &CStr) {
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");
+ self.set_err_raw(
+ NixErrorKind::Generic,
+ &CString::new(fmt).expect("NUL bytes were just replaced"),
+ );
+ }
pub fn new() -> Self {
let ctx = unsafe { c_context_create() };
Self(ctx)
@@ -931,6 +939,8 @@
}
}
+static TOKIO_FOR_NIX: OnceLock<Arc<tokio::runtime::Runtime>> = OnceLock::new();
+
pub fn init_libraries() {
unsafe { GC_allow_register_threads() };
@@ -945,37 +955,33 @@
nix_logging_cxx::apply_tracing_logger();
}
+pub fn init_tokio_for_nix(tokio: Arc<tokio::runtime::Runtime>) {
+ TOKIO_FOR_NIX
+ .set(tokio)
+ .expect("tokio for nix should only be initialized once");
+}
+
+pub fn await_in_nix<F: Send + 'static>(f: impl Future<Output = F> + Send + 'static) -> F {
+ // It should be possible to do Handle::current(), but some of the planned features don't work well with that
+ let runtime = TOKIO_FOR_NIX
+ .get()
+ .expect("init_tokio_for_nix was not called");
+ std::thread::spawn(move || runtime.block_on(f)).join().expect("await_in_nix inner thread panicked")
+}
+
unsafe extern "C" fn nix_primop_closure_adapter<const N: usize>(
user_data: *mut c_void,
- context: *mut c_context,
+ mut context: *mut c_context,
state: *mut nix_raw::EvalState,
args: *mut *mut value,
ret: *mut value,
) {
let user_closure: &UserClosure<N> = unsafe { &*user_data.cast_const().cast() };
- let mut e = None;
let args: [&Value; N] = array::from_fn(|i| {
let v: &mut Value = unsafe { &mut *args.add(i).cast() };
-
- info!("forcing arg");
- if matches!(v.type_of(), NixType::Thunk)
- && let Err(err) = v.force(state)
- {
- e = Some(err);
- };
v as &Value
});
- info!("args forced");
- let ctx: &mut NixContext = unsafe { &mut *context.cast() };
-
- if let Some(e) = e {
- warn!("set err = {e}");
- unsafe { init_int(context, ret, 0) };
- return ctx.set_err(
- NixErrorKind::Unknown,
- &CString::new(e.to_string()).expect("forcing argument value failed"),
- );
- }
+ let ctx: &mut NixContext = unsafe { transmute(&mut context) };
let state: &EvalState = unsafe { std::mem::transmute(&state) };
@@ -984,12 +990,7 @@
unsafe { copy_value(context, ret, v.0) };
}
Err(e) => {
- unsafe { init_int(context, ret, 0) };
- warn!("set err = {e:#?}");
- ctx.set_err(
- NixErrorKind::Unknown,
- &CString::new(e.to_string()).expect("error should not contain internal nuls"),
- );
+ ctx.set_err(e);
}
}
}
crates/nix-eval/src/macros.rsdiffbeforeafterboth--- a/crates/nix-eval/src/macros.rs
+++ b/crates/nix-eval/src/macros.rs
@@ -68,13 +68,13 @@
#[macro_export]
macro_rules! nix_go {
(@o($o:expr, $path:expr) . $var:ident $($tt:tt)*) => {{
- nix_go!(@o($o.get_field(stringify!($var)).context(concat!("getting nested ", $path))?, $path) $($tt)*)
+ nix_go!(@o(tokio::task::block_in_place(|| $o.get_field(stringify!($var))).context(concat!("getting nested ", $path))?, $path) $($tt)*)
}};
(@o($o:expr, $path:expr) [ $v:expr ] $($tt:tt)*) => {{
- nix_go!(@o($o.get_field($v).context(concat!("getting nested ", $path))?, $path) $($tt)*)
+ nix_go!(@o(tokio::task::block_in_place(|| $o.get_field($v)).context(concat!("getting nested ", $path))?, $path) $($tt)*)
}};
(@o($o:expr, $path:expr) ($($var:tt)*) $($tt:tt)*) => {
- nix_go!(@o($o.call($crate::nix_expr_inner!($($var)+)).context(concat!("getting nested ", $path))?, $path) $($tt)*)
+ nix_go!(@o(tokio::task::block_in_place(|| $o.call($crate::nix_expr_inner!($($var)+))).context(concat!("getting nested ", $path))?, $path) $($tt)*)
};
(@o($o:expr, $path:expr)) => {$o};
($field:ident $($tt:tt)+) => {{
@@ -87,6 +87,6 @@
#[macro_export]
macro_rules! nix_go_json {
($($tt:tt)*) => {{
- $crate::nix_go!($($tt)*).as_json()?
+ tokio::task::block_in_place(|| $crate::nix_go!($($tt)*).as_json())?
}};
}
flake.lockdiffbeforeafterboth--- a/flake.lock
+++ b/flake.lock
@@ -2,10 +2,10 @@
"nodes": {
"crane": {
"locked": {
- "lastModified": 1767461147,
+ "lastModified": 1768700043,
"owner": "ipetkov",
"repo": "crane",
- "rev": "7d59256814085fd9666a2ae3e774dc5ee216b630",
+ "rev": "935de8bd6838d940988bb065be2a2034259327b9",
"type": "github"
},
"original": {
@@ -37,10 +37,10 @@
]
},
"locked": {
- "lastModified": 1767609335,
+ "lastModified": 1768135262,
"owner": "hercules-ci",
"repo": "flake-parts",
- "rev": "250481aafeb741edfe23d29195671c19b36b6dca",
+ "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac",
"type": "github"
},
"original": {
@@ -111,10 +111,10 @@
"nixpkgs-regression": "nixpkgs-regression"
},
"locked": {
- "lastModified": 1767670640,
+ "lastModified": 1768702010,
"owner": "deltarocks",
"repo": "nix",
- "rev": "2181cd07134c9049bd77b7f48c3b1ea8647267de",
+ "rev": "b05b52670b9c7affff5b9be3edb539a1603c39e6",
"type": "github"
},
"original": {
@@ -126,10 +126,10 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1767657734,
+ "lastModified": 1768697925,
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "d4ccebf51ee4dbeb9df364dce1fe9848635c1258",
+ "rev": "665062f7df2c7db8fdbbec4f1b730091143828a3",
"type": "github"
},
"original": {
@@ -190,10 +190,10 @@
]
},
"locked": {
- "lastModified": 1767667566,
+ "lastModified": 1768617670,
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "056ce5b125ab32ffe78c7d3e394d9da44733c95e",
+ "rev": "56d0fbdd732f3686e8414b857cf885038fc17d57",
"type": "github"
},
"original": {
@@ -223,10 +223,10 @@
]
},
"locked": {
- "lastModified": 1767468822,
+ "lastModified": 1768158989,
"owner": "numtide",
"repo": "treefmt-nix",
- "rev": "d56486eb9493ad9c4777c65932618e9c2d0468fc",
+ "rev": "e96d59dff5c0d7fddb9d113ba108f03c3ef99eca",
"type": "github"
},
"original": {
modules/nixos.nixdiffbeforeafterboth--- a/modules/nixos.nix
+++ b/modules/nixos.nix
@@ -10,7 +10,7 @@
let
inherit (lib.attrsets) mapAttrs;
inherit (lib.options) mkOption;
- inherit (lib.types) deferredModule unspecified;
+ inherit (lib.types) deferredModule unspecified uniq str;
inherit (lib.strings) escapeNixIdentifier;
inherit (fleetLib.options) mkHostsOption;
@@ -24,9 +24,18 @@
'';
type = deferredModule;
};
- hosts = mkHostsOption (hostArgs: {
+ hosts = mkHostsOption (hostArgs: let
+ hostName = hostArgs.config._module.args.name;
+ in {
inherit _file;
options = {
+ name = mkOption {
+ description = ''
+ Host name (alias)
+ '';
+ type = uniq str;
+ default = hostName;
+ };
nixos = mkOption {
description = ''
Nixos configuration for the current host.
@@ -42,7 +51,7 @@
prefix = [
"fleetConfiguration"
"hosts"
- hostArgs.config._module.args.name
+ hostName
"nixos"
];
modules = (import "${modulesPath}/module-list.nix") ++ [
modules/nixos/secrets.nixdiffbeforeafterboth--- a/modules/nixos/secrets.nix
+++ b/modules/nixos/secrets.nix
@@ -15,7 +15,12 @@
inherit (lib.stringsWithDeps) stringAfter;
inherit (lib.options) mkOption literalExpression;
inherit (lib.lists) optional elem;
- inherit (lib.attrsets) mapAttrs mapAttrsToList;
+ inherit (lib.attrsets)
+ mapAttrs
+ mapAttrsToList
+ filterAttrs
+ attrNames
+ ;
inherit (lib.modules) mkIf;
inherit (lib.types)
submodule
@@ -25,9 +30,9 @@
uniq
functionTo
package
- bool
enum
either
+ listOf
;
inherit (fleetLib.strings) decodeRawSecret;
@@ -132,10 +137,33 @@
in
{
options = {
+ _providedSharedSecrets = mkOption {
+ description = ''
+ List of shared secrets, for which the current host was specified as `expectedOwners`
+ '';
+ type = listOf str;
+ default = [];
+ internal = true;
+ };
secrets = mkOption {
type = attrsOf secretType;
default = { };
- apply = mapAttrs (_: secret: secret.parts // { definition = secret; });
+ apply =
+ secrets:
+ mapAttrs (_: secret: secret.parts // { definition = secret; })
+
+ (
+ let
+ hostName = host.name;
+ expectedNonshared = attrNames (filterAttrs (_: def: def.generator != "shared") secrets);
+ expectedShared = config._providedSharedSecrets;
+ in
+ builtins.deepSeq [
+ hostName
+ expectedNonshared
+ expectedShared
+ ] (builtins.fleetEnsureHostSecrets hostName expectedNonshared expectedShared secrets)
+ );
description = "Host-local secrets";
};
system.secretsData = mkOption {
@@ -163,7 +191,7 @@
(secret.definition.generator == "shared") == hasSharedDefinition
&& (
hasSharedDefinition
- -> (elem host._module.args.name fleetConfiguration.secrets.${name}.expectedOwners)
+ -> (elem host.name fleetConfiguration.secrets.${name}.expectedOwners)
);
message =
if hasSharedDefinition then
modules/secrets.nixdiffbeforeafterboth--- a/modules/secrets.nix
+++ b/modules/secrets.nix
@@ -1,9 +1,10 @@
{
lib,
+ config,
...
}:
let
- inherit (lib.options) mkOption literalExpression;
+ inherit (lib.options) mkOption;
inherit (lib.types)
nullOr
listOf
@@ -16,6 +17,8 @@
uniq
;
inherit (lib.strings) concatStringsSep;
+ inherit (lib.lists) elem filter;
+ inherit (lib.attrsets) attrNames;
sharedSecret =
{ config, ... }:
@@ -30,28 +33,33 @@
regenerateOnOwnerAdded = mkOption {
type = bool;
description = ''
- Controls whether the secret must be regenerated when new owners are added.
+ Whether the secret prefers to be rotated when new owners are added.
- Set to true when the secret contains owner-specific references (e.g., X.509 Subject Alternative Names).
- When true, adding a new owner will trigger secret regeneration instead of simple re-encryption.
+ Note that this is only a security measure, if the secret needs to be regenerated due to e.g X.509 SANs
+ changes - then you most likely want to use generationData for that instead.
'';
+ default = false;
};
regenerateOnOwnerRemoved = mkOption {
- default = config.regenerateOnOwnerAdded;
- defaultText = literalExpression "regenerateOnOwnerAdded";
type = bool;
description = ''
- Determines secret behavior when owners are removed from the configuration.
-
- Typically mirrors regenerateOnOwnerAdded. Override cautiously.
- Set to false if host permissions are revoked through alternative mechanisms like firewall rules.
+ Whether the secret prefers to be rotated when the owners are removed, so the encrypted data
+ stored in fleet state can't be decrypted by those. Note that the secrets are still present in encrypted
+ form on those hosts until gc happens.
'';
+ default = false;
};
allowDifferent = mkOption {
type = bool;
description = ''
- When adding owner, do not update secret value for other owners, instead creating a new distribution
+ When adding owner, do not update secret value for other owners, instead creating a new distribution.
+
+ Defaults to true, since all secrets might differ on hosts on some point of deployment process.
+
+ Secret generator might also have opinion on this, like it makes little sense for askPass/synchronizing
+ generators to keep old data.
'';
+ default = true;
};
generator = mkOption {
type = uniq (nullOr (functionTo package));
@@ -75,6 +83,9 @@
};
};
config = {
+ nixos = {host, ...}: {
+ _providedSharedSecrets = filter (name: elem host.name config.secrets.${name}.expectedOwners) (attrNames config.secrets);
+ };
nixpkgs.overlays = [
(final: prev: {
mkSecretGenerators =
@@ -90,6 +101,7 @@
# (Some secrets-encryption-in-git/managed PKI solution is expected)
impureOn ? null,
generationData ? null,
+ allowDifferent ? true,
parts,
}:
(prev.writeShellScript "impureGenerator.sh" ''
@@ -118,7 +130,12 @@
'').overrideAttrs
(old: {
passthru = {
- inherit impureOn parts generationData;
+ inherit
+ impureOn
+ parts
+ generationData
+ allowDifferent
+ ;
generatorKind = "impure";
};
});