difftreelog
refactor prepare for decoupling fleet-cli from fleet-data-storage
in: trunk
26 files changed
Cargo.lockdiffbeforeafterboth322 packageslockfile v3
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.22.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678depends onused byadler
1.0.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35feused 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.10.0crates.io↘ 27↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumedeef7d7b199195a2d7d7a8155d2d04aee736e60c5c7bdd7097d115369a8817ddepends on- aes
0.8.4 - aes-gcm
0.10.3 - age-core
0.10.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.2 - hmac
0.12.1 - i18n-embed
0.14.1 - i18n-embed-fl
0.7.0 - lazy_static
1.4.0 - nom
7.1.3 - num-traits
0.2.19 - pin-project
1.1.5 - rand
0.8.5 - rsa
0.9.6 - rust-embed
8.4.0 - scrypt
0.11.0 - sha2
0.10.8 - subtle
2.5.0 - x25519-dalek
2.0.1 - zeroize
1.8.1
- aes
age-core
0.10.0crates.io↘ 9↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma5f11899bc2bbddd135edbc30c36b1924fa59d0746bb45beb5933fafe3fe509bdepends onused byaho-corasick
1.1.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916depends onalejandra
3.0.0github.com/kamadorueda/alejandra↘ 3↖ 1sourcegit+https://github.com/kamadorueda/alejandra#bb688cc2c22e43b3cd710eadc0340399c2de3151depends onused byandroid_system_properties
0.1.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311depends onused byandroid-tzdata
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0used byanstream
0.6.14crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15bdepends onused byanstyle
1.0.7crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1banstyle-parse
0.2.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4depends onused byanstyle-query
1.0.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5depends onused byanstyle-wincon
3.0.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19depends onused byanyhow
1.0.86crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063daarc-swap
1.7.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457used byasync-trait
0.1.80crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737cadepends onused byautocfg
1.3.0crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0backtrace
0.3.72crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11depends onused bybase64
0.21.7crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567base64
0.22.1crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6bcrypt-pbkdf
0.10.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2depends onused bybetter-command
0.1.0workspace↘ 5↖ 2bitflags
2.5.0crates.io↘ 1↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1depends 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.16.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012cused bybytecount
0.6.8crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ceused bybyteorder
1.5.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64bbytes
1.6.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9used bycbc
0.1.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6depends onused bycbitset
0.2.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29b6ad25ae296159fb0da12b970b2fe179b234584d7cd294c891e2bbb284466bdepends onused bycc
1.0.98crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03fcfg_aliases
0.2.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724used bycfg-if
1.0.0crates.io↘ 0↖ 15sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbaf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fdchacha20
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.38crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401depends onused bycipher
0.4.4crates.io↘ 3↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3daddepends onclap
4.5.4crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0depends onclap_builder
4.5.2crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4depends onused byclap_complete
4.5.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275edepends onused byclap_derive
4.5.4crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64used byclap_lex
0.7.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ceused bycolorchoice
1.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422used byconsole
0.15.8crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4ebused byconst-oid
0.9.6crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8used bycookie-factory
0.3.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2depends onused bycore-foundation-sys
0.8.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868fused bycountme
2.0.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum328b822bdcba4d4e402be8d9adb6eebf269f969f8eadef977a553ff3c4fbcb58used bycpufeatures
0.2.12crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504depends oncrossterm
0.27.0crates.io↘ 9↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824dfdepends onused bycrossterm_winapi
0.9.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumacdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2bdepends 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 bycurve25519-dalek
4.1.2crates.io↘ 9↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348depends oncurve25519-dalek-derive
0.1.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3depends onused bydashmap
5.5.3crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856used byder
0.7.9crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0depends onderanged
0.3.11crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4depends onused bydigest
0.10.7crates.io↘ 4↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292displaydoc
0.2.4crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175ddepends onused byed25519
2.2.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53depends onused byed25519-dalek
2.1.1crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871depends onused byeither
1.12.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58bused byencode_unicode
0.3.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831fused byequivalent
1.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5used byerrno
0.3.9crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820badepends onused byfastrand
2.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51aused byfiat-crypto
0.2.9crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811dused byfiledescriptor
0.8.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46edepends onused byfind-crate
0.6.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2depends onfleet
0.2.0workspace↘ 35↖ 0depends on- abort-on-drop
0.2.2 - age
0.10.0 - age-core
0.10.0 - anyhow
1.0.86 - async-trait
0.1.80 - base64
0.22.1 - better-command
0.1.0 - chrono
0.4.38 - clap
4.5.4 - clap_complete
4.5.2 - crossterm
0.27.0 - fleet-shared
0.1.0 - futures
0.3.30 - hostname
0.4.0 - human-repr
1.1.0 - indicatif
0.17.8 - itertools
0.13.0 - nix-eval
0.1.0 - nixlike
0.1.0 - nom
7.1.3 - openssh
0.10.4 - owo-colors
4.0.0 - peg
0.8.3 - regex
1.10.6 - serde
1.0.203 - serde_json
1.0.117 - shlex
1.3.0 - tabled
0.15.0 - tempfile
3.10.1 - time
0.3.36 - tokio
1.38.0 - tokio-util
0.7.11 - tracing
0.1.40 - tracing-indicatif
0.3.6 - tracing-subscriber
0.3.18
- abort-on-drop
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↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1used byfutures
0.3.30crates.io↘ 7↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0depends onfutures-channel
0.3.30crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumeac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78depends onfutures-core
0.3.30crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1dfutures-executor
0.3.30crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01dused byfutures-io
0.3.30crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1futures-macro
0.3.30crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489acdepends onused byfutures-sink
0.3.30crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5futures-task
0.3.30crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004futures-util
0.3.30crates.io↘ 10↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48depends ongeneric-array
0.14.7crates.io↘ 2↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9adepends ongetrandom
0.2.15crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7used byghash
0.5.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1depends onused bygimli
0.29.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffdused byhashbrown
0.9.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04used byhashbrown
0.14.5crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1used byheck
0.4.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8used byheck
0.5.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55eaused byhermit-abi
0.3.9crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024hex
0.4.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70used byhkdf
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 onhostname
0.4.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2badepends onused byhuman-repr
1.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf58b778a5761513caf593693f8951c97a5b610841e754788400f32102eefdff1used byi18n-config
0.4.6crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0c9ce3c48cbc21fd5b22b9331f32b5b51f6ad85d969b99e793427332e76e7640i18n-embed
0.14.1crates.io↘ 13↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum94205d95764f5bb9db9ea98fa77f89653365ca748e27161f5bbea2ffd50e459cdepends onused byi18n-embed-fl
0.7.0crates.io↘ 13↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9fc1f8715195dffc4caddcf1cf3128da15fe5d8a137606ea8856c9300047d5a2depends onused byi18n-embed-impl
0.8.3crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum81093c4701672f59416582fe3145676126fd23ba5db910acad0793c1108aaa58used byiana-time-zone
0.1.60crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141depends onused byiana-time-zone-haiku
0.1.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269fdepends onused byindexmap
2.2.6crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26depends onused byindicatif
0.17.8crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3depends oninout
0.1.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5depends onused byinstant
0.1.13crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222depends onused byintl_pluralrules
7.0.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972depends onused byintl-memoizer
0.5.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bdadepends onio_tee
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4b3f7cef34251886990511df1c61443aa928499d598a9473929ab5a90a527304used byis_ci
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45used byis_terminal_polyfill
1.70.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800used byis-terminal
0.4.12crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738bused byitertools
0.13.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186depends onused byitoa
1.0.11crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695bused byjs-sys
0.3.69crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296ddepends onlazy_static
1.4.0crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646depends onlibc
0.2.155crates.io↘ 0↖ 24sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847cused by- android_system_properties
0.1.5 - backtrace
0.3.72 - console
0.15.8 - cpufeatures
0.2.12 - crossterm
0.27.0 - errno
0.3.9 - filedescriptor
0.8.2 - getrandom
0.2.15 - hostname
0.4.0 - is-terminal
0.4.12 - libmimalloc-sys
0.1.38 - mio
0.8.11 - nix
0.29.0 - num_cpus
1.16.0 - openssh
0.10.4 - parking_lot_core
0.9.10 - rand
0.8.5 - rustix
0.38.34 - signal-hook
0.3.17 - signal-hook-mio
0.2.3 - signal-hook-registry
1.4.2 - socket2
0.5.7 - tokio
1.38.0 - tokio-pipe
0.2.12
- android_system_properties
libm
0.2.8crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058libmimalloc-sys
0.1.38crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0e7bb23d733dfcc8af652a78b7bf232f0e967710d044732185e561e47c0336b6depends onused bylinked-hash-map
0.5.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770fused bylinux-raw-sys
0.4.14crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89used bylock_api
0.4.12crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17depends onlog
0.4.21crates.io↘ 0↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901cmatchers
0.1.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558depends onused bymemchr
2.7.2crates.io↘ 0↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1dmemoffset
0.6.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79cedepends onused bymimalloc
0.1.42crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume9186d86b79b52f4a77af65604b51225e8db1d6ee7e3f41aec1e40829c71a176depends onused byminimal-lexical
0.2.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79aused byminiz_oxide
0.7.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdaedepends onused bymio
0.8.11crates.io↘ 4↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0cnix
0.29.0crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46used bynixlike
0.1.0workspace↘ 8↖ 2nom
7.1.3crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4adepends onnu-ansi-term
0.46.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84depends onused bynum_cpus
1.16.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43depends 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 onnumber_prefix
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3used byobject
0.35.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5edepends onused byonce_cell
1.19.0crates.io↘ 0↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92opaque-debug
0.3.1crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381openssh
0.10.4crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum432f4a7e4d194272876710557e6b712fc304e7b4711e2063655df1e446b4b8e3depends onused byoverload
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39used byowo-colors
4.0.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcaff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3fdepends onused bypapergrid
0.11.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9ad43c07024ef767f9160710b3a6773976194758c7919b17e63b863db0bdf7fbused byparking_lot
0.12.3crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27depends onparking_lot_core
0.9.10crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8pbkdf2
0.12.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2depends onpeg
0.8.3crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8a625d12ad770914cbf7eff6f9314c3ef803bfe364a1b20bc36ddf56673e71e5depends onused bypeg-macros
0.8.3crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf241d42067ed3ab6a4fece1db720838e1418f36d868585a27931f95d6bc03582used bypeg-runtime
0.8.3crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3aused bypin-project
1.1.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3depends onused bypin-project-internal
1.1.5crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965depends onused bypin-project-lite
0.2.14crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02pin-utils
0.1.0crates.io↘ 0↖ 1sourceregistry+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-indexchecksumf950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7platforms
3.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdb23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7used 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.6.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0used bypowerfmt
0.2.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391used byppv-lite86
0.2.17crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6deused byproc-macro-error
1.0.4crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumda25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38cproc-macro-error-attr
1.0.4crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869used byproc-macro2
1.0.84crates.io↘ 1↖ 24sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6depends onused by- async-trait
0.1.80 - clap_derive
4.5.4 - curve25519-dalek-derive
0.1.1 - displaydoc
0.2.4 - futures-macro
0.3.30 - i18n-embed-fl
0.7.0 - i18n-embed-impl
0.8.3 - peg-macros
0.8.3 - pin-project-internal
1.1.5 - proc-macro-error
1.0.4 - proc-macro-error-attr
1.0.4 - quote
1.0.36 - rust-embed-impl
8.4.0 - serde_derive
1.0.203 - syn
1.0.109 - syn
2.0.66 - tabled_derive
0.7.0 - thiserror-impl
1.0.61 - tokio-macros
2.3.0 - tracing-attributes
0.1.27 - vte_generate_state_changes
0.1.1 - wasm-bindgen-backend
0.2.92 - wasm-bindgen-macro-support
0.2.92 - zeroize_derive
1.4.2
- async-trait
quote
1.0.36crates.io↘ 1↖ 24sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7depends onused by- async-trait
0.1.80 - clap_derive
4.5.4 - curve25519-dalek-derive
0.1.1 - displaydoc
0.2.4 - futures-macro
0.3.30 - i18n-embed-fl
0.7.0 - i18n-embed-impl
0.8.3 - peg-macros
0.8.3 - pin-project-internal
1.1.5 - proc-macro-error
1.0.4 - proc-macro-error-attr
1.0.4 - rust-embed-impl
8.4.0 - serde_derive
1.0.203 - syn
1.0.109 - syn
2.0.66 - tabled_derive
0.7.0 - thiserror-impl
1.0.61 - tokio-macros
2.3.0 - tracing-attributes
0.1.27 - vte_generate_state_changes
0.1.1 - wasm-bindgen-backend
0.2.92 - wasm-bindgen-macro
0.2.92 - wasm-bindgen-macro-support
0.2.92 - zeroize_derive
1.4.2
- async-trait
r2d2
0.8.10crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93used byrand
0.8.5crates.io↘ 3↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404rand_chacha
0.3.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88depends onused byrand_core
0.6.4crates.io↘ 1↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922cdepends onredox_syscall
0.5.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7edepends onused byregex
1.10.6crates.io↘ 4↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619regex-automata
0.1.10crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132depends onused byregex-automata
0.4.6crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaeaused byregex-syntax
0.6.29crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1used byregex-syntax
0.8.3crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumadad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56remowt-fs
0.1.0workspace↘ 0↖ 0rnix
0.10.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8024a523e8836f1a5d051203dc00d833357fee94e351b51348dfaeca5364daa9depends onused byron
0.8.1crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94used byrowan
0.12.6crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma1b36e449f3702f3b0c821411db1cbdf30fb451726a9456dce5dabcd44420043used byrsa
0.9.6crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfcdepends onused byrust-embed
8.4.0crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806aused byrust-embed-impl
8.4.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4used byrust-embed-utils
8.4.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32depends onrustc_version
0.4.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366depends onused byrustc-demangle
0.1.24crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1fused byrustc-hash
1.1.0crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2rustix
0.38.34crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730fryu
1.0.18crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9fused bysalsa20
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 byscheduled-thread-pool
0.2.7crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19depends onused byscopeguard
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49used byscrypt
0.11.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1fdepends onused bysecrecy
0.8.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91edepends onused byself_cell
0.10.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915ddepends onused byself_cell
1.0.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714aused bysemver
1.0.23crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988bused byserde
1.0.203crates.io↘ 1↖ 23sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094depends onused by- better-command
0.1.0 - bitflags
2.5.0 - chrono
0.4.38 - deranged
0.3.11 - ed25519-dalek
2.1.1 - fleet
0.2.0 - fleet-install-secrets
0.1.0 - fleet-shared
0.1.0 - i18n-config
0.4.6 - nix-eval
0.1.0 - nixlike
0.1.0 - ron
0.8.1 - serde-transcode
1.1.1 - serde_json
1.0.117 - serde_spanned
0.6.6 - smol_str
0.1.24 - time
0.3.36 - toml
0.5.11 - toml
0.8.13 - toml_datetime
0.6.6 - toml_edit
0.22.13 - unic-langid-impl
0.9.5 - x25519-dalek
2.0.1
- better-command
serde_derive
1.0.203crates.io↘ 3↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5badepends onserde_json
1.0.117crates.io↘ 3↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3depends onserde_spanned
0.6.6crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0depends onused byserde-transcode
1.1.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2depends onused bysha2
0.10.8crates.io↘ 3↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8depends 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↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64used bysignal-hook
0.3.17crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801depends onsignal-hook-mio
0.2.3crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99afdepends onused bysignal-hook-registry
1.4.2crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1depends onused bysignature
2.2.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329dedepends onused byslab
0.4.9crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67depends onused bysmallvec
1.13.2crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67smol_str
0.1.24crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9depends onused bysocket2
0.5.7crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191cdepends onused byspin
0.5.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042dused byspki
0.7.3crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29ddepends onstrsim
0.10.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623used bystrsim
0.11.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4fused bysubtle
2.5.0crates.io↘ 0↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebcsupports-color
2.1.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89depends onused bysyn
1.0.109crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237syn
2.0.66crates.io↘ 3↖ 16sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5used by- async-trait
0.1.80 - clap_derive
4.5.4 - curve25519-dalek-derive
0.1.1 - displaydoc
0.2.4 - futures-macro
0.3.30 - i18n-embed-fl
0.7.0 - i18n-embed-impl
0.8.3 - pin-project-internal
1.1.5 - rust-embed-impl
8.4.0 - serde_derive
1.0.203 - thiserror-impl
1.0.61 - tokio-macros
2.3.0 - tracing-attributes
0.1.27 - wasm-bindgen-backend
0.2.92 - wasm-bindgen-macro-support
0.2.92 - zeroize_derive
1.4.2
- async-trait
tabled
0.15.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4c998b0c8b921495196a48aabaf1901ff28be0760136e31604f7967b0792050eused bytabled_derive
0.7.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4c138f99377e5d653a371cdad263615634cfc8467685dfe8e73e2b8e98f44b17used bytempfile
3.10.1crates.io↘ 4↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1terminal_size
0.3.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7depends onused bytext-size
1.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233used bythiserror
1.0.61crates.io↘ 1↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709depends onthiserror-impl
1.0.61crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533depends onused bythread_local
1.1.8crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719cdepends onused bytime
0.3.36crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885used bytime-core
0.1.2crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3used bytime-macros
0.2.18crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccfdepends onused bytinystr
0.7.6crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82fdepends onused bytokio
1.38.0crates.io↘ 10↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4adepends ontokio-macros
2.3.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39adepends onused bytokio-pipe
0.2.12crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf213a84bffbd61b8fa0ba8a044b4bbe35d471d0b518867181e82bd5c15542784depends onused bytokio-util
0.7.11crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1used bytoml
0.5.11crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234depends onused bytoml
0.8.13crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bbaused bytoml_datetime
0.6.6crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbfdepends onused bytoml_edit
0.22.13crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96cused bytracing
0.1.40crates.io↘ 3↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364eftracing-attributes
0.1.27crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7depends onused bytracing-core
0.1.32crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54depends ontracing-indicatif
0.3.6crates.io↘ 4↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum069580424efe11d97c3fef4197fa98c004fa26672cc71ad8770d224e23b1951dtracing-log
0.2.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3used bytracing-subscriber
0.3.18crates.io↘ 10↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8bdepends ontype-map
0.5.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdeb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9fdepends onused bytypenum
1.17.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825unic-langid
0.9.5crates.io↘ 1↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44depends onunic-langid-impl
0.9.5crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5depends onused byunicase
2.7.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89depends onused byunicode_categories
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14eused byunicode-ident
1.0.12crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4bunicode-width
0.1.12crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6unindent
0.2.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ceused byuniversal-hash
0.5.1crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07eadepends onused byutf8parse
0.2.1crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370avaluable
0.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6dused byversion_check
0.9.4crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483fvt100
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_generate_state_changes
0.1.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ffdepends onused bywalkdir
2.5.0crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4bdepends onwasi
0.11.0+wasi-snapshot-preview1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423used bywasm-bindgen
0.2.92crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8depends onwasm-bindgen-backend
0.2.92crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747dadepends onwasm-bindgen-macro
0.2.92crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726used bywasm-bindgen-macro-support
0.2.92crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7used bywinapi
0.3.9crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419winapi-i686-pc-windows-gnu
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6used bywinapi-util
0.1.8crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6bdepends onused bywinapi-x86_64-pc-windows-gnu
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183fused bywindows
0.52.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0bedepends onused bywindows_aarch64_gnullvm
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8used bywindows_aarch64_gnullvm
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263used bywindows_aarch64_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bcused bywindows_aarch64_msvc
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6used bywindows_i686_gnu
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743eused bywindows_i686_gnu
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670used bywindows_i686_gnullvm
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9used bywindows_i686_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406used bywindows_i686_msvc
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdb3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bfused bywindows_x86_64_gnu
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718eused bywindows_x86_64_gnu
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9used bywindows_x86_64_gnullvm
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044ccused bywindows_x86_64_gnullvm
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596used bywindows_x86_64_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538used bywindows_x86_64_msvc
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0used bywindows-core
0.52.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9depends onwindows-sys
0.48.0crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9depends onwindows-sys
0.52.0crates.io↘ 1↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33ddepends onwindows-targets
0.48.5crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940cdepends onused bywindows-targets
0.52.5crates.io↘ 8↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7ebdepends onwinnow
0.6.9crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6depends onused byx25519-dalek
2.0.1crates.io↘ 4↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277z85
3.0.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2a599daf1b507819c1121f0bf87fa37eb19daac6aff3aefefd4e6e2e0f2020fcused byzeroize
1.8.1crates.io↘ 1↖ 10sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4ddedepends onzeroize_derive
1.4.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69depends onused by
380 packageslockfile v3
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.22.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678depends onused byadler
1.0.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35feused 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.10.0crates.io↘ 27↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumedeef7d7b199195a2d7d7a8155d2d04aee736e60c5c7bdd7097d115369a8817ddepends on- aes
0.8.4 - aes-gcm
0.10.3 - age-core
0.10.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.2 - hmac
0.12.1 - i18n-embed
0.14.1 - i18n-embed-fl
0.7.0 - lazy_static
1.4.0 - nom
7.1.3 - num-traits
0.2.19 - pin-project
1.1.5 - rand
0.8.5 - rsa
0.9.6 - rust-embed
8.4.0 - scrypt
0.11.0 - sha2
0.10.8 - subtle
2.5.0 - x25519-dalek
2.0.1 - zeroize
1.8.1
- aes
age-core
0.10.0crates.io↘ 9↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma5f11899bc2bbddd135edbc30c36b1924fa59d0746bb45beb5933fafe3fe509bdepends onused byaho-corasick
1.1.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916depends onalejandra
3.0.0github.com/kamadorueda/alejandra↘ 3↖ 1sourcegit+https://github.com/kamadorueda/alejandra#bb688cc2c22e43b3cd710eadc0340399c2de3151depends onused byandroid_system_properties
0.1.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311depends onused byandroid-tzdata
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0used byanstream
0.6.14crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15bdepends onused byanstyle
1.0.7crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1banstyle-parse
0.2.4crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4depends onused byanstyle-query
1.0.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5depends onused byanstyle-wincon
3.0.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19depends onused byanyhow
1.0.86crates.io↘ 0↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063daarc-swap
1.7.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457used byasync-stream
0.3.5crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51used byasync-stream-impl
0.3.5crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193depends onused byasync-trait
0.1.81crates.io↘ 3↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107depends onatomic-waker
1.1.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0used byautocfg
1.3.0crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0axum
0.7.5crates.io↘ 19↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcfdepends onused byaxum-core
0.4.3crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3depends onused bybacktrace
0.3.72crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11depends onused bybase64
0.21.7crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567base64
0.22.1crates.io↘ 0↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6bcrypt-pbkdf
0.10.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2depends onused bybetter-command
0.1.0workspace↘ 5↖ 3bitflags
2.5.0crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1depends 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.16.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012cused bybytecount
0.6.8crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ceused bybyteorder
1.5.0crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64bbytes
1.6.0crates.io↘ 0↖ 14sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9cbc
0.1.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6depends onused bycbitset
0.2.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29b6ad25ae296159fb0da12b970b2fe179b234584d7cd294c891e2bbb284466bdepends onused bycc
1.0.98crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03fcfg_aliases
0.2.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724used bycfg-if
1.0.0crates.io↘ 0↖ 16sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbaf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fdchacha20
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.38crates.io↘ 7↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401depends onused bycipher
0.4.4crates.io↘ 3↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3daddepends onclap
4.5.4crates.io↘ 2↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0depends onclap_builder
4.5.2crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4depends onused byclap_complete
4.5.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275edepends onused byclap_derive
4.5.4crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64used byclap_lex
0.7.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ceused bycolorchoice
1.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422used byconsole
0.15.8crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4ebused byconst-oid
0.9.6crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8used bycookie-factory
0.3.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9885fa71e26b8ab7855e2ec7cae6e9b380edff76cd052e07c683a0319d51b3a2depends onused bycore-foundation-sys
0.8.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868fused bycountme
2.0.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum328b822bdcba4d4e402be8d9adb6eebf269f969f8eadef977a553ff3c4fbcb58used bycpufeatures
0.2.12crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504depends oncrossterm
0.27.0crates.io↘ 9↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824dfdepends onused bycrossterm_winapi
0.9.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumacdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2bdepends 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 bycurve25519-dalek
4.1.2crates.io↘ 9↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348depends oncurve25519-dalek-derive
0.1.1crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3depends onused bydashmap
5.5.3crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856used byder
0.7.9crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0depends onderanged
0.3.11crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4depends onused bydigest
0.10.7crates.io↘ 4↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292displaydoc
0.2.4crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175ddepends onused byed25519
2.2.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53depends onused byed25519-dalek
2.1.1crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871depends onused byeither
1.12.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58bused byencode_unicode
0.3.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831fused byequivalent
1.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5used byerrno
0.3.9crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820badepends onused byfastrand
2.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51aused byfiat-crypto
0.2.9crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811dused byfiledescriptor
0.8.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46edepends onused byfind-crate
0.6.3crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2depends onfixedbitset
0.4.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80used byfleet
0.2.0workspace↘ 36↖ 0depends on- abort-on-drop
0.2.2 - age
0.10.0 - age-core
0.10.0 - anyhow
1.0.86 - async-trait
0.1.81 - base64
0.22.1 - better-command
0.1.0 - chrono
0.4.38 - clap
4.5.4 - clap_complete
4.5.2 - crossterm
0.27.0 - fleet-base
0.1.0 - fleet-shared
0.1.0 - futures
0.3.30 - hostname
0.4.0 - human-repr
1.1.0 - indicatif
0.17.8 - itertools
0.13.0 - nix-eval
0.1.0 - nixlike
0.1.0 - nom
7.1.3 - openssh
0.10.4 - owo-colors
4.0.0 - peg
0.8.3 - regex
1.10.6 - serde
1.0.203 - serde_json
1.0.127 - shlex
1.3.0 - tabled
0.15.0 - tempfile
3.10.1 - time
0.3.36 - tokio
1.38.0 - tokio-util
0.7.11 - tracing
0.1.40 - tracing-indicatif
0.3.6 - tracing-subscriber
0.3.18
- abort-on-drop
fleet-base
0.1.0workspace↘ 19↖ 1fleet-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-indexchecksum3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1futures
0.3.30crates.io↘ 7↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0depends onfutures-channel
0.3.30crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumeac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78depends onfutures-core
0.3.30crates.io↘ 0↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1dfutures-executor
0.3.30crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01dused byfutures-io
0.3.30crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1futures-macro
0.3.30crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489acdepends onused byfutures-sink
0.3.30crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5futures-task
0.3.30crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004futures-util
0.3.30crates.io↘ 10↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48depends ongeneric-array
0.14.7crates.io↘ 2↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9adepends ongetrandom
0.2.15crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7used byghash
0.5.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1depends onused bygimli
0.29.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffdused byh2
0.4.6crates.io↘ 11↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205depends onused byhashbrown
0.9.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04used byhashbrown
0.12.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888used byhashbrown
0.14.5crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1used byheck
0.4.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8used byheck
0.5.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55eahermit-abi
0.3.9crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024hex
0.4.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70used byhkdf
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 onhostname
0.4.0crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2badepends onused byhttp
1.1.0crates.io↘ 3↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258depends onhttp-body
1.0.1crates.io↘ 2↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184depends onhttp-body-util
0.1.2crates.io↘ 5↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544fhttparse
1.9.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9used byhttpdate
1.0.3crates.io↘ 0↖ 1sourceregistry+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.4.1crates.io↘ 13↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05depends onhyper-timeout
0.5.1crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793used byhyper-util
0.1.7crates.io↘ 12↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9depends oni18n-config
0.4.6crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0c9ce3c48cbc21fd5b22b9331f32b5b51f6ad85d969b99e793427332e76e7640i18n-embed
0.14.1crates.io↘ 13↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum94205d95764f5bb9db9ea98fa77f89653365ca748e27161f5bbea2ffd50e459cdepends onused byi18n-embed-fl
0.7.0crates.io↘ 13↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9fc1f8715195dffc4caddcf1cf3128da15fe5d8a137606ea8856c9300047d5a2depends onused byi18n-embed-impl
0.8.3crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum81093c4701672f59416582fe3145676126fd23ba5db910acad0793c1108aaa58used byiana-time-zone
0.1.60crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141depends onused byiana-time-zone-haiku
0.1.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269fdepends onused byindexmap
1.9.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99depends onused byindexmap
2.2.6crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26depends onindicatif
0.17.8crates.io↘ 6↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3depends oninout
0.1.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5depends onused byinstant
0.1.13crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222depends onused byintl_pluralrules
7.0.2crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972depends onused byintl-memoizer
0.5.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bdadepends onio_tee
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4b3f7cef34251886990511df1c61443aa928499d598a9473929ab5a90a527304used byis_ci
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45used byis_terminal_polyfill
1.70.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800used byis-terminal
0.4.12crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738bused byitertools
0.13.0crates.io↘ 1↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186depends onitoa
1.0.11crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695bjs-sys
0.3.69crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296ddepends onlazy_static
1.4.0crates.io↘ 1↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646depends onlibc
0.2.155crates.io↘ 0↖ 26sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847cused by- android_system_properties
0.1.5 - backtrace
0.3.72 - console
0.15.8 - cpufeatures
0.2.12 - crossterm
0.27.0 - errno
0.3.9 - filedescriptor
0.8.2 - getrandom
0.2.15 - hostname
0.4.0 - is-terminal
0.4.12 - libmimalloc-sys
0.1.38 - mio
0.8.11 - nix
0.29.0 - num_cpus
1.16.0 - openssh
0.10.4 - openssh
0.11.0 - parking_lot_core
0.9.10 - rand
0.8.5 - ring
0.17.8 - rustix
0.38.34 - signal-hook
0.3.17 - signal-hook-mio
0.2.3 - signal-hook-registry
1.4.2 - socket2
0.5.7 - tokio
1.38.0 - tokio-pipe
0.2.12
- android_system_properties
libm
0.2.8crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058libmimalloc-sys
0.1.38crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0e7bb23d733dfcc8af652a78b7bf232f0e967710d044732185e561e47c0336b6depends onused bylinked-hash-map
0.5.6crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770fused bylinux-raw-sys
0.4.14crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89used bylock_api
0.4.12crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17depends onlog
0.4.21crates.io↘ 0↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901cmatchers
0.1.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558depends onused bymemchr
2.7.2crates.io↘ 0↖ 9sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1dmemoffset
0.6.5crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79cedepends onused bymimalloc
0.1.42crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume9186d86b79b52f4a77af65604b51225e8db1d6ee7e3f41aec1e40829c71a176depends onused bymime
0.3.17crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139aused byminimal-lexical
0.2.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79aused byminiz_oxide
0.7.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdaedepends onused bymio
0.8.11crates.io↘ 4↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0cmultimap
0.10.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdefc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03used bynix
0.29.0crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46used bynixlike
0.1.0workspace↘ 8↖ 3nom
7.1.3crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4adepends onnu-ansi-term
0.46.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84depends onused bynum_cpus
1.16.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43depends 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↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841depends onnumber_prefix
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3used byobject
0.35.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5edepends onused byonce_cell
1.19.0crates.io↘ 0↖ 10sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92opaque-debug
0.3.1crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381openssh
0.10.4crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum432f4a7e4d194272876710557e6b712fc304e7b4711e2063655df1e446b4b8e3depends onused byopenssh
0.11.0crates.io↘ 6↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0f27389e5da64700a3efb7f925e442f824f6e3d4b1c27f75e115a92ad3aecbb1used byoverload
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39used byowo-colors
4.0.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcaff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3fdepends onused bypapergrid
0.11.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9ad43c07024ef767f9160710b3a6773976194758c7919b17e63b863db0bdf7fbused byparking_lot
0.12.3crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27depends onparking_lot_core
0.9.10crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8pbkdf2
0.12.2crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2depends onpeg
0.8.3crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8a625d12ad770914cbf7eff6f9314c3ef803bfe364a1b20bc36ddf56673e71e5depends onused bypeg-macros
0.8.3crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf241d42067ed3ab6a4fece1db720838e1418f36d868585a27931f95d6bc03582used bypeg-runtime
0.8.3crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3aused bypem
3.0.4crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658faedepends onused bypercent-encoding
2.3.1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283eused bypetgraph
0.6.5crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47dbdepends onused bypin-project
1.1.5crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3depends onpin-project-internal
1.1.5crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965depends onused bypin-project-lite
0.2.14crates.io↘ 0↖ 14sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02pin-utils
0.1.0crates.io↘ 0↖ 1sourceregistry+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-indexchecksumf950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7platforms
3.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdb23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7used 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.6.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0used bypowerfmt
0.2.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391used byppv-lite86
0.2.17crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6deused byprettyplease
0.2.22crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5fabadepends onproc-macro-error
1.0.4crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumda25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38cproc-macro-error-attr
1.0.4crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869used byproc-macro2
1.0.84crates.io↘ 1↖ 28sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6depends onused by- async-stream-impl
0.3.5 - async-trait
0.1.81 - clap_derive
4.5.4 - curve25519-dalek-derive
0.1.1 - displaydoc
0.2.4 - futures-macro
0.3.30 - i18n-embed-fl
0.7.0 - i18n-embed-impl
0.8.3 - peg-macros
0.8.3 - pin-project-internal
1.1.5 - prettyplease
0.2.22 - proc-macro-error
1.0.4 - proc-macro-error-attr
1.0.4 - prost-derive
0.13.1 - quote
1.0.36 - rust-embed-impl
8.4.0 - serde_derive
1.0.203 - syn
1.0.109 - syn
2.0.76 - tabled_derive
0.7.0 - thiserror-impl
1.0.61 - tokio-macros
2.3.0 - tonic-build
0.12.2 - tracing-attributes
0.1.27 - vte_generate_state_changes
0.1.1 - wasm-bindgen-backend
0.2.92 - wasm-bindgen-macro-support
0.2.92 - zeroize_derive
1.4.2
- async-stream-impl
prost
0.13.1crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333ccdepends onprost-build
0.13.1crates.io↘ 13↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5bb182580f71dd070f88d01ce3de9f4da5021db7115d2e1c3605a754153b77c1depends onused byprost-derive
0.13.1crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfcaused byprost-types
0.13.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcee5168b05f49d4b0ca581206eb14a7b22fafd963efe729ac48eb03266e25cc2depends onused byquote
1.0.36crates.io↘ 1↖ 27sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7depends onused by- async-stream-impl
0.3.5 - async-trait
0.1.81 - clap_derive
4.5.4 - curve25519-dalek-derive
0.1.1 - displaydoc
0.2.4 - futures-macro
0.3.30 - i18n-embed-fl
0.7.0 - i18n-embed-impl
0.8.3 - peg-macros
0.8.3 - pin-project-internal
1.1.5 - proc-macro-error
1.0.4 - proc-macro-error-attr
1.0.4 - prost-derive
0.13.1 - rust-embed-impl
8.4.0 - serde_derive
1.0.203 - syn
1.0.109 - syn
2.0.76 - tabled_derive
0.7.0 - thiserror-impl
1.0.61 - tokio-macros
2.3.0 - tonic-build
0.12.2 - tracing-attributes
0.1.27 - vte_generate_state_changes
0.1.1 - wasm-bindgen-backend
0.2.92 - wasm-bindgen-macro
0.2.92 - wasm-bindgen-macro-support
0.2.92 - zeroize_derive
1.4.2
- async-stream-impl
r2d2
0.8.10crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93used byrand
0.8.5crates.io↘ 3↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404rand_chacha
0.3.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88depends onused byrand_core
0.6.4crates.io↘ 1↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922cdepends onrcgen
0.13.1crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum54077e1872c46788540de1ea3d7f4ccb1983d12f9aa909b234468676c1a36779used byredox_syscall
0.5.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7edepends onused byregex
1.10.6crates.io↘ 4↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619regex-automata
0.1.10crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132depends onused byregex-automata
0.4.6crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaeaused byregex-syntax
0.6.29crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1used byregex-syntax
0.8.3crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumadad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56ring
0.17.8crates.io↘ 7↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0drmp
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 byrnix
0.10.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8024a523e8836f1a5d051203dc00d833357fee94e351b51348dfaeca5364daa9depends onused byron
0.8.1crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94used byrowan
0.12.6crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma1b36e449f3702f3b0c821411db1cbdf30fb451726a9456dce5dabcd44420043used byrsa
0.9.6crates.io↘ 12↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfcdepends onused byrust-embed
8.4.0crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806aused byrust-embed-impl
8.4.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumcb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4used byrust-embed-utils
8.4.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32depends onrustc_version
0.4.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366depends onused byrustc-demangle
0.1.24crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1fused byrustc-hash
1.1.0crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2rustix
0.38.34crates.io↘ 5↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730frustls
0.23.12crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044depends onused byrustls-pemfile
2.1.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425depends onused byrustls-pki-types
1.8.0crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0rustls-webpki
0.102.7crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56used byrustversion
1.0.17crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6used byryu
1.0.18crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9fused bysalsa20
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 byscheduled-thread-pool
0.2.7crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19depends onused byscopeguard
1.2.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49used byscrypt
0.11.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1fdepends onused bysecrecy
0.8.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91edepends onused byself_cell
0.10.3crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915ddepends onused byself_cell
1.0.4crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714aused bysemver
1.0.23crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988bused byserde
1.0.203crates.io↘ 1↖ 32sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094depends onused by- axum
0.7.5 - better-command
0.1.0 - bitflags
2.5.0 - chrono
0.4.38 - deranged
0.3.11 - ed25519-dalek
2.1.1 - fleet
0.2.0 - fleet-base
0.1.0 - fleet-install-secrets
0.1.0 - fleet-shared
0.1.0 - i18n-config
0.4.6 - nix-eval
0.1.0 - nixlike
0.1.0 - pem
3.0.4 - rmp-serde
1.3.0 - ron
0.8.1 - serde-transcode
1.1.1 - serde_bytes
0.11.15 - serde_json
1.0.127 - serde_spanned
0.6.6 - smol_str
0.1.24 - terraform-provider-fleet
0.1.0 - tf-provider
0.2.2 - time
0.3.36 - toml
0.5.11 - toml
0.8.13 - toml_datetime
0.6.6 - toml_edit
0.22.13 - tracing-serde
0.1.3 - tracing-subscriber
0.3.18 - unic-langid-impl
0.9.5 - x25519-dalek
2.0.1
- axum
serde_bytes
0.11.15crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6adepends onused byserde_derive
1.0.203crates.io↘ 3↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5badepends onserde_json
1.0.127crates.io↘ 4↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329adserde_spanned
0.6.6crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0depends onused byserde-transcode
1.1.1crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2depends onused bysha2
0.10.8crates.io↘ 3↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8depends onsharded-slab
0.1.7crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6depends onused byshell-escape
0.1.5crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184fused byshlex
1.3.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64used bysignal-hook
0.3.17crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801depends onsignal-hook-mio
0.2.3crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99afdepends onused bysignal-hook-registry
1.4.2crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1depends onused bysignature
2.2.0crates.io↘ 2↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329dedepends onused byslab
0.4.9crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67depends onsmallvec
1.13.2crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67smol_str
0.1.24crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9depends onused bysocket2
0.5.7crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191cdepends onspin
0.5.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042dused 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 onstrsim
0.10.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623used bystrsim
0.11.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4fused bysubtle
2.5.0crates.io↘ 0↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebcsupports-color
2.1.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89depends onused bysyn
1.0.109crates.io↘ 3↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237syn
2.0.76crates.io↘ 3↖ 21sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525used by- async-stream-impl
0.3.5 - async-trait
0.1.81 - clap_derive
4.5.4 - curve25519-dalek-derive
0.1.1 - displaydoc
0.2.4 - futures-macro
0.3.30 - i18n-embed-fl
0.7.0 - i18n-embed-impl
0.8.3 - pin-project-internal
1.1.5 - prettyplease
0.2.22 - prost-build
0.13.1 - prost-derive
0.13.1 - rust-embed-impl
8.4.0 - serde_derive
1.0.203 - thiserror-impl
1.0.61 - tokio-macros
2.3.0 - tonic-build
0.12.2 - tracing-attributes
0.1.27 - wasm-bindgen-backend
0.2.92 - wasm-bindgen-macro-support
0.2.92 - zeroize_derive
1.4.2
- async-stream-impl
sync_wrapper
0.1.2crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160used bysync_wrapper
1.0.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394used bytabled
0.15.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4c998b0c8b921495196a48aabaf1901ff28be0760136e31604f7967b0792050eused bytabled_derive
0.7.0crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4c138f99377e5d653a371cdad263615634cfc8467685dfe8e73e2b8e98f44b17used bytempfile
3.10.1crates.io↘ 4↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1terminal_size
0.3.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7depends onused byterraform-provider-fleet
0.1.0workspace↘ 5↖ 0text-size
1.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233used bytf-provider
0.2.2crates.io↘ 20↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd80ea2e5f9f54717952d199888aab7e607dc99275ec5221f1259ce7a5f55f5a6depends onthiserror
1.0.61crates.io↘ 1↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709depends onthiserror-impl
1.0.61crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533depends onused bythread_local
1.1.8crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719cdepends onused bytime
0.3.36crates.io↘ 6↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885time-core
0.1.2crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3used bytime-macros
0.2.18crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccfdepends onused bytinystr
0.7.6crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82fdepends onused bytokio
1.38.0crates.io↘ 10↖ 18sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4adepends ontokio-macros
2.3.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39adepends onused bytokio-pipe
0.2.12crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf213a84bffbd61b8fa0ba8a044b4bbe35d471d0b518867181e82bd5c15542784depends onused bytokio-rustls
0.26.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4used bytokio-stream
0.1.15crates.io↘ 4↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37afused bytokio-util
0.7.11crates.io↘ 5↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1toml
0.5.11crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234depends onused bytoml
0.8.13crates.io↘ 4↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bbaused bytoml_datetime
0.6.6crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbfdepends onused bytoml_edit
0.22.13crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96cused bytonic
0.12.2crates.io↘ 24↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc6f6ba989e4b2c58ae83d862d3a3e27690b6e3ae630d0deb59f3697f32aa88addepends on- async-stream
0.3.5 - async-trait
0.1.81 - axum
0.7.5 - base64
0.22.1 - bytes
1.6.0 - h2
0.4.6 - http
1.1.0 - http-body
1.0.1 - http-body-util
0.1.2 - hyper
1.4.1 - hyper-timeout
0.5.1 - hyper-util
0.1.7 - percent-encoding
2.3.1 - pin-project
1.1.5 - prost
0.13.1 - rustls-pemfile
2.1.3 - socket2
0.5.7 - tokio
1.38.0 - tokio-rustls
0.26.0 - tokio-stream
0.1.15 - tower
0.4.13 - tower-layer
0.3.3 - tower-service
0.3.3 - tracing
0.1.40
used by- async-stream
tonic-build
0.12.2crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumfe4ee8877250136bd7e3d2331632810a4df4ea5e004656990d8d66d2f5ee8a67used bytower
0.4.13crates.io↘ 12↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumb8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1cdepends ontower-http
0.5.2crates.io↘ 9↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5depends onused bytower-layer
0.3.3crates.io↘ 0↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780etower-service
0.3.3crates.io↘ 0↖ 7sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3tracing
0.1.40crates.io↘ 3↖ 13sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364eftracing-attributes
0.1.27crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7depends onused bytracing-core
0.1.32crates.io↘ 2↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54depends ontracing-indicatif
0.3.6crates.io↘ 4↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum069580424efe11d97c3fef4197fa98c004fa26672cc71ad8770d224e23b1951dtracing-log
0.2.0crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3used bytracing-serde
0.1.3crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1depends onused bytracing-subscriber
0.3.18crates.io↘ 13↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8bdepends ontype-map
0.5.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdeb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9fdepends onused bytypenum
1.17.0crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825unic-langid
0.9.5crates.io↘ 1↖ 8sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44depends onunic-langid-impl
0.9.5crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5depends onused byunicase
2.7.0crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumf7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89depends onused byunicode_categories
0.1.1crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14eused byunicode-ident
1.0.12crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4bunicode-width
0.1.12crates.io↘ 0↖ 6sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6unindent
0.2.3crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumc7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ceused 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-indexchecksum8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1utf8parse
0.2.1crates.io↘ 0↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370avaluable
0.1.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6dused byversion_check
0.9.4crates.io↘ 0↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483fvt100
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_generate_state_changes
0.1.1crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumd257817081c7dffcdbab24b9e62d2def62e2ff7d00b1c20062551e6cccc145ffdepends 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.0+wasi-snapshot-preview1crates.io↘ 0↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423used bywasm-bindgen
0.2.92crates.io↘ 2↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8depends onwasm-bindgen-backend
0.2.92crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747dadepends onwasm-bindgen-macro
0.2.92crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726used bywasm-bindgen-macro-support
0.2.92crates.io↘ 5↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7used bywinapi
0.3.9crates.io↘ 2↖ 4sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419winapi-i686-pc-windows-gnu
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6used bywinapi-util
0.1.8crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6bdepends onused bywinapi-x86_64-pc-windows-gnu
0.4.0crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183fused bywindows
0.52.0crates.io↘ 2↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksume48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0bedepends onused bywindows_aarch64_gnullvm
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8used bywindows_aarch64_gnullvm
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263used bywindows_aarch64_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bcused bywindows_aarch64_msvc
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6used bywindows_i686_gnu
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksuma75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743eused bywindows_i686_gnu
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670used bywindows_i686_gnullvm
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9used bywindows_i686_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406used bywindows_i686_msvc
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumdb3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bfused bywindows_x86_64_gnu
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718eused bywindows_x86_64_gnu
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9used bywindows_x86_64_gnullvm
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044ccused bywindows_x86_64_gnullvm
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596used bywindows_x86_64_msvc
0.48.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538used bywindows_x86_64_msvc
0.52.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumbec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0used bywindows-core
0.52.0crates.io↘ 1↖ 2sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9depends onwindows-sys
0.48.0crates.io↘ 1↖ 3sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9depends onwindows-sys
0.52.0crates.io↘ 1↖ 10sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33ddepends onwindows-targets
0.48.5crates.io↘ 7↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940cdepends onused bywindows-targets
0.52.5crates.io↘ 8↖ 5sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7ebdepends onwinnow
0.6.9crates.io↘ 1↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6depends onused byx25519-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 byz85
3.0.5crates.io↘ 0↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksum2a599daf1b507819c1121f0bf87fa37eb19daac6aff3aefefd4e6e2e0f2020fcused byzeroize
1.8.1crates.io↘ 1↖ 11sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4ddedepends onzeroize_derive
1.4.2crates.io↘ 3↖ 1sourceregistry+https://github.com/rust-lang/crates.io-indexchecksumce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69depends onused by
cmds/fleet/Cargo.tomldiffbeforeafterboth--- a/cmds/fleet/Cargo.toml
+++ b/cmds/fleet/Cargo.toml
@@ -45,6 +45,7 @@
indicatif = { version = "0.17", optional = true }
nix-eval.workspace = true
nom = "7.1.3"
+fleet-base = { version = "0.1.0", path = "../../crates/fleet-base" }
[features]
# Not quite stable
cmds/fleet/src/cmds/build_systems.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/build_systems.rs
+++ b/cmds/fleet/src/cmds/build_systems.rs
@@ -2,15 +2,14 @@
use anyhow::{anyhow, Result};
use clap::{Parser, ValueEnum};
+use fleet_base::{
+ host::{Config, ConfigHost},
+ opts::FleetOpts,
+};
use itertools::Itertools as _;
use nix_eval::nix_go;
use tokio::{task::LocalSet, time::sleep};
use tracing::{error, field, info, info_span, warn, Instrument};
-
-use crate::{
- command::MyCommand,
- host::{Config, ConfigHost},
-};
#[derive(Parser)]
pub struct Deploy {
@@ -253,7 +252,6 @@
info!("building");
let host = config.host(&host).await?;
// let action = Action::from(self.subcommand.clone());
- let fleet_config = &config.config_field;
let nixos = host.nixos_config().await?;
let drv = nix_go!(nixos.system.build[{ build_attr }]);
let outputs = drv.build().await.inspect_err(|_| {
@@ -270,12 +268,12 @@
}
impl BuildSystems {
- pub async fn run(self, config: &Config) -> Result<()> {
+ pub async fn run(self, config: &Config, opts: &FleetOpts) -> Result<()> {
let hosts = config.list_hosts().await?;
let set = LocalSet::new();
let build_attr = self.build_attr.clone();
for host in hosts.into_iter() {
- if config.should_skip(&host).await? {
+ if opts.should_skip(&host).await? {
continue;
}
let config = config.clone();
@@ -320,17 +318,18 @@
}
impl Deploy {
- pub async fn run(self, config: &Config) -> Result<()> {
+ pub async fn run(self, config: &Config, opts: &FleetOpts) -> Result<()> {
let hosts = config.list_hosts().await?;
let set = LocalSet::new();
for host in hosts.into_iter() {
- if config.should_skip(&host).await? {
+ if opts.should_skip(&host).await? {
continue;
}
let config = config.clone();
let span = info_span!("deploy", host = field::display(&host.name));
let hostname = host.name.clone();
let local_host = config.local_host();
+ let opts = opts.clone();
// FIXME: Fix repl concurrency (see build-systems)
set.spawn_local(
(async move {
@@ -342,7 +341,7 @@
return;
}
};
- if !config.is_local(&hostname) {
+ if !opts.is_local(&hostname) {
info!("uploading system closure");
{
// TODO: Move to remote_derivation method.
@@ -387,7 +386,7 @@
self.action,
&host,
built,
- if let Ok(v) = config.action_attr(&host, "specialisation").await {
+ if let Ok(v) = opts.action_attr(&host, "specialisation").await {
v
} else {
error!("unreachable? failed to get specialization");
cmds/fleet/src/cmds/info.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/info.rs
+++ b/cmds/fleet/src/cmds/info.rs
@@ -2,9 +2,8 @@
use anyhow::{ensure, Result};
use clap::Parser;
+use fleet_base::host::Config;
use nix_eval::nix_go_json;
-
-use crate::host::Config;
#[derive(Parser)]
pub struct Info {
@@ -39,8 +38,7 @@
'host: for host in config.list_hosts().await? {
if !tagged.is_empty() {
let config = &config.config_field;
- let tags: Vec<String> =
- nix_go_json!(config.hosts[{ host.name }].tags);
+ let tags: Vec<String> = nix_go_json!(config.hosts[{ host.name }].tags);
for tag in tagged {
if !tags.contains(tag) {
continue 'host;
cmds/fleet/src/cmds/secrets/mod.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/secrets/mod.rs
+++ b/cmds/fleet/src/cmds/secrets/mod.rs
@@ -1,6 +1,5 @@
use std::{
collections::{BTreeMap, BTreeSet, HashSet},
- ffi::OsString,
io::{self, stdin, stdout, Read, Write},
path::PathBuf,
};
@@ -8,21 +7,19 @@
use anyhow::{anyhow, bail, ensure, Context, Result};
use chrono::{DateTime, Utc};
use clap::Parser;
-use crossterm::{terminal, tty::IsTty};
+use fleet_base::{
+ fleetdata::{encrypt_secret_data, FleetSecret, FleetSecretPart, FleetSharedSecret},
+ host::Config,
+ opts::FleetOpts,
+};
use fleet_shared::SecretData;
-use itertools::Itertools;
use nix_eval::{nix_go, nix_go_json, Value};
use owo_colors::OwoColorize;
use serde::Deserialize;
use tabled::{Table, Tabled};
-use tokio::{fs::read, process::Command};
+use tokio::fs::read;
use tracing::{error, info, info_span, warn, Instrument};
-use crate::{
- fleetdata::{encrypt_secret_data, FleetSecret, FleetSecretPart, FleetSharedSecret},
- host::Config,
-};
-
#[derive(Parser)]
pub enum Secret {
/// Force load host keys for all defined hosts
@@ -432,11 +429,11 @@
Ok(target_machines)
}
impl Secret {
- pub async fn run(self, config: &Config) -> Result<()> {
+ pub async fn run(self, config: &Config, opts: &FleetOpts) -> Result<()> {
match self {
Secret::ForceKeys => {
for host in config.list_hosts().await? {
- if config.should_skip(&host).await? {
+ if opts.should_skip(&host).await? {
continue;
}
config.key(&host.name).await?;
@@ -639,7 +636,7 @@
}
}
for host in config.list_hosts().await? {
- if config.should_skip(&host).await? {
+ if opts.should_skip(&host).await? {
continue;
}
@@ -757,6 +754,7 @@
}
}
+/*
async fn edit_temp_file(
builder: tempfile::Builder<'_, '_>,
r: Vec<u8>,
@@ -835,3 +833,4 @@
// Ok((success, abs_path))
}
+*/
cmds/fleet/src/cmds/tf.rsdiffbeforeafterboth--- a/cmds/fleet/src/cmds/tf.rs
+++ b/cmds/fleet/src/cmds/tf.rs
@@ -1,22 +1,67 @@
-use anyhow::Result;
+use std::{
+ collections::{BTreeMap, HashMap},
+ path::PathBuf,
+};
+
+use anyhow::{bail, Context, Result};
use clap::Parser;
-use nix_eval::nix_go_json;
+use fleet_base::host::Config;
+use nix_eval::nix_go;
+use serde::Deserialize;
use serde_json::Value;
-use tokio::fs::write;
-use tracing::info;
+use tokio::{fs::copy, process::Command};
-use crate::host::Config;
+#[derive(Deserialize)]
+pub struct TfData {
+ // Dummy
+ #[allow(dead_code)]
+ managed: bool,
+ // Host => Data
+ #[serde(default)]
+ #[serde(skip_serializing_if = "BTreeMap::is_empty")]
+ pub hosts: BTreeMap<String, Value>,
+}
#[derive(Parser)]
-pub struct Tf;
+pub enum Tf {
+ /// Generate fleet.tf.json file for running terraform.
+ Generate,
+ /// Fetch data from terraform to fleet.
+ Refresh,
+}
impl Tf {
pub async fn run(&self, config: &Config) -> Result<()> {
- let system = &config.local_system;
- let config = &config.config_field;
- let data: Value = nix_go_json!(config.tf({ system }).config);
- let str = serde_json::to_string_pretty(&data)?;
+ match self {
+ Tf::Generate => {
+ let system = &config.local_system;
+ let config = &config.config_field;
+ let data: HashMap<String, PathBuf> = nix_go!(config.tf({ system })).build().await?;
+ let data = &data["out"];
+
+ copy(data, "fleet.tf.json").await?;
+ }
+ Tf::Refresh => {
+ let cmd = Command::new("terraform").arg("refresh").status().await?;
+ if !cmd.success() {
+ bail!("terraform refresh failed")
+ }
- write("fleet.tf.json", str.as_bytes()).await?;
+ let data = Command::new("terraform")
+ .arg("output")
+ .arg("-json")
+ .arg("fleet")
+ .output()
+ .await?;
+ let tf_data: TfData = serde_json::from_slice(&data.stdout)
+ .context("failed to parse terraform fleet output")?;
+
+ let mut data = config.data();
+ data.extra.insert(
+ "terraformHosts".to_owned(),
+ serde_json::to_value(tf_data.hosts).expect("should be valid extra"),
+ );
+ }
+ }
Ok(())
}
cmds/fleet/src/command.rsdiffbeforeafterboth--- a/cmds/fleet/src/command.rs
+++ /dev/null
@@ -1,430 +0,0 @@
-use std::{ffi::OsStr, pin, process::Stdio, sync::Arc, task::Poll};
-
-use anyhow::{anyhow, Result};
-use better_command::{Handler, NixHandler, PlainHandler};
-use futures::StreamExt;
-use itertools::Either;
-use openssh::{OverSsh, OwningCommand, Session};
-use tokio::{io::AsyncRead, process::Command, select};
-use tokio_util::codec::{BytesCodec, FramedRead, LinesCodec};
-use tracing::debug;
-
-use crate::host::EscalationStrategy;
-
-fn escape_bash(input: &str, out: &mut String) {
- const TO_ESCAPE: &str = "$ !\"#&'()*,;<>?[\\]^`{|}";
- if input.chars().all(|c| !TO_ESCAPE.contains(c)) {
- out.push_str(input);
- return;
- }
- out.push('\'');
- for (i, v) in input.split('\'').enumerate() {
- if i != 0 {
- out.push_str("'\"'\"'");
- }
- out.push_str(v);
- }
- out.push('\'');
-}
-fn ostoutf8(os: impl AsRef<OsStr>) -> String {
- os.as_ref().to_str().expect("non-utf8 data").to_owned()
-}
-
-#[derive(Clone, Debug)]
-pub struct MyCommand {
- command: String,
- args: Vec<String>,
- env: Vec<(String, String)>,
- ssh_session: Option<Arc<Session>>,
- escalation: EscalationStrategy,
- escalate: bool,
-}
-impl MyCommand {
- pub fn new_on(
- escalation: EscalationStrategy,
- cmd: impl AsRef<OsStr>,
- session: Arc<Session>,
- ) -> Self {
- assert!(!cmd.as_ref().is_empty());
- Self {
- command: ostoutf8(cmd),
- args: vec![],
- env: vec![],
- ssh_session: Some(session),
- escalation,
- escalate: false,
- }
- }
- pub fn new(escalation: EscalationStrategy, cmd: impl AsRef<OsStr>) -> Self {
- assert!(!cmd.as_ref().is_empty());
- Self {
- command: ostoutf8(cmd),
- args: vec![],
- env: vec![],
- ssh_session: None,
- escalation,
- escalate: false,
- }
- }
- fn new_here(&self, cmd: impl AsRef<OsStr>) -> Self {
- if let Some(ssh_session) = self.ssh_session.clone() {
- Self::new_on(self.escalation, cmd, ssh_session)
- } else {
- Self::new(self.escalation, cmd)
- }
- }
-
- fn into_args(self) -> Vec<String> {
- let mut out = Vec::new();
- if !self.env.is_empty() {
- out.push("env".to_owned());
- for (k, v) in self.env {
- assert!(!k.contains('='));
- out.push(format!("{k}={v}"));
- }
- }
- out.push(self.command);
- out.extend(self.args);
- out
- }
-
- /// Translates environment variables into env command execution.
- /// Required for ssh, as ssh don't allow to send environment variables (at least by default).
- ///
- /// FIXME: Insecure, as arguments might be seen by other users on the same machine.
- /// Figure out some way to transfer environment using stdio?
- fn translate_env_into_env(self) -> Self {
- if self.env.is_empty() {
- return self;
- }
- let mut out = self.new_here("env");
- for (k, v) in self.env {
- assert!(!k.contains('='));
- out.arg(format!("{k}={v}"));
- }
- out.arg(self.command);
- out.args(self.args);
-
- out
- }
- fn into_string(self) -> String {
- let mut out = String::new();
- if !self.env.is_empty() {
- out.push_str("env");
- for (k, v) in self.env {
- out.push(' ');
- assert!(!k.contains('='));
- escape_bash(&k, &mut out);
- out.push('=');
- escape_bash(&v, &mut out);
- }
- }
- if !out.is_empty() {
- out.push(' ');
- }
- escape_bash(&self.command, &mut out);
- for arg in self.args {
- out.push(' ');
- escape_bash(&arg, &mut out);
- }
- out
- }
- fn into_command(self) -> Command {
- let mut out = Command::new(self.command);
- out.args(self.args);
- for (k, v) in self.env {
- out.env(k, v);
- }
- out
- }
- fn into_command_new(self) -> Result<Either<Command, openssh::OwningCommand<Arc<Session>>>> {
- Ok(if let Some(session) = self.ssh_session.clone() {
- let cmd = self.translate_env_into_env().into_command();
- Either::Right(
- cmd.over_ssh(session)
- .map_err(|e| anyhow!("ssh error: {e}"))?,
- )
- } else {
- let cmd = self.into_command();
- Either::Left(cmd)
- })
- }
- pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
- let arg = arg.as_ref();
- self.args.push(ostoutf8(arg));
- self
- }
- pub fn eqarg(&mut self, arg: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Self {
- let arg = arg.as_ref();
- let value = value.as_ref();
- let arg = ostoutf8(arg);
- let value = ostoutf8(value);
- self.arg(format!("{arg}={value}"));
- self
- }
- pub fn comparg(&mut self, arg: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Self {
- self.arg(arg);
- self.arg(value);
- self
- }
- pub fn env(&mut self, name: impl AsRef<str>, value: impl AsRef<str>) -> &mut Self {
- self.env
- .push((name.as_ref().to_owned(), value.as_ref().to_owned()));
- self
- }
- pub fn args<V: AsRef<OsStr>>(&mut self, args: impl IntoIterator<Item = V>) -> &mut Self {
- for arg in args.into_iter() {
- let arg = arg.as_ref();
- self.args.push(ostoutf8(arg));
- }
- self
- }
- pub fn sudo(mut self) -> Self {
- self.escalate = true;
- self
- }
- fn wrap_sudo_if_needed(self) -> Self {
- if !self.escalate {
- return self;
- }
- match self.escalation {
- EscalationStrategy::Su => {
- let mut out = self.new_here("su");
- out.arg("-c").arg(self.into_string());
- out
- }
- EscalationStrategy::Sudo => {
- let mut out = self.new_here("sudo");
- out.args(self.into_args());
- out
- }
- EscalationStrategy::Run0 => {
- // run0 wants interactive authentication by default.
- let mut run0 = self.new_here("run0");
- let mut out = self.new_here("script");
-
- // Red backgrounds messes with fleet formatting
- run0.arg("--background=");
- run0.args(self.into_args());
-
- out.arg("-q");
- out.arg("/dev/null");
- out.arg("-c");
- out.arg(run0.into_string());
- dbg!(&out);
- out
- }
- }
- }
-
- pub async fn run(self) -> Result<()> {
- let str = self.clone().into_string();
- let cmd = self.wrap_sudo_if_needed().into_command_new()?;
- match cmd {
- Either::Left(cmd) => run_nix_inner(str, cmd, &mut PlainHandler).await?,
- Either::Right(cmd) => run_nix_inner_ssh(str, cmd, &mut PlainHandler).await?,
- };
- Ok(())
- }
- pub async fn run_string(self) -> Result<String> {
- let bytes = self.run_bytes().await?;
- Ok(String::from_utf8(bytes)?)
- }
- pub async fn run_bytes(self) -> Result<Vec<u8>> {
- let str = self.clone().into_string();
- let cmd = self.wrap_sudo_if_needed().into_command_new()?;
- let v = match cmd {
- Either::Left(cmd) => run_nix_inner_stdout(str, cmd, &mut PlainHandler).await?,
- Either::Right(cmd) => run_nix_inner_stdout_ssh(str, cmd, &mut PlainHandler).await?,
- };
- Ok(v)
- }
-
- pub async fn run_nix_string(mut self) -> Result<String> {
- let str = self.clone().into_string();
- self.arg("--log-format").arg("internal-json");
- let mut cmd = self.wrap_sudo_if_needed().into_command();
- let bytes = run_nix_inner_stdout(str, cmd, &mut NixHandler::default()).await?;
- Ok(String::from_utf8(bytes)?)
- }
- pub async fn run_nix(mut self) -> Result<()> {
- let str = self.clone().into_string();
- self.arg("--log-format").arg("internal-json");
- let mut cmd = self.wrap_sudo_if_needed().into_command();
- cmd.stdout(Stdio::inherit());
- run_nix_inner(str, cmd, &mut NixHandler::default()).await
- }
-}
-
-struct EmptyAsyncRead;
-impl AsyncRead for EmptyAsyncRead {
- fn poll_read(
- self: std::pin::Pin<&mut Self>,
- _cx: &mut std::task::Context<'_>,
- _buf: &mut tokio::io::ReadBuf<'_>,
- ) -> Poll<std::io::Result<()>> {
- Poll::Pending
- }
-}
-
-async fn run_nix_inner_stdout(
- str: String,
- cmd: Command,
- handler: &mut dyn Handler,
-) -> Result<Vec<u8>> {
- Ok(run_nix_inner_raw(str, cmd, true, handler, None)
- .await?
- .expect("has out"))
-}
-async fn run_nix_inner(str: String, cmd: Command, handler: &mut dyn Handler) -> Result<()> {
- let v = run_nix_inner_raw(str, cmd, false, handler, None).await?;
- assert!(v.is_none());
- Ok(())
-}
-async fn run_nix_inner_stdout_ssh(
- str: String,
- cmd: OwningCommand<Arc<Session>>,
- handler: &mut dyn Handler,
-) -> Result<Vec<u8>> {
- Ok(run_nix_inner_raw_ssh(str, cmd, true, handler, None)
- .await?
- .expect("has out"))
-}
-async fn run_nix_inner_ssh(
- str: String,
- cmd: OwningCommand<Arc<Session>>,
- handler: &mut dyn Handler,
-) -> Result<()> {
- let v = run_nix_inner_raw_ssh(str, cmd, false, handler, None).await?;
- assert!(v.is_none());
- Ok(())
-}
-
-async fn run_nix_inner_raw(
- str: String,
- mut cmd: Command,
- want_stdout: bool,
- err_handler: &mut dyn Handler,
- mut out_handler: Option<&mut dyn Handler>,
-) -> Result<Option<Vec<u8>>> {
- cmd.stderr(Stdio::piped());
- cmd.stdout(Stdio::piped());
- debug!("running command {str:?} on local");
- let mut child = cmd.spawn()?;
- let mut stderr = child.stderr.take().unwrap();
- let stdout = child.stdout.take().unwrap();
- let mut err = FramedRead::new(&mut stderr, LinesCodec::new());
- let mut out: Option<Box<dyn AsyncRead + Unpin>> = Some(Box::new(stdout));
- let mut ob = want_stdout
- .then(|| out.take().unwrap())
- .unwrap_or_else(|| Box::new(EmptyAsyncRead));
- let mut ol = (!want_stdout)
- .then(|| out.take().unwrap())
- .unwrap_or_else(|| Box::new(EmptyAsyncRead));
- let mut ob = FramedRead::new(&mut ob, BytesCodec::new());
- let mut ol = FramedRead::new(&mut ol, LinesCodec::new());
-
- // while let Some(line) = read.next().await? {}
-
- let mut out_buf = if want_stdout { Some(vec![]) } else { None };
- loop {
- select! {
- e = err.next() => {
- if let Some(e) = e {
- let e = e?;
- err_handler.handle_line(&e);
- }
- },
- o = ob.next() => {
- if let Some(o) = o {
- out_buf.as_mut().expect("stdout == wants_stdout").extend_from_slice(&o?);
- }
- },
- o = ol.next() => {
- if let Some(o) = o {
- let o = o?;
- if let Some(out) = out_handler.as_mut() {
- out.handle_line(&o)
- } else {
- err_handler.handle_line(&o)
- }
- // out_handler.handle_info(&o);
- }
- },
- code = child.wait() => {
- let code = code?;
- if !code.success() {
- anyhow::bail!("command '{str}' failed with status {}", code);
- }
- break;
- }
- }
- }
-
- Ok(out_buf)
-}
-async fn run_nix_inner_raw_ssh(
- str: String,
- mut cmd: OwningCommand<Arc<Session>>,
- want_stdout: bool,
- err_handler: &mut dyn Handler,
- mut out_handler: Option<&mut dyn Handler>,
-) -> Result<Option<Vec<u8>>> {
- debug!("running command {str:?} over ssh");
- cmd.stderr(openssh::Stdio::piped());
- cmd.stdout(openssh::Stdio::piped());
- let mut child = cmd.spawn().await?;
- let mut stderr = child.stderr().take().unwrap();
- let stdout = child.stdout().take().unwrap();
- let mut err = FramedRead::new(&mut stderr, LinesCodec::new());
- let mut out: Option<Box<dyn AsyncRead + Unpin>> = Some(Box::new(stdout));
- let mut ob = want_stdout
- .then(|| out.take().unwrap())
- .unwrap_or_else(|| Box::new(EmptyAsyncRead));
- let mut ol = (!want_stdout)
- .then(|| out.take().unwrap())
- .unwrap_or_else(|| Box::new(EmptyAsyncRead));
- let mut ob = FramedRead::new(&mut ob, BytesCodec::new());
- let mut ol = FramedRead::new(&mut ol, LinesCodec::new());
-
- // while let Some(line) = read.next().await? {}
-
- let mut out_buf = if want_stdout { Some(vec![]) } else { None };
-
- let mut wait_future = pin::pin!(child.wait());
- loop {
- select! {
- e = err.next() => {
- if let Some(e) = e {
- let e = e?;
- err_handler.handle_line(&e);
- }
- },
- o = ob.next() => {
- if let Some(o) = o {
- out_buf.as_mut().expect("stdout == wants_stdout").extend_from_slice(&o?);
- }
- },
- o = ol.next() => {
- if let Some(o) = o {
- let o = o?;
- if let Some(out) = out_handler.as_mut() {
- out.handle_line(&o)
- } else {
- err_handler.handle_line(&o)
- }
- // out_handler.handle_info(&o);
- }
- },
- code = &mut wait_future => {
- let code = code?;
- if !code.success() {
- anyhow::bail!("command '{str}' failed with status {}", code);
- }
- break;
- }
- }
- }
-
- Ok(out_buf)
-}
cmds/fleet/src/fleetdata.rsdiffbeforeafterboth--- a/cmds/fleet/src/fleetdata.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-use std::{
- collections::BTreeMap,
- io::{self, Cursor},
-};
-
-use age::Recipient;
-use chrono::{DateTime, Utc};
-use fleet_shared::SecretData;
-use itertools::Itertools;
-use serde::{de::Error, Deserialize, Serialize};
-
-#[derive(Serialize, Deserialize, Default)]
-#[serde(rename_all = "camelCase")]
-pub struct HostData {
- #[serde(default)]
- #[serde(skip_serializing_if = "String::is_empty")]
- pub encryption_key: String,
-}
-
-const VERSION: &str = "0.1.0";
-pub struct FleetDataVersion;
-impl Serialize for FleetDataVersion {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: serde::Serializer,
- {
- VERSION.serialize(serializer)
- }
-}
-impl<'de> Deserialize<'de> for FleetDataVersion {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: serde::Deserializer<'de>,
- {
- let version = String::deserialize(deserializer)?;
- if version != VERSION {
- return Err(D::Error::custom(format!(
- "fleet.nix data version mismatch, expected {VERSION}, got {version}.\nFollow the docs for migration instruction"
- )));
- }
- Ok(Self)
- }
-}
-
-#[derive(Serialize, Deserialize)]
-#[serde(rename_all = "camelCase")]
-pub struct FleetData {
- pub version: FleetDataVersion,
-
- #[serde(default)]
- pub hosts: BTreeMap<String, HostData>,
- #[serde(default)]
- #[serde(skip_serializing_if = "BTreeMap::is_empty")]
- pub shared_secrets: BTreeMap<String, FleetSharedSecret>,
- #[serde(default)]
- #[serde(skip_serializing_if = "BTreeMap::is_empty")]
- pub host_secrets: BTreeMap<String, BTreeMap<String, FleetSecret>>,
-}
-
-#[derive(Serialize, Deserialize, Clone)]
-#[serde(rename_all = "camelCase")]
-#[must_use]
-pub struct FleetSharedSecret {
- pub owners: Vec<String>,
- #[serde(flatten)]
- pub secret: FleetSecret,
-}
-
-/// Returns None if recipients.is_empty()
-pub fn encrypt_secret_data(
- recipients: impl IntoIterator<Item = impl Recipient + Send + 'static>,
- data: Vec<u8>,
-) -> Option<SecretData> {
- let mut encrypted = vec![];
- let recipients = recipients
- .into_iter()
- .map(|v| Box::new(v) as Box<dyn Recipient + Send>)
- .collect_vec();
- let mut encryptor = age::Encryptor::with_recipients(recipients)?
- .wrap_output(&mut encrypted)
- .expect("in memory write");
- io::copy(&mut Cursor::new(data), &mut encryptor).expect("in memory copy");
- encryptor.finish().expect("in memory flush");
- Some(SecretData {
- data: encrypted,
- encrypted: true,
- })
-}
-
-#[derive(Serialize, Deserialize, Clone)]
-pub struct FleetSecretPart {
- pub raw: SecretData,
-}
-
-#[derive(Serialize, Deserialize, Clone)]
-#[serde(rename_all = "camelCase")]
-#[must_use]
-pub struct FleetSecret {
- #[serde(default = "Utc::now")]
- pub created_at: DateTime<Utc>,
- #[serde(default)]
- #[serde(skip_serializing_if = "Option::is_none", alias = "expire_at")]
- pub expires_at: Option<DateTime<Utc>>,
-
- #[serde(flatten)]
- pub parts: BTreeMap<String, FleetSecretPart>,
-}
cmds/fleet/src/host.rsdiffbeforeafterboth--- a/cmds/fleet/src/host.rs
+++ /dev/null
@@ -1,630 +0,0 @@
-use std::{
- cell::{LazyCell, OnceCell},
- collections::BTreeMap,
- env::current_dir,
- ffi::{OsStr, OsString},
- fmt::Display,
- io::Write,
- ops::Deref,
- path::PathBuf,
- str::FromStr,
- sync::{Arc, Mutex, MutexGuard, OnceLock},
-};
-
-use anyhow::{anyhow, bail, ensure, Context, Result};
-use clap::Parser;
-use fleet_shared::SecretData;
-use nix_eval::{nix_go, nix_go_json, util::assert_warn, NixSessionPool, Value};
-use nom::{
- bytes::complete::take_while1,
- character::complete::char,
- combinator::{map, opt},
- multi::separated_list1,
- sequence::{preceded, separated_pair},
-};
-use openssh::SessionBuilder;
-use serde::de::DeserializeOwned;
-use tempfile::NamedTempFile;
-use tracing::error;
-
-use crate::{
- command::MyCommand,
- fleetdata::{FleetData, FleetSecret, FleetSharedSecret},
-};
-
-pub struct FleetConfigInternals {
- pub local_system: String,
- pub directory: PathBuf,
- pub opts: FleetOpts,
- pub data: Mutex<FleetData>,
- pub nix_args: Vec<OsString>,
- /// fleet_config.config
- pub config_field: Value,
-
- /// import nixpkgs {system = local};
- pub default_pkgs: Value,
-}
-
-#[derive(Clone)]
-pub struct Config(Arc<FleetConfigInternals>);
-
-impl Deref for Config {
- type Target = FleetConfigInternals;
-
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-
-#[derive(Clone, Copy, Debug)]
-pub enum EscalationStrategy {
- Sudo,
- Run0,
- Su,
-}
-
-pub struct ConfigHost {
- config: Config,
- pub name: String,
- pub local: bool,
- pub session: OnceLock<Arc<openssh::Session>>,
- groups: OnceCell<Vec<String>>,
-
- pub host_config: Option<Value>,
- pub nixos_config: OnceCell<Value>,
-}
-impl ConfigHost {
- pub async fn escalation_strategy(&self) -> Result<EscalationStrategy> {
- // Prefer sudo, as run0 has some gotchas with polkit
- // and too many repeating prompts.
- if let Ok(_) = self.find_in_path("sudo").await {
- return Ok(EscalationStrategy::Sudo);
- }
- if let Ok(_) = self.find_in_path("run0").await {
- return Ok(EscalationStrategy::Run0);
- }
- Ok(EscalationStrategy::Su)
- }
- // TOCTOU is possible here in case if config is changed, but this case is not handled anywhere anyway,
- // assuming getting tags always returns the same value.
- pub async fn tags(&self) -> Result<Vec<String>> {
- if let Some(v) = self.groups.get() {
- return Ok(v.clone());
- }
- let Some(host_config) = &self.host_config else {
- return Ok(vec![]);
- };
- let tags: Vec<String> = nix_go_json!(host_config.tags);
-
- let _ = self.groups.set(tags.clone());
-
- Ok(tags)
- }
- pub async fn nixos_config(&self) -> Result<Value> {
- if let Some(v) = self.nixos_config.get() {
- return Ok(v.clone());
- }
- let Some(host_config) = &self.host_config else {
- bail!("local host has no nixos_config");
- };
- let nixos_config = nix_go!(host_config.nixos.config);
- assert_warn("nixos config evaluation", &nixos_config).await?;
-
- let _ = self.nixos_config.set(nixos_config.clone());
-
- Ok(nixos_config)
- }
- async fn open_session(&self) -> Result<Arc<openssh::Session>> {
- assert!(!self.local, "do not open ssh connection to local session");
- // FIXME: TOCTOU
- if let Some(session) = &self.session.get() {
- return Ok((*session).clone());
- };
- let mut session = SessionBuilder::default();
- let session = session
- .connect(&self.name)
- .await
- .map_err(|e| anyhow!("ssh error while connecting to {}: {e}", self.name))?;
- let session = Arc::new(session);
- self.session.set(session.clone()).expect("TOCTOU happened");
- Ok(session)
- }
- pub async fn mktemp_dir(&self) -> Result<String> {
- let mut cmd = self.cmd("mktemp").await?;
- cmd.arg("-d");
- let path = cmd.run_string().await?;
- Ok(path.trim_end().to_owned())
- }
- pub async fn read_file_bin(&self, path: impl AsRef<OsStr>) -> Result<Vec<u8>> {
- let mut cmd = self.cmd("cat").await?;
- cmd.arg(path);
- cmd.run_bytes().await
- }
- pub async fn read_file_text(&self, path: impl AsRef<OsStr>) -> Result<String> {
- let mut cmd = self.cmd("cat").await?;
- cmd.arg(path);
- cmd.run_string().await
- }
- pub async fn read_dir(&self, path: impl AsRef<OsStr>) -> Result<Vec<String>> {
- let mut cmd = self.cmd("ls").await?;
- cmd.arg(path);
- let out = cmd.run_string().await?;
- let mut lines = out.split('\n');
- if let Some(last) = lines.next_back() {
- ensure!(last.is_empty(), "output of ls should end with newline");
- }
- Ok(lines.map(ToOwned::to_owned).collect())
- }
- #[allow(dead_code)]
- pub async fn read_file_json<D: DeserializeOwned>(&self, path: impl AsRef<OsStr>) -> Result<D> {
- let text = self.read_file_text(path).await?;
- Ok(serde_json::from_str(&text)?)
- }
- pub async fn read_env(&self, env: &str) -> Result<String> {
- let mut cmd = self.cmd("printenv").await?;
- cmd.arg(env);
- Ok(cmd.run_string().await?)
- }
- pub async fn find_in_path(&self, command: &str) -> Result<String> {
- // // `which` is not a part of coreutils, and it might not exist on machine.
- // let path = self.read_env("PATH").await?;
- // // Assuming delimiter is :, we don't work with windows host, this check will be much
- // // more sophisticated in remowt backend (and quicker, since actual PATH search will be done on remote machine)
- // for ele in path.split(':') {
- // let test_path = format!("{ele}/{cmd}");
- // test -x etc
- // }
- // let mut cmd = self.cmd("printenv").await?;
- // cmd.arg(env);
- // Ok(cmd.run_string().await?)
- // Assuming this is an environment issue if which doesn't exist, will be fixed with remowt.
- let mut cmd = self
- .cmd_escalation(
- // Not used
- EscalationStrategy::Su,
- "which",
- )
- .await?;
- cmd.arg(command);
- cmd.run_string().await
- }
- pub async fn read_file_value<D: FromStr>(&self, path: impl AsRef<OsStr>) -> Result<D>
- where
- <D as FromStr>::Err: Display,
- {
- let text = self.read_file_text(path).await?;
- D::from_str(&text).map_err(|e| anyhow!("failed to parse value: {e}"))
- }
- pub async fn cmd(&self, cmd: impl AsRef<OsStr>) -> Result<MyCommand> {
- self.cmd_escalation(self.escalation_strategy().await?, cmd)
- .await
- }
- pub async fn cmd_escalation(
- &self,
- escalation: EscalationStrategy,
- cmd: impl AsRef<OsStr>,
- ) -> Result<MyCommand> {
- if self.local {
- Ok(MyCommand::new(escalation, cmd))
- } else {
- let session = self.open_session().await?;
- Ok(MyCommand::new_on(escalation, cmd, session))
- }
- }
-
- pub async fn decrypt(&self, data: SecretData) -> Result<Vec<u8>> {
- ensure!(data.encrypted, "secret is not encrypted");
- let mut cmd = self.cmd("fleet-install-secrets").await?;
- cmd.arg("decrypt").eqarg("--secret", data.to_string());
- let encoded = cmd
- .sudo()
- .run_string()
- .await
- .context("failed to call remote host for decrypt")?;
- let data: SecretData = encoded.parse().map_err(|e| anyhow!("{e}"))?;
- ensure!(!data.encrypted, "secret came out encrypted");
- Ok(data.data)
- }
- pub async fn reencrypt(&self, data: SecretData, targets: Vec<String>) -> 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());
- for target in targets {
- let key = self.config.key(&target).await?;
- cmd.eqarg("--targets", key);
- }
- let encoded = cmd
- .sudo()
- .run_string()
- .await
- .context("failed to call remote host for decrypt")?;
- let data: SecretData = encoded.parse().map_err(|e| anyhow!("{e}"))?;
- ensure!(data.encrypted, "secret came out not encrypted");
- Ok(data)
- }
- /// Returns path for futureproofing, as path might change i.e on conversion to CA
- pub async fn remote_derivation(&self, path: &PathBuf) -> Result<PathBuf> {
- if self.local {
- // Path is located locally, thus already trusted.
- return Ok(path.to_owned());
- }
- let mut nix = MyCommand::new(
- // Not used
- EscalationStrategy::Su,
- "nix",
- );
- nix.arg("copy")
- .arg("--substitute-on-destination")
- .comparg("--to", format!("ssh-ng://{}", self.name))
- .arg(path);
- nix.run_nix().await.context("nix copy")?;
- Ok(path.to_owned())
- }
- pub async fn systemctl_stop(&self, name: &str) -> Result<()> {
- let mut cmd = self.cmd("systemctl").await?;
- cmd.arg("stop").arg(name);
- cmd.sudo().run().await
- }
- pub async fn systemctl_start(&self, name: &str) -> Result<()> {
- let mut cmd = self.cmd("systemctl").await?;
- cmd.arg("start").arg(name);
- cmd.sudo().run().await
- }
-
- pub async fn rm_file(&self, path: impl AsRef<OsStr>, sudo: bool) -> Result<()> {
- let mut cmd = self.cmd("rm").await?;
- cmd.arg("-f").arg(path);
- if sudo {
- cmd = cmd.sudo()
- }
- cmd.run().await
- }
-
- pub async fn list_configured_secrets(&self) -> Result<Vec<String>> {
- let nixos = self.nixos_config().await?;
- let secrets = nix_go!(nixos.secrets);
- let mut out = Vec::new();
- for name in secrets.list_fields().await? {
- let secret = nix_go!(secrets[{ name }]);
- let is_shared: bool = nix_go_json!(secret.shared);
- if is_shared {
- continue;
- }
- out.push(name);
- }
- Ok(out)
- }
- pub async fn secret_field(&self, name: &str) -> Result<Value> {
- let nixos = self.nixos_config().await?;
- Ok(nix_go!(nixos.secrets[{ name }]))
- }
-
- /// Packages for this host, resolved with nixpkgs overlays
- pub async fn pkgs(&self) -> Result<Value> {
- let Some(host_config) = &self.host_config else {
- bail!("local host has no host_config");
- };
- // TODO: Should nixos.options be cached?
- Ok(nix_go!(host_config.nixos.options._module.args.value.pkgs))
- }
-}
-
-impl Config {
- pub async fn should_skip(&self, host: &ConfigHost) -> Result<bool> {
- if !self.opts.skip.is_empty() && self.opts.skip.iter().any(|h| h as &str == host.name) {
- return Ok(true);
- }
- if self.opts.only.is_empty() {
- return Ok(false);
- }
- let mut have_group_matches = false;
- for item in self.opts.only.iter() {
- match item {
- HostItem::Host { name, .. } if *name == host.name => {
- return Ok(false);
- }
- HostItem::Tag { .. } => {
- have_group_matches = true;
- }
- _ => {}
- }
- }
- if have_group_matches {
- let host_tags = host.tags().await?;
- for item in self.opts.only.iter() {
- match item {
- HostItem::Tag { name, .. } if host_tags.contains(name) => {
- return Ok(false);
- }
- _ => {}
- }
- }
- }
- Ok(true)
- }
- pub async fn action_attr(&self, host: &ConfigHost, attr: &str) -> Result<Option<String>> {
- if self.opts.only.is_empty() {
- return Ok(None);
- }
- let mut have_group_matches = false;
- for item in self.opts.only.iter() {
- match item {
- HostItem::Host { name, attrs }
- if *name == host.name && attrs.contains_key(attr) =>
- {
- return Ok(attrs.get(attr).cloned());
- }
- HostItem::Tag { attrs, .. } if attrs.contains_key(attr) => {
- have_group_matches = true;
- }
- _ => {}
- }
- }
- if have_group_matches {
- let host_tags = host.tags().await?;
- for item in self.opts.only.iter() {
- match item {
- HostItem::Tag { name, attrs }
- if host_tags.contains(name) && attrs.contains_key(attr) =>
- {
- return Ok(attrs.get(attr).cloned());
- }
- _ => {}
- }
- }
- }
- Ok(None)
- }
- pub fn is_local(&self, host: &str) -> bool {
- self.opts.localhost.as_ref().map(|s| s as &str) == Some(host)
- }
-
- pub fn local_host(&self) -> ConfigHost {
- ConfigHost {
- config: self.clone(),
- name: "<virtual localhost>".to_owned(),
- local: true,
- session: OnceLock::new(),
- host_config: None,
- nixos_config: OnceCell::new(),
- groups: {
- let cell = OnceCell::new();
- let _ = cell.set(vec![]);
- cell
- },
- }
- }
-
- pub async fn host(&self, name: &str) -> Result<ConfigHost> {
- let config = &self.config_field;
- let host_config = nix_go!(config.hosts[{ name }]);
-
- Ok(ConfigHost {
- config: self.clone(),
- name: name.to_owned(),
- local: self.is_local(name),
- session: OnceLock::new(),
- host_config: Some(host_config),
- nixos_config: OnceCell::new(),
- groups: OnceCell::new(),
- })
- }
- pub async fn list_hosts(&self) -> Result<Vec<ConfigHost>> {
- let config = &self.config_field;
- let names = nix_go!(config.hosts).list_fields().await?;
- let mut out = vec![];
- for name in names {
- out.push(self.host(&name).await?);
- }
- Ok(out)
- }
- pub async fn system_config(&self, host: &str) -> Result<Value> {
- let fleet_field = &self.config_field;
- Ok(nix_go!(fleet_field.hosts[{ host }].nixos.config))
- }
-
- pub(super) fn data(&self) -> MutexGuard<FleetData> {
- self.data.lock().unwrap()
- }
- pub(super) fn data_mut(&self) -> MutexGuard<FleetData> {
- self.data.lock().unwrap()
- }
- /// Shared secrets configured in fleet.nix or in flake
- pub async fn list_configured_shared(&self) -> Result<Vec<String>> {
- let config_field = &self.config_field;
- Ok(nix_go!(config_field.sharedSecrets).list_fields().await?)
- }
- /// Shared secrets configured in fleet.nix
- pub fn list_shared(&self) -> Vec<String> {
- let data = self.data();
- data.shared_secrets.keys().cloned().collect()
- }
- pub fn has_shared(&self, name: &str) -> bool {
- let data = self.data();
- data.shared_secrets.contains_key(name)
- }
- pub fn replace_shared(&self, name: String, shared: FleetSharedSecret) {
- let mut data = self.data_mut();
- data.shared_secrets.insert(name.to_owned(), shared);
- }
- pub fn remove_shared(&self, secret: &str) {
- let mut data = self.data_mut();
- data.shared_secrets.remove(secret);
- }
-
- pub fn list_secrets(&self, host: &str) -> Vec<String> {
- let data = self.data();
- let Some(secrets) = data.host_secrets.get(host) else {
- return Vec::new();
- };
- secrets.keys().cloned().collect()
- }
-
- pub fn has_secret(&self, host: &str, secret: &str) -> bool {
- let data = self.data();
- let Some(host_secrets) = data.host_secrets.get(host) else {
- return false;
- };
- host_secrets.contains_key(secret)
- }
- pub fn insert_secret(&self, host: &str, secret: String, value: FleetSecret) {
- let mut data = self.data_mut();
- let host_secrets = data.host_secrets.entry(host.to_owned()).or_default();
- host_secrets.insert(secret, value);
- }
-
- pub fn host_secret(&self, host: &str, secret: &str) -> Result<FleetSecret> {
- let data = self.data();
- let Some(host_secrets) = data.host_secrets.get(host) else {
- bail!("no secrets for machine {host}");
- };
- let Some(secret) = host_secrets.get(secret) else {
- bail!("machine {host} has no secret {secret}");
- };
- Ok(secret.clone())
- }
- pub fn shared_secret(&self, secret: &str) -> Result<FleetSharedSecret> {
- let data = self.data();
- let Some(secret) = data.shared_secrets.get(secret) else {
- bail!("no shared secret {secret}");
- };
- Ok(secret.clone())
- }
- pub async fn shared_secret_expected_owners(&self, secret: &str) -> Result<Vec<String>> {
- let config_field = &self.config_field;
- Ok(nix_go_json!(
- config_field.sharedSecrets[{ secret }].expectedOwners
- ))
- }
-
- 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)?;
- tempfile.write_all(
- format!(
- "# This file contains fleet state and shouldn't be edited by hand\n\n{}\n\n# vim: ts=2 et nowrap\n",
- data
- )
- .as_bytes(),
- )?;
- let mut fleet_data_path = self.directory.clone();
- fleet_data_path.push("fleet.nix");
- tempfile.persist(fleet_data_path)?;
- Ok(())
- }
-}
-
-#[derive(Clone)]
-enum HostItem {
- Host {
- name: String,
- attrs: BTreeMap<String, String>,
- },
- Tag {
- name: String,
- attrs: BTreeMap<String, String>,
- },
-}
-fn host_item_parser(input: &str) -> Result<HostItem, String> {
- fn err_to_string(err: nom::Err<nom::error::Error<&str>>) -> String {
- err.to_string()
- }
-
- let (input, is_tag) = map(opt(char('@')), |c| c.is_some())(input).map_err(err_to_string)?;
- let (input, name) = map(
- take_while1(|v| v != ',' && v != '?' && v != '@'),
- str::to_owned,
- )(input)
- .map_err(err_to_string)?;
-
- let kw_item = separated_pair(
- map(take_while1(|v| v != '&' && v != '='), str::to_owned),
- char('='),
- map(take_while1(|v| v != '&'), str::to_owned),
- );
- let kw = map(separated_list1(char('&'), kw_item), |vec| {
- vec.into_iter().collect::<BTreeMap<_, _>>()
- });
- let mut opt_kw = map(opt(preceded(char('?'), kw)), Option::unwrap_or_default);
-
- let (input, attrs) = opt_kw(input).map_err(err_to_string)?;
-
- if !input.is_empty() {
- return Err(format!("unexpected trailing input: {input:?}"));
- }
- Ok(if is_tag {
- HostItem::Tag { name, attrs }
- } else {
- HostItem::Host { name, attrs }
- })
-}
-
-#[derive(Parser, Clone)]
-pub struct FleetOpts {
- /// All hosts except those would be skipped
- #[clap(long, number_of_values = 1, value_parser = host_item_parser)]
- only: Vec<HostItem>,
-
- /// Hosts to skip
- #[clap(long, number_of_values = 1)]
- skip: Vec<String>,
-
- /// Host, which should be threaten as current machine
- #[clap(long)]
- pub localhost: Option<String>,
-
- /// Override detected system for host, to perform builds via
- /// binfmt-declared qemu instead of trying to crosscompile
- #[clap(long, default_value = "detect")]
- pub local_system: String,
-}
-
-impl FleetOpts {
- pub async fn build(mut self, nix_args: Vec<OsString>) -> Result<Config> {
- if self.localhost.is_none() {
- self.localhost
- .replace(hostname::get().unwrap().to_str().unwrap().to_owned());
- }
- let directory = current_dir()?;
-
- let pool = NixSessionPool::new(directory.as_os_str().to_owned(), nix_args.clone()).await?;
- let root_field = pool.get().await?;
-
- let builtins_field = Value::binding(root_field.clone(), "builtins").await?;
- if self.local_system == "detect" {
- self.local_system = nix_go_json!(builtins_field.currentSystem);
- }
- let local_system = self.local_system.clone();
-
- let mut fleet_data_path = directory.clone();
- fleet_data_path.push("fleet.nix");
- let bytes = std::fs::read_to_string(fleet_data_path)?;
- let data: Mutex<FleetData> = nixlike::parse_str(&bytes)?;
-
- let fleet_root = Value::binding(root_field, "fleetConfigurations").await?;
- let fleet_field = nix_go!(fleet_root.default({ data }));
-
- let config_field = nix_go!(fleet_field.config);
-
- assert_warn("fleet config evaluation", &config_field).await?;
-
- let import = nix_go!(builtins_field.import);
- let overlays = nix_go!(config_field.nixpkgs.overlays);
- let nixpkgs = nix_go!(fleet_field.nixpkgs.buildUsing | import);
-
- let default_pkgs = nix_go!(nixpkgs(Obj {
- overlays,
- system: { self.local_system.clone() },
- }));
-
- Ok(Config(Arc::new(FleetConfigInternals {
- opts: self,
- directory,
- data,
- local_system,
- nix_args,
- config_field,
- default_pkgs,
- })))
- }
-}
cmds/fleet/src/keys.rsdiffbeforeafterboth--- a/cmds/fleet/src/keys.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-use std::str::FromStr;
-
-use age::Recipient;
-use anyhow::{anyhow, Result};
-use futures::{StreamExt, TryStreamExt};
-use itertools::Itertools;
-use tracing::warn;
-
-use crate::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);
- if let Some(key) = key {
- if key.is_empty() {
- return None;
- }
- }
- 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();
- 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) {
- Ok(key)
- } else {
- warn!("Loading key for {}", host);
- let host = self.host(host).await?;
- let mut cmd = host.cmd("cat").await?;
- cmd.arg("/etc/ssh/ssh_host_ed25519_key.pub");
- let key = cmd.run_string().await?;
- self.update_key(&host.name, key.clone());
- Ok(key)
- }
- }
- /// Insecure, requires root
- pub async fn recipient(&self, host: &str) -> anyhow::Result<impl Recipient> {
- let key = self.key(host).await?;
- age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))
- }
-
- pub async fn recipients(&self, hosts: Vec<String>) -> Result<Vec<impl Recipient>> {
- futures::stream::iter(hosts.iter())
- .then(|m| self.recipient(m.as_ref()))
- .try_collect::<Vec<_>>()
- .await
- }
-
- #[allow(dead_code)]
- pub async fn orphaned_data(&self) -> Result<Vec<String>> {
- let mut out = Vec::new();
- let host_names = self
- .list_hosts()
- .await?
- .into_iter()
- .map(|h| h.name)
- .collect_vec();
- for hostname in self
- .data()
- .hosts
- .iter()
- .filter(|(_, host)| !host.encryption_key.is_empty())
- .map(|(n, _)| n)
- {
- if !host_names.contains(hostname) {
- out.push(hostname.to_owned())
- }
- }
-
- Ok(out)
- }
-}
cmds/fleet/src/main.rsdiffbeforeafterboth--- a/cmds/fleet/src/main.rs
+++ b/cmds/fleet/src/main.rs
@@ -2,13 +2,8 @@
#![feature(try_blocks)]
pub(crate) mod cmds;
-pub(crate) mod command;
-pub(crate) mod host;
-pub(crate) mod keys;
-
+// pub(crate) mod command;
pub(crate) mod extra_args;
-
-mod fleetdata;
use std::{ffi::OsString, process::ExitCode};
@@ -21,8 +16,9 @@
secrets::Secret,
tf::Tf,
};
+use fleet_base::{host::Config, opts::FleetOpts};
use futures::{future::LocalBoxFuture, stream::FuturesUnordered, TryStreamExt};
-use host::{Config, FleetOpts};
+// use host::Config;
#[cfg(feature = "indicatif")]
use human_repr::HumanCount;
#[cfg(feature = "indicatif")]
@@ -31,8 +27,6 @@
#[cfg(feature = "indicatif")]
use tracing_indicatif::IndicatifLayer;
use tracing_subscriber::{prelude::*, EnvFilter};
-
-use crate::command::MyCommand;
#[derive(Parser)]
struct Prefetch {}
@@ -88,6 +82,7 @@
#[clap(hide(true))]
Complete(Complete),
/// Compile and evaluate terranix configuration
+ #[clap(subcommand)]
Tf(Tf),
}
@@ -100,11 +95,11 @@
command: Opts,
}
-async fn run_command(config: &Config, command: Opts) -> Result<()> {
+async fn run_command(config: &Config, opts: FleetOpts, command: Opts) -> Result<()> {
match command {
- Opts::BuildSystems(c) => c.run(config).await?,
- Opts::Deploy(d) => d.run(config).await?,
- Opts::Secret(s) => s.run(config).await?,
+ Opts::BuildSystems(c) => c.run(config, &opts).await?,
+ Opts::Deploy(d) => d.run(config, &opts).await?,
+ Opts::Secret(s) => s.run(config, &opts).await?,
Opts::Info(i) => i.run(config).await?,
Opts::Prefetch(p) => p.run(config).await?,
Opts::Tf(t) => t.run(config).await?,
@@ -211,7 +206,7 @@
.unwrap_or_default();
let config = opts.fleet_opts.build(nix_args).await?;
- match run_command(&config, opts.command).await {
+ match run_command(&config, opts.fleet_opts, opts.command).await {
Ok(()) => {
config.save()?;
Ok(())
crates/fleet-base/Cargo.tomldiffbeforeafterboth--- /dev/null
+++ b/crates/fleet-base/Cargo.toml
@@ -0,0 +1,25 @@
+[package]
+name = "fleet-base"
+edition = "2021"
+version.workspace = true
+
+[dependencies]
+age.workspace = true
+anyhow.workspace = true
+better-command.workspace = true
+chrono = "0.4.38"
+clap = { workspace = true, features = ["derive"] }
+fleet-shared.workspace = true
+futures = "0.3.30"
+hostname = "0.4.0"
+itertools = "0.13.0"
+nix-eval.workspace = true
+nixlike.workspace = true
+nom = "7.1.3"
+openssh = "0.11.0"
+serde.workspace = true
+serde_json = "1.0.127"
+tempfile.workspace = true
+tokio.workspace = true
+tokio-util = "0.7.11"
+tracing.workspace = true
crates/fleet-base/src/command.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/fleet-base/src/command.rs
@@ -0,0 +1,430 @@
+use std::{ffi::OsStr, pin, process::Stdio, sync::Arc, task::Poll};
+
+use anyhow::{anyhow, Result};
+use better_command::{Handler, NixHandler, PlainHandler};
+use futures::StreamExt;
+use itertools::Either;
+use openssh::{OverSsh, OwningCommand, Session};
+use tokio::{io::AsyncRead, process::Command, select};
+use tokio_util::codec::{BytesCodec, FramedRead, LinesCodec};
+use tracing::debug;
+
+use crate::host::EscalationStrategy;
+
+fn escape_bash(input: &str, out: &mut String) {
+ const TO_ESCAPE: &str = "$ !\"#&'()*,;<>?[\\]^`{|}";
+ if input.chars().all(|c| !TO_ESCAPE.contains(c)) {
+ out.push_str(input);
+ return;
+ }
+ out.push('\'');
+ for (i, v) in input.split('\'').enumerate() {
+ if i != 0 {
+ out.push_str("'\"'\"'");
+ }
+ out.push_str(v);
+ }
+ out.push('\'');
+}
+fn ostoutf8(os: impl AsRef<OsStr>) -> String {
+ os.as_ref().to_str().expect("non-utf8 data").to_owned()
+}
+
+#[derive(Clone, Debug)]
+pub struct MyCommand {
+ command: String,
+ args: Vec<String>,
+ env: Vec<(String, String)>,
+ ssh_session: Option<Arc<Session>>,
+ escalation: EscalationStrategy,
+ escalate: bool,
+}
+impl MyCommand {
+ pub fn new_on(
+ escalation: EscalationStrategy,
+ cmd: impl AsRef<OsStr>,
+ session: Arc<Session>,
+ ) -> Self {
+ assert!(!cmd.as_ref().is_empty());
+ Self {
+ command: ostoutf8(cmd),
+ args: vec![],
+ env: vec![],
+ ssh_session: Some(session),
+ escalation,
+ escalate: false,
+ }
+ }
+ pub fn new(escalation: EscalationStrategy, cmd: impl AsRef<OsStr>) -> Self {
+ assert!(!cmd.as_ref().is_empty());
+ Self {
+ command: ostoutf8(cmd),
+ args: vec![],
+ env: vec![],
+ ssh_session: None,
+ escalation,
+ escalate: false,
+ }
+ }
+ fn new_here(&self, cmd: impl AsRef<OsStr>) -> Self {
+ if let Some(ssh_session) = self.ssh_session.clone() {
+ Self::new_on(self.escalation, cmd, ssh_session)
+ } else {
+ Self::new(self.escalation, cmd)
+ }
+ }
+
+ fn into_args(self) -> Vec<String> {
+ let mut out = Vec::new();
+ if !self.env.is_empty() {
+ out.push("env".to_owned());
+ for (k, v) in self.env {
+ assert!(!k.contains('='));
+ out.push(format!("{k}={v}"));
+ }
+ }
+ out.push(self.command);
+ out.extend(self.args);
+ out
+ }
+
+ /// Translates environment variables into env command execution.
+ /// Required for ssh, as ssh don't allow to send environment variables (at least by default).
+ ///
+ /// FIXME: Insecure, as arguments might be seen by other users on the same machine.
+ /// Figure out some way to transfer environment using stdio?
+ fn translate_env_into_env(self) -> Self {
+ if self.env.is_empty() {
+ return self;
+ }
+ let mut out = self.new_here("env");
+ for (k, v) in self.env {
+ assert!(!k.contains('='));
+ out.arg(format!("{k}={v}"));
+ }
+ out.arg(self.command);
+ out.args(self.args);
+
+ out
+ }
+ fn into_string(self) -> String {
+ let mut out = String::new();
+ if !self.env.is_empty() {
+ out.push_str("env");
+ for (k, v) in self.env {
+ out.push(' ');
+ assert!(!k.contains('='));
+ escape_bash(&k, &mut out);
+ out.push('=');
+ escape_bash(&v, &mut out);
+ }
+ }
+ if !out.is_empty() {
+ out.push(' ');
+ }
+ escape_bash(&self.command, &mut out);
+ for arg in self.args {
+ out.push(' ');
+ escape_bash(&arg, &mut out);
+ }
+ out
+ }
+ fn into_command(self) -> Command {
+ let mut out = Command::new(self.command);
+ out.args(self.args);
+ for (k, v) in self.env {
+ out.env(k, v);
+ }
+ out
+ }
+ fn into_command_new(self) -> Result<Either<Command, openssh::OwningCommand<Arc<Session>>>> {
+ Ok(if let Some(session) = self.ssh_session.clone() {
+ let cmd = self.translate_env_into_env().into_command();
+ Either::Right(
+ cmd.over_ssh(session)
+ .map_err(|e| anyhow!("ssh error: {e}"))?,
+ )
+ } else {
+ let cmd = self.into_command();
+ Either::Left(cmd)
+ })
+ }
+ pub fn arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
+ let arg = arg.as_ref();
+ self.args.push(ostoutf8(arg));
+ self
+ }
+ pub fn eqarg(&mut self, arg: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Self {
+ let arg = arg.as_ref();
+ let value = value.as_ref();
+ let arg = ostoutf8(arg);
+ let value = ostoutf8(value);
+ self.arg(format!("{arg}={value}"));
+ self
+ }
+ pub fn comparg(&mut self, arg: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> &mut Self {
+ self.arg(arg);
+ self.arg(value);
+ self
+ }
+ pub fn env(&mut self, name: impl AsRef<str>, value: impl AsRef<str>) -> &mut Self {
+ self.env
+ .push((name.as_ref().to_owned(), value.as_ref().to_owned()));
+ self
+ }
+ pub fn args<V: AsRef<OsStr>>(&mut self, args: impl IntoIterator<Item = V>) -> &mut Self {
+ for arg in args.into_iter() {
+ let arg = arg.as_ref();
+ self.args.push(ostoutf8(arg));
+ }
+ self
+ }
+ pub fn sudo(mut self) -> Self {
+ self.escalate = true;
+ self
+ }
+ fn wrap_sudo_if_needed(self) -> Self {
+ if !self.escalate {
+ return self;
+ }
+ match self.escalation {
+ EscalationStrategy::Su => {
+ let mut out = self.new_here("su");
+ out.arg("-c").arg(self.into_string());
+ out
+ }
+ EscalationStrategy::Sudo => {
+ let mut out = self.new_here("sudo");
+ out.args(self.into_args());
+ out
+ }
+ EscalationStrategy::Run0 => {
+ // run0 wants interactive authentication by default.
+ let mut run0 = self.new_here("run0");
+ let mut out = self.new_here("script");
+
+ // Red backgrounds messes with fleet formatting
+ run0.arg("--background=");
+ run0.args(self.into_args());
+
+ out.arg("-q");
+ out.arg("/dev/null");
+ out.arg("-c");
+ out.arg(run0.into_string());
+ dbg!(&out);
+ out
+ }
+ }
+ }
+
+ pub async fn run(self) -> Result<()> {
+ let str = self.clone().into_string();
+ let cmd = self.wrap_sudo_if_needed().into_command_new()?;
+ match cmd {
+ Either::Left(cmd) => run_nix_inner(str, cmd, &mut PlainHandler).await?,
+ Either::Right(cmd) => run_nix_inner_ssh(str, cmd, &mut PlainHandler).await?,
+ };
+ Ok(())
+ }
+ pub async fn run_string(self) -> Result<String> {
+ let bytes = self.run_bytes().await?;
+ Ok(String::from_utf8(bytes)?)
+ }
+ pub async fn run_bytes(self) -> Result<Vec<u8>> {
+ let str = self.clone().into_string();
+ let cmd = self.wrap_sudo_if_needed().into_command_new()?;
+ let v = match cmd {
+ Either::Left(cmd) => run_nix_inner_stdout(str, cmd, &mut PlainHandler).await?,
+ Either::Right(cmd) => run_nix_inner_stdout_ssh(str, cmd, &mut PlainHandler).await?,
+ };
+ Ok(v)
+ }
+
+ pub async fn run_nix_string(mut self) -> Result<String> {
+ let str = self.clone().into_string();
+ self.arg("--log-format").arg("internal-json");
+ let cmd = self.wrap_sudo_if_needed().into_command();
+ let bytes = run_nix_inner_stdout(str, cmd, &mut NixHandler::default()).await?;
+ Ok(String::from_utf8(bytes)?)
+ }
+ pub async fn run_nix(mut self) -> Result<()> {
+ let str = self.clone().into_string();
+ self.arg("--log-format").arg("internal-json");
+ let mut cmd = self.wrap_sudo_if_needed().into_command();
+ cmd.stdout(Stdio::inherit());
+ run_nix_inner(str, cmd, &mut NixHandler::default()).await
+ }
+}
+
+struct EmptyAsyncRead;
+impl AsyncRead for EmptyAsyncRead {
+ fn poll_read(
+ self: std::pin::Pin<&mut Self>,
+ _cx: &mut std::task::Context<'_>,
+ _buf: &mut tokio::io::ReadBuf<'_>,
+ ) -> Poll<std::io::Result<()>> {
+ Poll::Pending
+ }
+}
+
+async fn run_nix_inner_stdout(
+ str: String,
+ cmd: Command,
+ handler: &mut dyn Handler,
+) -> Result<Vec<u8>> {
+ Ok(run_nix_inner_raw(str, cmd, true, handler, None)
+ .await?
+ .expect("has out"))
+}
+async fn run_nix_inner(str: String, cmd: Command, handler: &mut dyn Handler) -> Result<()> {
+ let v = run_nix_inner_raw(str, cmd, false, handler, None).await?;
+ assert!(v.is_none());
+ Ok(())
+}
+async fn run_nix_inner_stdout_ssh(
+ str: String,
+ cmd: OwningCommand<Arc<Session>>,
+ handler: &mut dyn Handler,
+) -> Result<Vec<u8>> {
+ Ok(run_nix_inner_raw_ssh(str, cmd, true, handler, None)
+ .await?
+ .expect("has out"))
+}
+async fn run_nix_inner_ssh(
+ str: String,
+ cmd: OwningCommand<Arc<Session>>,
+ handler: &mut dyn Handler,
+) -> Result<()> {
+ let v = run_nix_inner_raw_ssh(str, cmd, false, handler, None).await?;
+ assert!(v.is_none());
+ Ok(())
+}
+
+async fn run_nix_inner_raw(
+ str: String,
+ mut cmd: Command,
+ want_stdout: bool,
+ err_handler: &mut dyn Handler,
+ mut out_handler: Option<&mut dyn Handler>,
+) -> Result<Option<Vec<u8>>> {
+ cmd.stderr(Stdio::piped());
+ cmd.stdout(Stdio::piped());
+ debug!("running command {str:?} on local");
+ let mut child = cmd.spawn()?;
+ let mut stderr = child.stderr.take().unwrap();
+ let stdout = child.stdout.take().unwrap();
+ let mut err = FramedRead::new(&mut stderr, LinesCodec::new());
+ let mut out: Option<Box<dyn AsyncRead + Unpin>> = Some(Box::new(stdout));
+ let mut ob = want_stdout
+ .then(|| out.take().unwrap())
+ .unwrap_or_else(|| Box::new(EmptyAsyncRead));
+ let mut ol = (!want_stdout)
+ .then(|| out.take().unwrap())
+ .unwrap_or_else(|| Box::new(EmptyAsyncRead));
+ let mut ob = FramedRead::new(&mut ob, BytesCodec::new());
+ let mut ol = FramedRead::new(&mut ol, LinesCodec::new());
+
+ // while let Some(line) = read.next().await? {}
+
+ let mut out_buf = if want_stdout { Some(vec![]) } else { None };
+ loop {
+ select! {
+ e = err.next() => {
+ if let Some(e) = e {
+ let e = e?;
+ err_handler.handle_line(&e);
+ }
+ },
+ o = ob.next() => {
+ if let Some(o) = o {
+ out_buf.as_mut().expect("stdout == wants_stdout").extend_from_slice(&o?);
+ }
+ },
+ o = ol.next() => {
+ if let Some(o) = o {
+ let o = o?;
+ if let Some(out) = out_handler.as_mut() {
+ out.handle_line(&o)
+ } else {
+ err_handler.handle_line(&o)
+ }
+ // out_handler.handle_info(&o);
+ }
+ },
+ code = child.wait() => {
+ let code = code?;
+ if !code.success() {
+ anyhow::bail!("command '{str}' failed with status {}", code);
+ }
+ break;
+ }
+ }
+ }
+
+ Ok(out_buf)
+}
+async fn run_nix_inner_raw_ssh(
+ str: String,
+ mut cmd: OwningCommand<Arc<Session>>,
+ want_stdout: bool,
+ err_handler: &mut dyn Handler,
+ mut out_handler: Option<&mut dyn Handler>,
+) -> Result<Option<Vec<u8>>> {
+ debug!("running command {str:?} over ssh");
+ cmd.stderr(openssh::Stdio::piped());
+ cmd.stdout(openssh::Stdio::piped());
+ let mut child = cmd.spawn().await?;
+ let mut stderr = child.stderr().take().unwrap();
+ let stdout = child.stdout().take().unwrap();
+ let mut err = FramedRead::new(&mut stderr, LinesCodec::new());
+ let mut out: Option<Box<dyn AsyncRead + Unpin>> = Some(Box::new(stdout));
+ let mut ob = want_stdout
+ .then(|| out.take().unwrap())
+ .unwrap_or_else(|| Box::new(EmptyAsyncRead));
+ let mut ol = (!want_stdout)
+ .then(|| out.take().unwrap())
+ .unwrap_or_else(|| Box::new(EmptyAsyncRead));
+ let mut ob = FramedRead::new(&mut ob, BytesCodec::new());
+ let mut ol = FramedRead::new(&mut ol, LinesCodec::new());
+
+ // while let Some(line) = read.next().await? {}
+
+ let mut out_buf = if want_stdout { Some(vec![]) } else { None };
+
+ let mut wait_future = pin::pin!(child.wait());
+ loop {
+ select! {
+ e = err.next() => {
+ if let Some(e) = e {
+ let e = e?;
+ err_handler.handle_line(&e);
+ }
+ },
+ o = ob.next() => {
+ if let Some(o) = o {
+ out_buf.as_mut().expect("stdout == wants_stdout").extend_from_slice(&o?);
+ }
+ },
+ o = ol.next() => {
+ if let Some(o) = o {
+ let o = o?;
+ if let Some(out) = out_handler.as_mut() {
+ out.handle_line(&o)
+ } else {
+ err_handler.handle_line(&o)
+ }
+ // out_handler.handle_info(&o);
+ }
+ },
+ code = &mut wait_future => {
+ let code = code?;
+ if !code.success() {
+ anyhow::bail!("command '{str}' failed with status {}", code);
+ }
+ break;
+ }
+ }
+ }
+
+ Ok(out_buf)
+}
crates/fleet-base/src/fleetdata.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/fleet-base/src/fleetdata.rs
@@ -0,0 +1,113 @@
+use std::{
+ collections::BTreeMap,
+ io::{self, Cursor},
+};
+
+use age::Recipient;
+use chrono::{DateTime, Utc};
+use fleet_shared::SecretData;
+use itertools::Itertools;
+use serde::{de::Error, Deserialize, Serialize};
+use serde_json::Value;
+
+#[derive(Serialize, Deserialize, Default)]
+#[serde(rename_all = "camelCase")]
+pub struct HostData {
+ #[serde(default)]
+ #[serde(skip_serializing_if = "String::is_empty")]
+ pub encryption_key: String,
+}
+
+const VERSION: &str = "0.1.0";
+pub struct FleetDataVersion;
+impl Serialize for FleetDataVersion {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ VERSION.serialize(serializer)
+ }
+}
+impl<'de> Deserialize<'de> for FleetDataVersion {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let version = String::deserialize(deserializer)?;
+ if version != VERSION {
+ return Err(D::Error::custom(format!(
+ "fleet.nix data version mismatch, expected {VERSION}, got {version}.\nFollow the docs for migration instruction"
+ )));
+ }
+ Ok(Self)
+ }
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct FleetData {
+ pub version: FleetDataVersion,
+
+ #[serde(default)]
+ pub hosts: BTreeMap<String, HostData>,
+ #[serde(default)]
+ #[serde(skip_serializing_if = "BTreeMap::is_empty")]
+ pub shared_secrets: BTreeMap<String, FleetSharedSecret>,
+ #[serde(default)]
+ #[serde(skip_serializing_if = "BTreeMap::is_empty")]
+ pub host_secrets: BTreeMap<String, BTreeMap<String, FleetSecret>>,
+
+ // extra_name => anything
+ #[serde(default)]
+ #[serde(skip_serializing_if = "BTreeMap::is_empty")]
+ pub extra: BTreeMap<String, Value>,
+}
+
+#[derive(Serialize, Deserialize, Clone)]
+#[serde(rename_all = "camelCase")]
+#[must_use]
+pub struct FleetSharedSecret {
+ pub owners: Vec<String>,
+ #[serde(flatten)]
+ pub secret: FleetSecret,
+}
+
+/// Returns None if recipients.is_empty()
+pub fn encrypt_secret_data(
+ recipients: impl IntoIterator<Item = impl Recipient + Send + 'static>,
+ data: Vec<u8>,
+) -> Option<SecretData> {
+ let mut encrypted = vec![];
+ let recipients = recipients
+ .into_iter()
+ .map(|v| Box::new(v) as Box<dyn Recipient + Send>)
+ .collect_vec();
+ let mut encryptor = age::Encryptor::with_recipients(recipients)?
+ .wrap_output(&mut encrypted)
+ .expect("in memory write");
+ io::copy(&mut Cursor::new(data), &mut encryptor).expect("in memory copy");
+ encryptor.finish().expect("in memory flush");
+ Some(SecretData {
+ data: encrypted,
+ encrypted: true,
+ })
+}
+
+#[derive(Serialize, Deserialize, Clone)]
+pub struct FleetSecretPart {
+ pub raw: SecretData,
+}
+
+#[derive(Serialize, Deserialize, Clone)]
+#[serde(rename_all = "camelCase")]
+#[must_use]
+pub struct FleetSecret {
+ #[serde(default = "Utc::now")]
+ pub created_at: DateTime<Utc>,
+ #[serde(default)]
+ #[serde(skip_serializing_if = "Option::is_none", alias = "expire_at")]
+ pub expires_at: Option<DateTime<Utc>>,
+
+ #[serde(flatten)]
+ pub parts: BTreeMap<String, FleetSecretPart>,
+}
crates/fleet-base/src/host.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/fleet-base/src/host.rs
@@ -0,0 +1,452 @@
+use std::{
+ cell::OnceCell,
+ ffi::{OsStr, OsString},
+ fmt::Display,
+ io::Write,
+ ops::Deref,
+ path::PathBuf,
+ str::FromStr,
+ sync::{Arc, Mutex, MutexGuard, OnceLock},
+};
+
+use anyhow::{anyhow, bail, ensure, Context, Result};
+use fleet_shared::SecretData;
+use nix_eval::{nix_go, nix_go_json, util::assert_warn, Value};
+use openssh::SessionBuilder;
+use serde::de::DeserializeOwned;
+use tempfile::NamedTempFile;
+
+use crate::{
+ command::MyCommand,
+ fleetdata::{FleetData, FleetSecret, FleetSharedSecret},
+};
+
+pub struct FleetConfigInternals {
+ pub local_system: String,
+ pub directory: PathBuf,
+ pub data: Mutex<FleetData>,
+ pub nix_args: Vec<OsString>,
+ /// fleet_config.config
+ pub config_field: Value,
+ // TODO: Remove with connectivity refactor
+ pub localhost: String,
+
+ /// import nixpkgs {system = local};
+ pub default_pkgs: Value,
+}
+
+// TODO: Make field not pub
+#[derive(Clone)]
+pub struct Config(pub Arc<FleetConfigInternals>);
+
+impl Deref for Config {
+ type Target = FleetConfigInternals;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+#[derive(Clone, Copy, Debug)]
+pub enum EscalationStrategy {
+ Sudo,
+ Run0,
+ Su,
+}
+
+pub struct ConfigHost {
+ config: Config,
+ pub name: String,
+ groups: OnceCell<Vec<String>>,
+
+ pub host_config: Option<Value>,
+ pub nixos_config: OnceCell<Value>,
+
+ // TODO: Move command helpers away with connectivity refactor
+ pub local: bool,
+ pub session: OnceLock<Arc<openssh::Session>>,
+}
+// TODO: Move command helpers away with connectivity refactor
+impl ConfigHost {
+ pub async fn escalation_strategy(&self) -> Result<EscalationStrategy> {
+ // Prefer sudo, as run0 has some gotchas with polkit
+ // and too many repeating prompts.
+ if (self.find_in_path("sudo").await).is_ok() {
+ return Ok(EscalationStrategy::Sudo);
+ }
+ if (self.find_in_path("run0").await).is_ok() {
+ return Ok(EscalationStrategy::Run0);
+ }
+ Ok(EscalationStrategy::Su)
+ }
+ async fn open_session(&self) -> Result<Arc<openssh::Session>> {
+ assert!(!self.local, "do not open ssh connection to local session");
+ // FIXME: TOCTOU
+ if let Some(session) = &self.session.get() {
+ return Ok((*session).clone());
+ };
+ let session = SessionBuilder::default();
+ let session = session
+ .connect(&self.name)
+ .await
+ .map_err(|e| anyhow!("ssh error while connecting to {}: {e}", self.name))?;
+ let session = Arc::new(session);
+ self.session.set(session.clone()).expect("TOCTOU happened");
+ Ok(session)
+ }
+ pub async fn mktemp_dir(&self) -> Result<String> {
+ let mut cmd = self.cmd("mktemp").await?;
+ cmd.arg("-d");
+ let path = cmd.run_string().await?;
+ Ok(path.trim_end().to_owned())
+ }
+ pub async fn read_file_bin(&self, path: impl AsRef<OsStr>) -> Result<Vec<u8>> {
+ let mut cmd = self.cmd("cat").await?;
+ cmd.arg(path);
+ cmd.run_bytes().await
+ }
+ pub async fn read_file_text(&self, path: impl AsRef<OsStr>) -> Result<String> {
+ let mut cmd = self.cmd("cat").await?;
+ cmd.arg(path);
+ cmd.run_string().await
+ }
+ pub async fn read_dir(&self, path: impl AsRef<OsStr>) -> Result<Vec<String>> {
+ let mut cmd = self.cmd("ls").await?;
+ cmd.arg(path);
+ let out = cmd.run_string().await?;
+ let mut lines = out.split('\n');
+ if let Some(last) = lines.next_back() {
+ ensure!(last.is_empty(), "output of ls should end with newline");
+ }
+ Ok(lines.map(ToOwned::to_owned).collect())
+ }
+ #[allow(dead_code)]
+ pub async fn read_file_json<D: DeserializeOwned>(&self, path: impl AsRef<OsStr>) -> Result<D> {
+ let text = self.read_file_text(path).await?;
+ Ok(serde_json::from_str(&text)?)
+ }
+ pub async fn read_env(&self, env: &str) -> Result<String> {
+ let mut cmd = self.cmd("printenv").await?;
+ cmd.arg(env);
+ cmd.run_string().await
+ }
+ pub async fn find_in_path(&self, command: &str) -> Result<String> {
+ // // `which` is not a part of coreutils, and it might not exist on machine.
+ // let path = self.read_env("PATH").await?;
+ // // Assuming delimiter is :, we don't work with windows host, this check will be much
+ // // more sophisticated in remowt backend (and quicker, since actual PATH search will be done on remote machine)
+ // for ele in path.split(':') {
+ // let test_path = format!("{ele}/{cmd}");
+ // test -x etc
+ // }
+ // let mut cmd = self.cmd("printenv").await?;
+ // cmd.arg(env);
+ // Ok(cmd.run_string().await?)
+ // Assuming this is an environment issue if which doesn't exist, will be fixed with remowt.
+ let mut cmd = self
+ .cmd_escalation(
+ // Not used
+ EscalationStrategy::Su,
+ "which",
+ )
+ .await?;
+ cmd.arg(command);
+ cmd.run_string().await
+ }
+ pub async fn read_file_value<D: FromStr>(&self, path: impl AsRef<OsStr>) -> Result<D>
+ where
+ <D as FromStr>::Err: Display,
+ {
+ let text = self.read_file_text(path).await?;
+ D::from_str(&text).map_err(|e| anyhow!("failed to parse value: {e}"))
+ }
+ pub async fn cmd(&self, cmd: impl AsRef<OsStr>) -> Result<MyCommand> {
+ self.cmd_escalation(self.escalation_strategy().await?, cmd)
+ .await
+ }
+ pub async fn cmd_escalation(
+ &self,
+ escalation: EscalationStrategy,
+ cmd: impl AsRef<OsStr>,
+ ) -> Result<MyCommand> {
+ if self.local {
+ Ok(MyCommand::new(escalation, cmd))
+ } else {
+ let session = self.open_session().await?;
+ Ok(MyCommand::new_on(escalation, cmd, session))
+ }
+ }
+
+ pub async fn decrypt(&self, data: SecretData) -> Result<Vec<u8>> {
+ ensure!(data.encrypted, "secret is not encrypted");
+ let mut cmd = self.cmd("fleet-install-secrets").await?;
+ cmd.arg("decrypt").eqarg("--secret", data.to_string());
+ let encoded = cmd
+ .sudo()
+ .run_string()
+ .await
+ .context("failed to call remote host for decrypt")?;
+ let data: SecretData = encoded.parse().map_err(|e| anyhow!("{e}"))?;
+ ensure!(!data.encrypted, "secret came out encrypted");
+ Ok(data.data)
+ }
+ pub async fn reencrypt(&self, data: SecretData, targets: Vec<String>) -> 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());
+ for target in targets {
+ let key = self.config.key(&target).await?;
+ cmd.eqarg("--targets", key);
+ }
+ let encoded = cmd
+ .sudo()
+ .run_string()
+ .await
+ .context("failed to call remote host for decrypt")?;
+ let data: SecretData = encoded.parse().map_err(|e| anyhow!("{e}"))?;
+ ensure!(data.encrypted, "secret came out not encrypted");
+ Ok(data)
+ }
+ /// Returns path for futureproofing, as path might change i.e on conversion to CA
+ pub async fn remote_derivation(&self, path: &PathBuf) -> Result<PathBuf> {
+ if self.local {
+ // Path is located locally, thus already trusted.
+ return Ok(path.to_owned());
+ }
+ let mut nix = MyCommand::new(
+ // Not used
+ EscalationStrategy::Su,
+ "nix",
+ );
+ nix.arg("copy")
+ .arg("--substitute-on-destination")
+ .comparg("--to", format!("ssh-ng://{}", self.name))
+ .arg(path);
+ nix.run_nix().await.context("nix copy")?;
+ Ok(path.to_owned())
+ }
+ pub async fn systemctl_stop(&self, name: &str) -> Result<()> {
+ let mut cmd = self.cmd("systemctl").await?;
+ cmd.arg("stop").arg(name);
+ cmd.sudo().run().await
+ }
+ pub async fn systemctl_start(&self, name: &str) -> Result<()> {
+ let mut cmd = self.cmd("systemctl").await?;
+ cmd.arg("start").arg(name);
+ cmd.sudo().run().await
+ }
+
+ pub async fn rm_file(&self, path: impl AsRef<OsStr>, sudo: bool) -> Result<()> {
+ let mut cmd = self.cmd("rm").await?;
+ cmd.arg("-f").arg(path);
+ if sudo {
+ cmd = cmd.sudo()
+ }
+ cmd.run().await
+ }
+}
+impl ConfigHost {
+ // TOCTOU is possible here in case if config is changed, but this case is not handled anywhere anyway,
+ // assuming getting tags always returns the same value.
+ pub async fn tags(&self) -> Result<Vec<String>> {
+ if let Some(v) = self.groups.get() {
+ return Ok(v.clone());
+ }
+ let Some(host_config) = &self.host_config else {
+ return Ok(vec![]);
+ };
+ let tags: Vec<String> = nix_go_json!(host_config.tags);
+
+ let _ = self.groups.set(tags.clone());
+
+ Ok(tags)
+ }
+ pub async fn nixos_config(&self) -> Result<Value> {
+ if let Some(v) = self.nixos_config.get() {
+ return Ok(v.clone());
+ }
+ let Some(host_config) = &self.host_config else {
+ bail!("local host has no nixos_config");
+ };
+ let nixos_config = nix_go!(host_config.nixos.config);
+ assert_warn("nixos config evaluation", &nixos_config).await?;
+
+ let _ = self.nixos_config.set(nixos_config.clone());
+
+ Ok(nixos_config)
+ }
+
+ pub async fn list_configured_secrets(&self) -> Result<Vec<String>> {
+ let nixos = self.nixos_config().await?;
+ let secrets = nix_go!(nixos.secrets);
+ let mut out = Vec::new();
+ for name in secrets.list_fields().await? {
+ let secret = nix_go!(secrets[{ name }]);
+ let is_shared: bool = nix_go_json!(secret.shared);
+ if is_shared {
+ continue;
+ }
+ out.push(name);
+ }
+ Ok(out)
+ }
+ pub async fn secret_field(&self, name: &str) -> Result<Value> {
+ let nixos = self.nixos_config().await?;
+ Ok(nix_go!(nixos.secrets[{ name }]))
+ }
+
+ /// Packages for this host, resolved with nixpkgs overlays
+ pub async fn pkgs(&self) -> Result<Value> {
+ let Some(host_config) = &self.host_config else {
+ bail!("local host has no host_config");
+ };
+ // TODO: Should nixos.options be cached?
+ Ok(nix_go!(host_config.nixos.options._module.args.value.pkgs))
+ }
+}
+
+impl Config {
+ pub fn local_host(&self) -> ConfigHost {
+ ConfigHost {
+ config: self.clone(),
+ name: "<virtual localhost>".to_owned(),
+ local: true,
+ session: OnceLock::new(),
+ host_config: None,
+ nixos_config: OnceCell::new(),
+ groups: {
+ let cell = OnceCell::new();
+ let _ = cell.set(vec![]);
+ cell
+ },
+ }
+ }
+
+ pub async fn host(&self, name: &str) -> Result<ConfigHost> {
+ let config = &self.config_field;
+ let host_config = nix_go!(config.hosts[{ name }]);
+
+ Ok(ConfigHost {
+ config: self.clone(),
+ name: name.to_owned(),
+ host_config: Some(host_config),
+ nixos_config: OnceCell::new(),
+ groups: OnceCell::new(),
+
+ // TODO: Remove with connectivit refactor
+ local: self.localhost == name,
+ session: OnceLock::new(),
+ })
+ }
+ pub async fn list_hosts(&self) -> Result<Vec<ConfigHost>> {
+ let config = &self.config_field;
+ let names = nix_go!(config.hosts).list_fields().await?;
+ let mut out = vec![];
+ for name in names {
+ out.push(self.host(&name).await?);
+ }
+ Ok(out)
+ }
+ // TODO: Replace usages with .host().nixos_config
+ pub async 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 async fn list_configured_shared(&self) -> Result<Vec<String>> {
+ let config_field = &self.config_field;
+ Ok(nix_go!(config_field.sharedSecrets).list_fields().await?)
+ }
+ /// Shared secrets configured in fleet.nix
+ pub fn list_shared(&self) -> Vec<String> {
+ let data = self.data();
+ data.shared_secrets.keys().cloned().collect()
+ }
+ pub fn has_shared(&self, name: &str) -> bool {
+ let data = self.data();
+ data.shared_secrets.contains_key(name)
+ }
+ pub fn replace_shared(&self, name: String, shared: FleetSharedSecret) {
+ let mut data = self.data_mut();
+ data.shared_secrets.insert(name.to_owned(), shared);
+ }
+ pub fn remove_shared(&self, secret: &str) {
+ let mut data = self.data_mut();
+ data.shared_secrets.remove(secret);
+ }
+
+ pub fn list_secrets(&self, host: &str) -> Vec<String> {
+ let data = self.data();
+ let Some(secrets) = data.host_secrets.get(host) else {
+ return Vec::new();
+ };
+ secrets.keys().cloned().collect()
+ }
+
+ pub fn has_secret(&self, host: &str, secret: &str) -> bool {
+ let data = self.data();
+ let Some(host_secrets) = data.host_secrets.get(host) else {
+ return false;
+ };
+ host_secrets.contains_key(secret)
+ }
+ pub fn insert_secret(&self, host: &str, secret: String, value: FleetSecret) {
+ let mut data = self.data_mut();
+ let host_secrets = data.host_secrets.entry(host.to_owned()).or_default();
+ host_secrets.insert(secret, value);
+ }
+
+ pub fn host_secret(&self, host: &str, secret: &str) -> Result<FleetSecret> {
+ let data = self.data();
+ let Some(host_secrets) = data.host_secrets.get(host) else {
+ bail!("no secrets for machine {host}");
+ };
+ let Some(secret) = host_secrets.get(secret) else {
+ bail!("machine {host} has no secret {secret}");
+ };
+ Ok(secret.clone())
+ }
+ pub fn shared_secret(&self, secret: &str) -> Result<FleetSharedSecret> {
+ let data = self.data();
+ let Some(secret) = data.shared_secrets.get(secret) else {
+ bail!("no shared secret {secret}");
+ };
+ Ok(secret.clone())
+ }
+ pub async fn shared_secret_expected_owners(&self, secret: &str) -> Result<Vec<String>> {
+ let config_field = &self.config_field;
+ Ok(nix_go_json!(
+ config_field.sharedSecrets[{ secret }].expectedOwners
+ ))
+ }
+
+ // 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)?;
+ tempfile.write_all(
+ format!(
+ "# This file contains fleet state and shouldn't be edited by hand\n\n{}\n\n# vim: ts=2 et nowrap\n",
+ data
+ )
+ .as_bytes(),
+ )?;
+ let mut fleet_data_path = self.directory.clone();
+ fleet_data_path.push("fleet.nix");
+ tempfile.persist(fleet_data_path)?;
+ Ok(())
+ }
+}
crates/fleet-base/src/keys.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/fleet-base/src/keys.rs
@@ -0,0 +1,77 @@
+use std::str::FromStr as _;
+
+use age::Recipient;
+use anyhow::{anyhow, Result};
+use futures::{StreamExt as _, TryStreamExt as _};
+use itertools::Itertools as _;
+use tracing::warn;
+
+use crate::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);
+ if let Some(key) = key {
+ if key.is_empty() {
+ return None;
+ }
+ }
+ 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();
+ 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) {
+ Ok(key)
+ } else {
+ warn!("Loading key for {}", host);
+ let host = self.host(host).await?;
+ let mut cmd = host.cmd("cat").await?;
+ cmd.arg("/etc/ssh/ssh_host_ed25519_key.pub");
+ let key = cmd.run_string().await?;
+ self.update_key(&host.name, key.clone());
+ Ok(key)
+ }
+ }
+ /// Insecure, requires root
+ pub async fn recipient(&self, host: &str) -> anyhow::Result<impl Recipient> {
+ let key = self.key(host).await?;
+ age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))
+ }
+
+ pub async fn recipients(&self, hosts: Vec<String>) -> Result<Vec<impl Recipient>> {
+ futures::stream::iter(hosts.iter())
+ .then(|m| self.recipient(m.as_ref()))
+ .try_collect::<Vec<_>>()
+ .await
+ }
+
+ #[allow(dead_code)]
+ pub async fn orphaned_data(&self) -> Result<Vec<String>> {
+ let mut out = Vec::new();
+ let host_names = self
+ .list_hosts()
+ .await?
+ .into_iter()
+ .map(|h| h.name)
+ .collect_vec();
+ for hostname in self
+ .data()
+ .hosts
+ .iter()
+ .filter(|(_, host)| !host.encryption_key.is_empty())
+ .map(|(n, _)| n)
+ {
+ if !host_names.contains(hostname) {
+ out.push(hostname.to_owned())
+ }
+ }
+
+ Ok(out)
+ }
+}
crates/fleet-base/src/lib.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/fleet-base/src/lib.rs
@@ -0,0 +1,5 @@
+pub mod fleetdata;
+pub mod host;
+pub mod command;
+pub mod opts;
+mod keys;
crates/fleet-base/src/opts.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/fleet-base/src/opts.rs
@@ -0,0 +1,216 @@
+use std::{
+ collections::BTreeMap,
+ env::current_dir,
+ ffi::OsString,
+ str::FromStr,
+ sync::{Arc, Mutex},
+};
+
+use anyhow::Result;
+use clap::Parser;
+use nix_eval::{nix_go, nix_go_json, util::assert_warn, NixSessionPool, Value};
+use nom::{
+ bytes::complete::take_while1,
+ character::complete::char,
+ combinator::{map, opt},
+ multi::separated_list1,
+ sequence::{preceded, separated_pair},
+};
+
+use crate::{
+ fleetdata::FleetData,
+ host::{Config, ConfigHost, FleetConfigInternals},
+};
+
+#[derive(Clone)]
+pub enum HostItem {
+ Host {
+ name: String,
+ attrs: BTreeMap<String, String>,
+ },
+ Tag {
+ name: String,
+ attrs: BTreeMap<String, String>,
+ },
+}
+fn host_item_parser(input: &str) -> Result<HostItem, String> {
+ fn err_to_string(err: nom::Err<nom::error::Error<&str>>) -> String {
+ err.to_string()
+ }
+
+ let (input, is_tag) = map(opt(char('@')), |c| c.is_some())(input).map_err(err_to_string)?;
+ let (input, name) = map(
+ take_while1(|v| v != ',' && v != '?' && v != '@'),
+ str::to_owned,
+ )(input)
+ .map_err(err_to_string)?;
+
+ let kw_item = separated_pair(
+ map(take_while1(|v| v != '&' && v != '='), str::to_owned),
+ char('='),
+ map(take_while1(|v| v != '&'), str::to_owned),
+ );
+ let kw = map(separated_list1(char('&'), kw_item), |vec| {
+ vec.into_iter().collect::<BTreeMap<_, _>>()
+ });
+ let mut opt_kw = map(opt(preceded(char('?'), kw)), Option::unwrap_or_default);
+
+ let (input, attrs) = opt_kw(input).map_err(err_to_string)?;
+
+ if !input.is_empty() {
+ return Err(format!("unexpected trailing input: {input:?}"));
+ }
+ Ok(if is_tag {
+ HostItem::Tag { name, attrs }
+ } else {
+ HostItem::Host { name, attrs }
+ })
+}
+
+// TODO: Rename to HostSelector
+#[derive(Parser, Clone)]
+pub struct FleetOpts {
+ /// All hosts except those would be skipped
+ #[clap(long, number_of_values = 1, value_parser = host_item_parser)]
+ pub only: Vec<HostItem>,
+
+ /// Hosts to skip
+ #[clap(long, number_of_values = 1)]
+ pub skip: Vec<String>,
+
+ /// Host, which should be threaten as current machine
+ // TODO: Replace with connectivity refactor
+ #[clap(long, default_value_t = hostname::get().expect("unknown hostname").to_str().expect("hostname is not utf-8").to_owned())]
+ pub localhost: String,
+
+ /// Override detected system for host, to perform builds via
+ /// binfmt-declared qemu instead of trying to crosscompile
+ // TODO: Remove, as it is not used anymore.
+ #[clap(long, default_value = "detect")]
+ pub local_system: String,
+}
+
+impl FleetOpts {
+ pub async fn should_skip(&self, host: &ConfigHost) -> Result<bool> {
+ if self.skip.iter().any(|h| h as &str == host.name) {
+ return Ok(true);
+ }
+ if self.only.is_empty() {
+ return Ok(false);
+ }
+ let mut have_group_matches = false;
+ for item in self.only.iter() {
+ match item {
+ HostItem::Host { name, .. } if *name == host.name => {
+ return Ok(false);
+ }
+ HostItem::Tag { .. } => {
+ have_group_matches = true;
+ }
+ _ => {}
+ }
+ }
+ if have_group_matches {
+ let host_tags = host.tags().await?;
+ for item in self.only.iter() {
+ match item {
+ HostItem::Tag { name, .. } if host_tags.contains(name) => {
+ return Ok(false);
+ }
+ _ => {}
+ }
+ }
+ }
+ Ok(true)
+ }
+ pub async fn action_attr<T: FromStr>(&self, host: &ConfigHost, attr: &str) -> Result<Option<T>>
+ where
+ T::Err: Sync,
+ anyhow::Error: From<T::Err>,
+ {
+ let str = self.action_attr_str(host, attr).await?;
+ Ok(str.map(|v| T::from_str(&v)).transpose()?)
+ }
+ pub async fn action_attr_str(&self, host: &ConfigHost, attr: &str) -> Result<Option<String>> {
+ if self.only.is_empty() {
+ return Ok(None);
+ }
+ let mut have_group_matches = false;
+ for item in self.only.iter() {
+ match item {
+ HostItem::Host { name, attrs }
+ if *name == host.name && attrs.contains_key(attr) =>
+ {
+ return Ok(attrs.get(attr).cloned());
+ }
+ HostItem::Tag { attrs, .. } if attrs.contains_key(attr) => {
+ have_group_matches = true;
+ }
+ _ => {}
+ }
+ }
+ if have_group_matches {
+ let host_tags = host.tags().await?;
+ for item in self.only.iter() {
+ match item {
+ HostItem::Tag { name, attrs }
+ if host_tags.contains(name) && attrs.contains_key(attr) =>
+ {
+ return Ok(attrs.get(attr).cloned());
+ }
+ _ => {}
+ }
+ }
+ }
+ Ok(None)
+ }
+ pub fn is_local(&self, host: &str) -> bool {
+ self.localhost == host
+ }
+
+ // TODO: Config should be detached from opts.
+ pub async fn build(&self, nix_args: Vec<OsString>) -> Result<Config> {
+ let directory = current_dir()?;
+
+ let pool = NixSessionPool::new(directory.as_os_str().to_owned(), nix_args.clone()).await?;
+ let root_field = pool.get().await?;
+
+ let builtins_field = Value::binding(root_field.clone(), "builtins").await?;
+ let local_system = if self.local_system == "detect" {
+ nix_go_json!(builtins_field.currentSystem)
+ } else {
+ self.local_system.clone()
+ };
+
+ let mut fleet_data_path = directory.clone();
+ fleet_data_path.push("fleet.nix");
+ let bytes = std::fs::read_to_string(fleet_data_path)?;
+ let data: Mutex<FleetData> = nixlike::parse_str(&bytes)?;
+
+ let fleet_root = Value::binding(root_field, "fleetConfigurations").await?;
+ let fleet_field = nix_go!(fleet_root.default({ data }));
+
+ let config_field = nix_go!(fleet_field.config);
+
+ assert_warn("fleet config evaluation", &config_field).await?;
+
+ let import = nix_go!(builtins_field.import);
+ let overlays = nix_go!(config_field.nixpkgs.overlays);
+ let nixpkgs = nix_go!(fleet_field.nixpkgs.buildUsing | import);
+
+ let default_pkgs = nix_go!(nixpkgs(Obj {
+ overlays,
+ system: { self.local_system.clone() },
+ }));
+
+ Ok(Config(Arc::new(FleetConfigInternals {
+ directory,
+ data,
+ local_system,
+ nix_args,
+ config_field,
+ default_pkgs,
+ localhost: self.localhost.to_owned(),
+ })))
+ }
+}
crates/fleet-shared/src/encoding.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/fleet-shared/src/encoding.rs
@@ -0,0 +1,156 @@
+use std::{
+ fmt::{self, Display},
+ str::FromStr,
+};
+
+use base64::engine::{general_purpose::STANDARD_NO_PAD, Engine};
+use serde::{de::Error, Deserialize, Deserializer, Serialize};
+use unicode_categories::UnicodeCategories;
+
+#[derive(Debug, PartialEq, Clone)]
+pub struct SecretData {
+ pub data: Vec<u8>,
+ pub encrypted: bool,
+}
+
+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>";
+
+const SECRET_PREFIX: &str = "<ENCRYPTED>";
+
+impl<'de> Deserialize<'de> for SecretData {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let string = String::deserialize(deserializer)?;
+ string.parse().map_err(D::Error::custom)
+ }
+}
+
+impl Serialize for SecretData {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ self.to_string().serialize(serializer)
+ }
+}
+
+impl FromStr for SecretData {
+ type Err = String;
+
+ fn from_str(string: &str) -> Result<Self, Self::Err> {
+ let (encrypted, string) = if let Some(unprefixed) = string.strip_prefix(SECRET_PREFIX) {
+ (true, unprefixed)
+ } else {
+ (false, string)
+ };
+ let data = if let Some(unprefixed) = string.strip_prefix(BASE64_ENCODED_PREFIX) {
+ STANDARD_NO_PAD
+ .decode(unprefixed.replace(|v| matches!(v, '\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(|v| matches!(v, '\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}"
+ ));
+ };
+ Ok(Self { data, encrypted })
+ }
+}
+
+impl Display for SecretData {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let mut readable = std::str::from_utf8(&self.data).ok();
+ if self.encrypted {
+ write!(f, "{SECRET_PREFIX}")?;
+ // Always base64-encode encrypted fields.
+ readable = None;
+ }
+ if Some(false) == readable.map(is_printable) {
+ readable = None
+ };
+ // TODO: Check if text is readable, and has no unprintable characters?..
+ if let Some(plaintext) = readable {
+ if plaintext.ends_with('\n') {
+ write!(f, "{PLAINTEXT_NEWLINE_PREFIX}")?;
+ } else {
+ write!(f, "{PLAINTEXT_PREFIX}")?;
+ }
+ write!(f, "{plaintext}")?;
+ } else {
+ write!(f, "{BASE64_ENCODED_PREFIX}")?;
+ let encoded = STANDARD_NO_PAD.encode(&self.data);
+ for ele in encoded.as_bytes().chunks(64) {
+ let chunk = std::str::from_utf8(ele).expect(
+ "any slice of base64-encoded text is utf-8 compatible, as it is ascii-based",
+ );
+ writeln!(f, "{chunk}")?;
+ }
+ };
+ Ok(())
+ }
+}
+
+fn is_printable(text: &str) -> bool {
+ text.chars().all(|c| {
+ c.is_letter()
+ || c.is_mark()
+ || c.is_number()
+ || c.is_punctuation()
+ || c.is_separator()
+ || c == '\n' || c == '\t'
+ // Complete base64 alphabet
+ || c == '/' || c == '+'
+ || c == '='
+ })
+}
+
+#[test]
+fn test() {
+ fn check_roundtrip(data: SecretData, expected: &str) {
+ let string = data.to_string();
+ assert_eq!(string, expected, "unexpected encoding");
+ let roundtrip: SecretData = string.parse().expect("roundtrip parse");
+ assert_eq!(data, roundtrip, "roundtrip didn't match");
+ }
+ check_roundtrip(
+ SecretData {
+ data: vec![1, 2, 3, 4, 5, 6],
+ encrypted: false,
+ },
+ "<BASE64-ENCODED>\nAQIDBAUG\n",
+ );
+ check_roundtrip(
+ SecretData {
+ data: vec![1, 2, 3, 4, 5, 6],
+ encrypted: true,
+ },
+ "<ENCRYPTED><BASE64-ENCODED>\nAQIDBAUG\n",
+ );
+ check_roundtrip(
+ SecretData {
+ data: "Привет, мир!\n".to_owned().into(),
+ encrypted: false,
+ },
+ "<PLAINTEXT-NL>\nПривет, мир!\n",
+ );
+ check_roundtrip(
+ SecretData {
+ data: "Привет, мир!".to_owned().into(),
+ encrypted: false,
+ },
+ "<PLAINTEXT>Привет, мир!",
+ );
+}
crates/fleet-shared/src/lib.rsdiffbeforeafterboth--- a/crates/fleet-shared/src/lib.rs
+++ b/crates/fleet-shared/src/lib.rs
@@ -1,156 +1,2 @@
-use std::{
- fmt::{self, Display},
- str::FromStr,
-};
-
-use base64::engine::{general_purpose::STANDARD_NO_PAD, Engine};
-use serde::{de::Error, Deserialize, Deserializer, Serialize};
-use unicode_categories::UnicodeCategories;
-
-#[derive(Debug, PartialEq, Clone)]
-pub struct SecretData {
- pub data: Vec<u8>,
- pub encrypted: bool,
-}
-
-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>";
-
-const SECRET_PREFIX: &str = "<ENCRYPTED>";
-
-impl<'de> Deserialize<'de> for SecretData {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- let string = String::deserialize(deserializer)?;
- string.parse().map_err(D::Error::custom)
- }
-}
-
-impl Serialize for SecretData {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: serde::Serializer,
- {
- self.to_string().serialize(serializer)
- }
-}
-
-impl FromStr for SecretData {
- type Err = String;
-
- fn from_str(string: &str) -> Result<Self, Self::Err> {
- let (encrypted, string) = if let Some(unprefixed) = string.strip_prefix(SECRET_PREFIX) {
- (true, unprefixed)
- } else {
- (false, string)
- };
- let data = if let Some(unprefixed) = string.strip_prefix(BASE64_ENCODED_PREFIX) {
- STANDARD_NO_PAD
- .decode(unprefixed.replace(|v| matches!(v, '\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(|v| matches!(v, '\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}"
- ));
- };
- Ok(Self { data, encrypted })
- }
-}
-
-impl Display for SecretData {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let mut readable = std::str::from_utf8(&self.data).ok();
- if self.encrypted {
- write!(f, "{SECRET_PREFIX}")?;
- // Always base64-encode encrypted fields.
- readable = None;
- }
- if Some(false) == readable.map(is_printable) {
- readable = None
- };
- // TODO: Check if text is readable, and has no unprintable characters?..
- if let Some(plaintext) = readable {
- if plaintext.ends_with('\n') {
- write!(f, "{PLAINTEXT_NEWLINE_PREFIX}")?;
- } else {
- write!(f, "{PLAINTEXT_PREFIX}")?;
- }
- write!(f, "{plaintext}")?;
- } else {
- write!(f, "{BASE64_ENCODED_PREFIX}")?;
- let encoded = STANDARD_NO_PAD.encode(&self.data);
- for ele in encoded.as_bytes().chunks(64) {
- let chunk = std::str::from_utf8(ele).expect(
- "any slice of base64-encoded text is utf-8 compatible, as it is ascii-based",
- );
- writeln!(f, "{chunk}")?;
- }
- };
- Ok(())
- }
-}
-
-fn is_printable(text: &str) -> bool {
- text.chars().all(|c| {
- c.is_letter()
- || c.is_mark()
- || c.is_number()
- || c.is_punctuation()
- || c.is_separator()
- || c == '\n' || c == '\t'
- // Complete base64 alphabet
- || c == '/' || c == '+'
- || c == '='
- })
-}
-
-#[test]
-fn test() {
- fn check_roundtrip(data: SecretData, expected: &str) {
- let string = data.to_string();
- assert_eq!(string, expected, "unexpected encoding");
- let roundtrip: SecretData = string.parse().expect("roundtrip parse");
- assert_eq!(data, roundtrip, "roundtrip didn't match");
- }
- check_roundtrip(
- SecretData {
- data: vec![1, 2, 3, 4, 5, 6],
- encrypted: false,
- },
- "<BASE64-ENCODED>\nAQIDBAUG\n",
- );
- check_roundtrip(
- SecretData {
- data: vec![1, 2, 3, 4, 5, 6],
- encrypted: true,
- },
- "<ENCRYPTED><BASE64-ENCODED>\nAQIDBAUG\n",
- );
- check_roundtrip(
- SecretData {
- data: "Привет, мир!\n".to_owned().into(),
- encrypted: false,
- },
- "<PLAINTEXT-NL>\nПривет, мир!\n",
- );
- check_roundtrip(
- SecretData {
- data: "Привет, мир!".to_owned().into(),
- encrypted: false,
- },
- "<PLAINTEXT>Привет, мир!",
- );
-}
+mod encoding;
+pub use encoding::SecretData;
crates/nix-eval/src/session.rsdiffbeforeafterboth--- a/crates/nix-eval/src/session.rs
+++ b/crates/nix-eval/src/session.rs
@@ -12,7 +12,7 @@
sync::{mpsc, oneshot, Mutex},
};
use tokio_util::codec::{FramedRead, LinesCodec};
-use tracing::{debug, error, info, warn, Level};
+use tracing::{debug, error, warn, Level};
#[derive(Error, Debug)]
pub enum Error {
@@ -147,8 +147,7 @@
// s.split('\n').filter(|s| !s.trim().is_empty()).map(|v| v.)
// }
if !self.collected.is_empty() {
- return Err(Error::NixError(format!(
- "{}",
+ return Err(Error::NixError(
self.collected
.iter()
.map(|v| {
@@ -159,8 +158,9 @@
v.to_owned()
}
})
- .join("\n"),
- )));
+ .join("\n")
+ .to_string(),
+ ));
}
Ok(())
}
@@ -316,7 +316,7 @@
}
out.push_str(&line);
}
- return Err(Error::MissingDelimiter);
+ Err(Error::MissingDelimiter)
}
pub(crate) async fn execute_expression_number(
&mut self,
@@ -347,9 +347,10 @@
let mut fexpr = b"builtins.toJSON (".to_vec();
fexpr.extend_from_slice(expr.as_ref());
fexpr.push(b')');
- let s = String::from_utf8_lossy(expr.as_ref());
- let v = self.execute_expression_string(fexpr).await?;
- Ok(serde_json::from_str(&v)?)
+
+ Ok(serde_json::from_str(
+ &self.execute_expression_string(fexpr).await?,
+ )?)
}
async fn execute_expression_wrapping(
&mut self,
crates/remowt-fs/Cargo.tomldiffbeforeafterboth--- a/crates/remowt-fs/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "remowt-fs"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
crates/remowt-fs/src/lib.rsdiffbeforeafterboth--- a/crates/remowt-fs/src/lib.rs
+++ /dev/null
@@ -1 +0,0 @@
-trait RemowtFS {}
flake.nixdiffbeforeafterboth--- a/flake.nix
+++ b/flake.nix
@@ -116,6 +116,7 @@
bacon
nil
];
+ env.PROTOC = "${pkgs.protobuf}/bin/protoc";
};
};
# fleet-install-secrets will not be built normally, because they are not ran directly by user most of the time.
modules/extras/tf.nixdiffbeforeafterboth--- a/modules/extras/tf.nix
+++ b/modules/extras/tf.nix
@@ -1,26 +1,45 @@
{
config,
lib,
+ fleetLib,
inputs,
...
}: let
- inherit (lib) mkOption;
- inherit (lib.types) deferredModule;
+ inherit (lib.options) mkOption;
+ inherit (lib.types) deferredModule attrsOf unspecified;
+ inherit (fleetLib.options) mkDataOption;
in {
- options.tf = mkOption {
- type = deferredModule;
- apply = module: system:
- inputs.terranix.lib.terranixConfigurationAst {
- inherit system;
- pkgs = config.nixpkgs.buildUsing.legacyPackages.${system};
- modules = [module];
+ options = {
+ tf = mkOption {
+ type = deferredModule;
+ apply = module: system:
+ inputs.terranix.lib.terranixConfiguration {
+ inherit system;
+ pkgs = config.nixpkgs.buildUsing.legacyPackages.${system};
+ modules = [
+ module
+ ];
+ };
+ };
+ data = mkDataOption {
+ # host => hostData
+ options.extra.terraformHosts = mkOption {
+ default = {};
+ type = attrsOf (attrsOf unspecified);
+ description = "Hosts data provided by fleet tf";
};
+ };
};
- config.tf.output.fleet = {
- value = {
- managed = true;
+
+ config = {
+ tf.output.fleet = {
+ value = {
+ managed = true;
+ };
+ # Just to avoid printing this attribute on every apply, the whole fleet attribute
+ # will be somehow processed by fleet tf.
+ sensitive = true;
};
- # Just to avoid printing this attribute on every apply.
- sensitive = true;
+ hosts = config.data.extra.terraformHosts;
};
}
modules/secrets-data.nixdiffbeforeafterboth--- a/modules/secrets-data.nix
+++ b/modules/secrets-data.nix
@@ -6,8 +6,8 @@
}: let
inherit (fleetLib.options) mkDataOption;
inherit (lib.options) mkOption;
- inherit (lib.types) lazyAttrsOf nullOr listOf str attrsOf submodule bool;
- inherit (lib.attrsets) mapAttrsToList mapAttrs catAttrs filterAttrs genAttrs;
+ inherit (lib.types) nullOr listOf str attrsOf submodule bool;
+ inherit (lib.attrsets) mapAttrsToList mapAttrs filterAttrs genAttrs;
inherit (lib.lists) sort unique concatLists;
inherit (lib.strings) toJSON;