git.delta.rocks / jrsonnet / refs/commits / d0d2d550883b

difftreelog

refactor temporarly break cross, but greatly cleanup data

Yaroslav Bolyukin2023-12-31parent: #7c6930a.patch.diff
in: trunk

16 files changed

modifiedCargo.lockdiffbeforeafterboth
117117
118[[package]]118[[package]]
119name = "aho-corasick"119name = "aho-corasick"
120version = "1.1.1"120version = "1.1.2"
121source = "registry+https://github.com/rust-lang/crates.io-index"121source = "registry+https://github.com/rust-lang/crates.io-index"
122checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"122checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
123dependencies = [123dependencies = [
124 "memchr",124 "memchr",
125]125]
170170
171[[package]]171[[package]]
172name = "anstream"172name = "anstream"
173version = "0.6.4"173version = "0.6.5"
174source = "registry+https://github.com/rust-lang/crates.io-index"174source = "registry+https://github.com/rust-lang/crates.io-index"
175checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"175checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6"
176dependencies = [176dependencies = [
177 "anstyle",177 "anstyle",
178 "anstyle-parse",178 "anstyle-parse",
190190
191[[package]]191[[package]]
192name = "anstyle-parse"192name = "anstyle-parse"
193version = "0.2.2"193version = "0.2.3"
194source = "registry+https://github.com/rust-lang/crates.io-index"194source = "registry+https://github.com/rust-lang/crates.io-index"
195checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"195checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
196dependencies = [196dependencies = [
197 "utf8parse",197 "utf8parse",
198]198]
199199
200[[package]]200[[package]]
201name = "anstyle-query"201name = "anstyle-query"
202version = "1.0.0"202version = "1.0.2"
203source = "registry+https://github.com/rust-lang/crates.io-index"203source = "registry+https://github.com/rust-lang/crates.io-index"
204checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"204checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
205dependencies = [205dependencies = [
206 "windows-sys 0.48.0",206 "windows-sys 0.52.0",
207]207]
208208
209[[package]]209[[package]]
210name = "anstyle-wincon"210name = "anstyle-wincon"
211version = "3.0.1"211version = "3.0.2"
212source = "registry+https://github.com/rust-lang/crates.io-index"212source = "registry+https://github.com/rust-lang/crates.io-index"
213checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"213checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
214dependencies = [214dependencies = [
215 "anstyle",215 "anstyle",
216 "windows-sys 0.48.0",216 "windows-sys 0.52.0",
217]217]
218218
219[[package]]219[[package]]
220name = "anyhow"220name = "anyhow"
221version = "1.0.75"221version = "1.0.77"
222source = "registry+https://github.com/rust-lang/crates.io-index"222source = "registry+https://github.com/rust-lang/crates.io-index"
223checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"223checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9"
224224
225[[package]]225[[package]]
226name = "arc-swap"226name = "arc-swap"
242242
243[[package]]243[[package]]
244name = "async-trait"244name = "async-trait"
245version = "0.1.74"245version = "0.1.75"
246source = "registry+https://github.com/rust-lang/crates.io-index"246source = "registry+https://github.com/rust-lang/crates.io-index"
247checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"247checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98"
248dependencies = [248dependencies = [
249 "proc-macro2",249 "proc-macro2",
250 "quote",250 "quote",
251 "syn 2.0.38",251 "syn 2.0.43",
252]252]
253253
254[[package]]254[[package]]
387387
388[[package]]388[[package]]
389name = "byteorder"389name = "byteorder"
390version = "1.4.3"390version = "1.5.0"
391source = "registry+https://github.com/rust-lang/crates.io-index"391source = "registry+https://github.com/rust-lang/crates.io-index"
392checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"392checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
393393
394[[package]]394[[package]]
395name = "bytes"395name = "bytes"
482482
483[[package]]483[[package]]
484name = "clap"484name = "clap"
485version = "4.4.7"485version = "4.4.12"
486source = "registry+https://github.com/rust-lang/crates.io-index"486source = "registry+https://github.com/rust-lang/crates.io-index"
487checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"487checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d"
488dependencies = [488dependencies = [
489 "clap_builder",489 "clap_builder",
490 "clap_derive",490 "clap_derive",
491]491]
492492
493[[package]]493[[package]]
494name = "clap_builder"494name = "clap_builder"
495version = "4.4.7"495version = "4.4.12"
496source = "registry+https://github.com/rust-lang/crates.io-index"496source = "registry+https://github.com/rust-lang/crates.io-index"
497checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"497checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9"
498dependencies = [498dependencies = [
499 "anstream",499 "anstream",
500 "anstyle",500 "anstyle",
514 "heck",514 "heck",
515 "proc-macro2",515 "proc-macro2",
516 "quote",516 "quote",
517 "syn 2.0.38",517 "syn 2.0.43",
518]518]
519519
520[[package]]520[[package]]
544544
545[[package]]545[[package]]
546name = "const-oid"546name = "const-oid"
547version = "0.9.5"547version = "0.9.6"
548source = "registry+https://github.com/rust-lang/crates.io-index"548source = "registry+https://github.com/rust-lang/crates.io-index"
549checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"549checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
550550
551[[package]]551[[package]]
552name = "cookie-factory"552name = "cookie-factory"
556556
557[[package]]557[[package]]
558name = "core-foundation-sys"558name = "core-foundation-sys"
559version = "0.8.4"559version = "0.8.6"
560source = "registry+https://github.com/rust-lang/crates.io-index"560source = "registry+https://github.com/rust-lang/crates.io-index"
561checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"561checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
562562
563[[package]]563[[package]]
564name = "countme"564name = "countme"
568568
569[[package]]569[[package]]
570name = "cpufeatures"570name = "cpufeatures"
571version = "0.2.9"571version = "0.2.11"
572source = "registry+https://github.com/rust-lang/crates.io-index"572source = "registry+https://github.com/rust-lang/crates.io-index"
573checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"573checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0"
574dependencies = [574dependencies = [
575 "libc",575 "libc",
576]576]
615checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"615checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
616dependencies = [616dependencies = [
617 "cfg-if",617 "cfg-if",
618 "hashbrown 0.14.1",618 "hashbrown 0.14.3",
619 "lock_api",619 "lock_api",
620 "once_cell",620 "once_cell",
621 "parking_lot_core",621 "parking_lot_core",
633633
634[[package]]634[[package]]
635name = "deranged"635name = "deranged"
636version = "0.3.9"636version = "0.3.11"
637source = "registry+https://github.com/rust-lang/crates.io-index"637source = "registry+https://github.com/rust-lang/crates.io-index"
638checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"638checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
639dependencies = [639dependencies = [
640 "powerfmt",640 "powerfmt",
641 "serde",641 "serde",
691dependencies = [691dependencies = [
692 "proc-macro2",692 "proc-macro2",
693 "quote",693 "quote",
694 "syn 2.0.38",694 "syn 2.0.43",
695]695]
696696
697[[package]]697[[package]]
708708
709[[package]]709[[package]]
710name = "env_logger"710name = "env_logger"
711version = "0.10.0"711version = "0.10.1"
712source = "registry+https://github.com/rust-lang/crates.io-index"712source = "registry+https://github.com/rust-lang/crates.io-index"
713checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"713checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
714dependencies = [714dependencies = [
715 "humantime",715 "humantime",
716 "is-terminal",716 "is-terminal",
727727
728[[package]]728[[package]]
729name = "errno"729name = "errno"
730version = "0.3.5"730version = "0.3.8"
731source = "registry+https://github.com/rust-lang/crates.io-index"731source = "registry+https://github.com/rust-lang/crates.io-index"
732checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"732checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
733dependencies = [733dependencies = [
734 "libc",734 "libc",
735 "windows-sys 0.48.0",735 "windows-sys 0.52.0",
736]736]
737737
738[[package]]738[[package]]
752752
753[[package]]753[[package]]
754name = "fleet"754name = "fleet"
755version = "0.1.0"755version = "0.2.0"
756dependencies = [756dependencies = [
757 "abort-on-drop",757 "abort-on-drop",
758 "age",758 "age",
827 "intl-memoizer",827 "intl-memoizer",
828 "intl_pluralrules",828 "intl_pluralrules",
829 "rustc-hash",829 "rustc-hash",
830 "self_cell",830 "self_cell 0.10.3",
831 "smallvec",831 "smallvec",
832 "unic-langid",832 "unic-langid",
833]833]
858858
859[[package]]859[[package]]
860name = "futures"860name = "futures"
861version = "0.3.29"861version = "0.3.30"
862source = "registry+https://github.com/rust-lang/crates.io-index"862source = "registry+https://github.com/rust-lang/crates.io-index"
863checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"863checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
864dependencies = [864dependencies = [
865 "futures-channel",865 "futures-channel",
866 "futures-core",866 "futures-core",
873873
874[[package]]874[[package]]
875name = "futures-channel"875name = "futures-channel"
876version = "0.3.29"876version = "0.3.30"
877source = "registry+https://github.com/rust-lang/crates.io-index"877source = "registry+https://github.com/rust-lang/crates.io-index"
878checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"878checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
879dependencies = [879dependencies = [
880 "futures-core",880 "futures-core",
881 "futures-sink",881 "futures-sink",
882]882]
883883
884[[package]]884[[package]]
885name = "futures-core"885name = "futures-core"
886version = "0.3.29"886version = "0.3.30"
887source = "registry+https://github.com/rust-lang/crates.io-index"887source = "registry+https://github.com/rust-lang/crates.io-index"
888checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"888checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
889889
890[[package]]890[[package]]
891name = "futures-executor"891name = "futures-executor"
892version = "0.3.29"892version = "0.3.30"
893source = "registry+https://github.com/rust-lang/crates.io-index"893source = "registry+https://github.com/rust-lang/crates.io-index"
894checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"894checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
895dependencies = [895dependencies = [
896 "futures-core",896 "futures-core",
897 "futures-task",897 "futures-task",
900900
901[[package]]901[[package]]
902name = "futures-io"902name = "futures-io"
903version = "0.3.29"903version = "0.3.30"
904source = "registry+https://github.com/rust-lang/crates.io-index"904source = "registry+https://github.com/rust-lang/crates.io-index"
905checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"905checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
906906
907[[package]]907[[package]]
908name = "futures-macro"908name = "futures-macro"
909version = "0.3.29"909version = "0.3.30"
910source = "registry+https://github.com/rust-lang/crates.io-index"910source = "registry+https://github.com/rust-lang/crates.io-index"
911checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"911checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
912dependencies = [912dependencies = [
913 "proc-macro2",913 "proc-macro2",
914 "quote",914 "quote",
915 "syn 2.0.38",915 "syn 2.0.43",
916]916]
917917
918[[package]]918[[package]]
919name = "futures-sink"919name = "futures-sink"
920version = "0.3.29"920version = "0.3.30"
921source = "registry+https://github.com/rust-lang/crates.io-index"921source = "registry+https://github.com/rust-lang/crates.io-index"
922checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"922checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
923923
924[[package]]924[[package]]
925name = "futures-task"925name = "futures-task"
926version = "0.3.29"926version = "0.3.30"
927source = "registry+https://github.com/rust-lang/crates.io-index"927source = "registry+https://github.com/rust-lang/crates.io-index"
928checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"928checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
929929
930[[package]]930[[package]]
931name = "futures-util"931name = "futures-util"
932version = "0.3.29"932version = "0.3.30"
933source = "registry+https://github.com/rust-lang/crates.io-index"933source = "registry+https://github.com/rust-lang/crates.io-index"
934checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"934checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
935dependencies = [935dependencies = [
936 "futures-channel",936 "futures-channel",
937 "futures-core",937 "futures-core",
968968
969[[package]]969[[package]]
970name = "getrandom"970name = "getrandom"
971version = "0.2.10"971version = "0.2.11"
972source = "registry+https://github.com/rust-lang/crates.io-index"972source = "registry+https://github.com/rust-lang/crates.io-index"
973checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"973checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
974dependencies = [974dependencies = [
975 "cfg-if",975 "cfg-if",
976 "libc",976 "libc",
989989
990[[package]]990[[package]]
991name = "gimli"991name = "gimli"
992version = "0.28.0"992version = "0.28.1"
993source = "registry+https://github.com/rust-lang/crates.io-index"993source = "registry+https://github.com/rust-lang/crates.io-index"
994checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"994checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
995995
996[[package]]996[[package]]
997name = "hashbrown"997name = "hashbrown"
10011001
1002[[package]]1002[[package]]
1003name = "hashbrown"1003name = "hashbrown"
1004version = "0.14.1"1004version = "0.14.3"
1005source = "registry+https://github.com/rust-lang/crates.io-index"1005source = "registry+https://github.com/rust-lang/crates.io-index"
1006checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"1006checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
10071007
1008[[package]]1008[[package]]
1009name = "heck"1009name = "heck"
10281028
1029[[package]]1029[[package]]
1030name = "hkdf"1030name = "hkdf"
1031version = "0.12.3"1031version = "0.12.4"
1032source = "registry+https://github.com/rust-lang/crates.io-index"1032source = "registry+https://github.com/rust-lang/crates.io-index"
1033checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"1033checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
1034dependencies = [1034dependencies = [
1035 "hmac",1035 "hmac",
1036]1036]
1077 "serde",1077 "serde",
1078 "serde_derive",1078 "serde_derive",
1079 "thiserror",1079 "thiserror",
1080 "toml 0.8.0",1080 "toml 0.8.8",
1081 "unic-langid",1081 "unic-langid",
1082]1082]
10831083
1119 "proc-macro2",1119 "proc-macro2",
1120 "quote",1120 "quote",
1121 "strsim",1121 "strsim",
1122 "syn 2.0.38",1122 "syn 2.0.43",
1123 "unic-langid",1123 "unic-langid",
1124]1124]
11251125
1126[[package]]1126[[package]]
1127name = "i18n-embed-impl"1127name = "i18n-embed-impl"
1128version = "0.8.2"1128version = "0.8.3"
1129source = "registry+https://github.com/rust-lang/crates.io-index"1129source = "registry+https://github.com/rust-lang/crates.io-index"
1130checksum = "a2a4d5bff745c9a6e1459c490059281b353a4ab0a4e1e58b3eeeaef71f97d07b"1130checksum = "81093c4701672f59416582fe3145676126fd23ba5db910acad0793c1108aaa58"
1131dependencies = [1131dependencies = [
1132 "find-crate",1132 "find-crate",
1133 "i18n-config",1133 "i18n-config",
1134 "proc-macro2",1134 "proc-macro2",
1135 "quote",1135 "quote",
1136 "syn 2.0.38",1136 "syn 2.0.43",
1137]1137]
11381138
1139[[package]]1139[[package]]
1140name = "iana-time-zone"1140name = "iana-time-zone"
1141version = "0.1.57"1141version = "0.1.59"
1142source = "registry+https://github.com/rust-lang/crates.io-index"1142source = "registry+https://github.com/rust-lang/crates.io-index"
1143checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"1143checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
1144dependencies = [1144dependencies = [
1145 "android_system_properties",1145 "android_system_properties",
1146 "core-foundation-sys",1146 "core-foundation-sys",
1147 "iana-time-zone-haiku",1147 "iana-time-zone-haiku",
1148 "js-sys",1148 "js-sys",
1149 "wasm-bindgen",1149 "wasm-bindgen",
1150 "windows",1150 "windows-core",
1151]1151]
11521152
1153[[package]]1153[[package]]
11611161
1162[[package]]1162[[package]]
1163name = "indexmap"1163name = "indexmap"
1164version = "2.0.2"1164version = "2.1.0"
1165source = "registry+https://github.com/rust-lang/crates.io-index"1165source = "registry+https://github.com/rust-lang/crates.io-index"
1166checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"1166checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
1167dependencies = [1167dependencies = [
1168 "equivalent",1168 "equivalent",
1169 "hashbrown 0.14.1",1169 "hashbrown 0.14.3",
1170]1170]
11711171
1172[[package]]1172[[package]]
12291229
1230[[package]]1230[[package]]
1231name = "is-terminal"1231name = "is-terminal"
1232version = "0.4.9"1232version = "0.4.10"
1233source = "registry+https://github.com/rust-lang/crates.io-index"1233source = "registry+https://github.com/rust-lang/crates.io-index"
1234checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"1234checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
1235dependencies = [1235dependencies = [
1236 "hermit-abi 0.3.3",1236 "hermit-abi 0.3.3",
1237 "rustix",1237 "rustix",
1238 "windows-sys 0.48.0",1238 "windows-sys 0.52.0",
1239]1239]
12401240
1241[[package]]1241[[package]]
12551255
1256[[package]]1256[[package]]
1257name = "itoa"1257name = "itoa"
1258version = "1.0.9"1258version = "1.0.10"
1259source = "registry+https://github.com/rust-lang/crates.io-index"1259source = "registry+https://github.com/rust-lang/crates.io-index"
1260checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"1260checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
12611261
1262[[package]]1262[[package]]
1263name = "js-sys"1263name = "js-sys"
1264version = "0.3.64"1264version = "0.3.66"
1265source = "registry+https://github.com/rust-lang/crates.io-index"1265source = "registry+https://github.com/rust-lang/crates.io-index"
1266checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"1266checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
1267dependencies = [1267dependencies = [
1268 "wasm-bindgen",1268 "wasm-bindgen",
1269]1269]
12791279
1280[[package]]1280[[package]]
1281name = "libc"1281name = "libc"
1282version = "0.2.149"1282version = "0.2.151"
1283source = "registry+https://github.com/rust-lang/crates.io-index"1283source = "registry+https://github.com/rust-lang/crates.io-index"
1284checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"1284checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
12851285
1286[[package]]1286[[package]]
1287name = "libm"1287name = "libm"
1288version = "0.2.7"1288version = "0.2.8"
1289source = "registry+https://github.com/rust-lang/crates.io-index"1289source = "registry+https://github.com/rust-lang/crates.io-index"
1290checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"1290checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
12911291
1292[[package]]1292[[package]]
1293name = "libmimalloc-sys"1293name = "libmimalloc-sys"
1307dependencies = [1307dependencies = [
1308 "bitflags 2.4.1",1308 "bitflags 2.4.1",
1309 "libc",1309 "libc",
1310 "redox_syscall 0.4.1",1310 "redox_syscall",
1311]1311]
13121312
1313[[package]]1313[[package]]
13181318
1319[[package]]1319[[package]]
1320name = "linux-raw-sys"1320name = "linux-raw-sys"
1321version = "0.4.10"1321version = "0.4.12"
1322source = "registry+https://github.com/rust-lang/crates.io-index"1322source = "registry+https://github.com/rust-lang/crates.io-index"
1323checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"1323checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
13241324
1325[[package]]1325[[package]]
1326name = "lock_api"1326name = "lock_api"
1327version = "0.4.10"1327version = "0.4.11"
1328source = "registry+https://github.com/rust-lang/crates.io-index"1328source = "registry+https://github.com/rust-lang/crates.io-index"
1329checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"1329checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
1330dependencies = [1330dependencies = [
1331 "autocfg",1331 "autocfg",
1332 "scopeguard",1332 "scopeguard",
13551355
1356[[package]]1356[[package]]
1357name = "memchr"1357name = "memchr"
1358version = "2.6.4"1358version = "2.7.1"
1359source = "registry+https://github.com/rust-lang/crates.io-index"1359source = "registry+https://github.com/rust-lang/crates.io-index"
1360checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"1360checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
13611361
1362[[package]]1362[[package]]
1363name = "memoffset"1363name = "memoffset"
13941394
1395[[package]]1395[[package]]
1396name = "mio"1396name = "mio"
1397version = "0.8.8"1397version = "0.8.10"
1398source = "registry+https://github.com/rust-lang/crates.io-index"1398source = "registry+https://github.com/rust-lang/crates.io-index"
1399checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"1399checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
1400dependencies = [1400dependencies = [
1401 "libc",1401 "libc",
1402 "wasi 0.11.0+wasi-snapshot-preview1",1402 "wasi 0.11.0+wasi-snapshot-preview1",
15141514
1515[[package]]1515[[package]]
1516name = "object"1516name = "object"
1517version = "0.32.1"1517version = "0.32.2"
1518source = "registry+https://github.com/rust-lang/crates.io-index"1518source = "registry+https://github.com/rust-lang/crates.io-index"
1519checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"1519checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
1520dependencies = [1520dependencies = [
1521 "memchr",1521 "memchr",
1522]1522]
15351535
1536[[package]]1536[[package]]
1537name = "openssh"1537name = "openssh"
1538version = "0.10.1"1538version = "0.10.2"
1539source = "registry+https://github.com/rust-lang/crates.io-index"1539source = "registry+https://github.com/rust-lang/crates.io-index"
1540checksum = "3dfe68c42d6ee6bd9de175b7a5d9bb86aa99d4e2fa7cf2f2a44e97f60b6d2759"1540checksum = "8274f2bf1fc3785406a3ff07c92c15590c00e84efb883da77b671562ca9a6115"
1541dependencies = [1541dependencies = [
1542 "dirs",1542 "dirs",
1543 "libc",1543 "libc",
15951595
1596[[package]]1596[[package]]
1597name = "parking_lot_core"1597name = "parking_lot_core"
1598version = "0.9.8"1598version = "0.9.9"
1599source = "registry+https://github.com/rust-lang/crates.io-index"1599source = "registry+https://github.com/rust-lang/crates.io-index"
1600checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"1600checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
1601dependencies = [1601dependencies = [
1602 "cfg-if",1602 "cfg-if",
1603 "libc",1603 "libc",
1604 "redox_syscall 0.3.5",1604 "redox_syscall",
1605 "smallvec",1605 "smallvec",
1606 "windows-targets 0.48.5",1606 "windows-targets 0.48.5",
1607]1607]
1659dependencies = [1659dependencies = [
1660 "proc-macro2",1660 "proc-macro2",
1661 "quote",1661 "quote",
1662 "syn 2.0.38",1662 "syn 2.0.43",
1663]1663]
16641664
1665[[package]]1665[[package]]
17211721
1722[[package]]1722[[package]]
1723name = "portable-atomic"1723name = "portable-atomic"
1724version = "1.4.3"1724version = "1.6.0"
1725source = "registry+https://github.com/rust-lang/crates.io-index"1725source = "registry+https://github.com/rust-lang/crates.io-index"
1726checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b"1726checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
17271727
1728[[package]]1728[[package]]
1729name = "powerfmt"1729name = "powerfmt"
17631763
1764[[package]]1764[[package]]
1765name = "proc-macro2"1765name = "proc-macro2"
1766version = "1.0.69"1766version = "1.0.71"
1767source = "registry+https://github.com/rust-lang/crates.io-index"1767source = "registry+https://github.com/rust-lang/crates.io-index"
1768checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"1768checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
1769dependencies = [1769dependencies = [
1770 "unicode-ident",1770 "unicode-ident",
1771]1771]
1849source = "registry+https://github.com/rust-lang/crates.io-index"1849source = "registry+https://github.com/rust-lang/crates.io-index"
1850checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"1850checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1851dependencies = [1851dependencies = [
1852 "getrandom 0.2.10",1852 "getrandom 0.2.11",
1853]1853]
18541854
1855[[package]]1855[[package]]
1861 "rand_core 0.5.1",1861 "rand_core 0.5.1",
1862]1862]
1863
1864[[package]]
1865name = "redox_syscall"
1866version = "0.3.5"
1867source = "registry+https://github.com/rust-lang/crates.io-index"
1868checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
1869dependencies = [
1870 "bitflags 1.3.2",
1871]
18721863
1873[[package]]1864[[package]]
1874name = "redox_syscall"1865name = "redox_syscall"
1885source = "registry+https://github.com/rust-lang/crates.io-index"1876source = "registry+https://github.com/rust-lang/crates.io-index"
1886checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"1877checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
1887dependencies = [1878dependencies = [
1888 "getrandom 0.2.10",1879 "getrandom 0.2.11",
1889 "libredox",1880 "libredox",
1890 "thiserror",1881 "thiserror",
1891]1882]
2015 "proc-macro2",2006 "proc-macro2",
2016 "quote",2007 "quote",
2017 "rust-embed-utils",2008 "rust-embed-utils",
2018 "syn 2.0.38",2009 "syn 2.0.43",
2019 "walkdir",2010 "walkdir",
2020]2011]
20212012
20432034
2044[[package]]2035[[package]]
2045name = "rustix"2036name = "rustix"
2046version = "0.38.21"2037version = "0.38.28"
2047source = "registry+https://github.com/rust-lang/crates.io-index"2038source = "registry+https://github.com/rust-lang/crates.io-index"
2048checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"2039checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
2049dependencies = [2040dependencies = [
2050 "bitflags 2.4.1",2041 "bitflags 2.4.1",
2051 "errno",2042 "errno",
2052 "libc",2043 "libc",
2053 "linux-raw-sys",2044 "linux-raw-sys",
2054 "windows-sys 0.48.0",2045 "windows-sys 0.52.0",
2055]2046]
20562047
2057[[package]]2048[[package]]
2058name = "ryu"2049name = "ryu"
2059version = "1.0.15"2050version = "1.0.16"
2060source = "registry+https://github.com/rust-lang/crates.io-index"2051source = "registry+https://github.com/rust-lang/crates.io-index"
2061checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"2052checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
20622053
2063[[package]]2054[[package]]
2064name = "salsa20"2055name = "salsa20"
21162107
2117[[package]]2108[[package]]
2118name = "self_cell"2109name = "self_cell"
2119version = "0.10.2"2110version = "0.10.3"
2120source = "registry+https://github.com/rust-lang/crates.io-index"2111source = "registry+https://github.com/rust-lang/crates.io-index"
2121checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"2112checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d"
2113dependencies = [
2114 "self_cell 1.0.3",
2115]
2116
2117[[package]]
2118name = "self_cell"
2119version = "1.0.3"
2120source = "registry+https://github.com/rust-lang/crates.io-index"
2121checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba"
21222122
2123[[package]]2123[[package]]
2124name = "serde"2124name = "serde"
2146dependencies = [2146dependencies = [
2147 "proc-macro2",2147 "proc-macro2",
2148 "quote",2148 "quote",
2149 "syn 2.0.38",2149 "syn 2.0.43",
2150]2150]
21512151
2152[[package]]2152[[package]]
21622162
2163[[package]]2163[[package]]
2164name = "serde_spanned"2164name = "serde_spanned"
2165version = "0.6.3"2165version = "0.6.5"
2166source = "registry+https://github.com/rust-lang/crates.io-index"2166source = "registry+https://github.com/rust-lang/crates.io-index"
2167checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"2167checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
2168dependencies = [2168dependencies = [
2169 "serde",2169 "serde",
2170]2170]
21822182
2183[[package]]2183[[package]]
2184name = "sharded-slab"2184name = "sharded-slab"
2185version = "0.1.4"2185version = "0.1.7"
2186source = "registry+https://github.com/rust-lang/crates.io-index"2186source = "registry+https://github.com/rust-lang/crates.io-index"
2187checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"2187checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
2188dependencies = [2188dependencies = [
2189 "lazy_static",2189 "lazy_static",
2190]2190]
22312231
2232[[package]]2232[[package]]
2233name = "smallvec"2233name = "smallvec"
2234version = "1.11.1"2234version = "1.11.2"
2235source = "registry+https://github.com/rust-lang/crates.io-index"2235source = "registry+https://github.com/rust-lang/crates.io-index"
2236checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"2236checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
22372237
2238[[package]]2238[[package]]
2239name = "smol_str"2239name = "smol_str"
22462246
2247[[package]]2247[[package]]
2248name = "socket2"2248name = "socket2"
2249version = "0.5.4"2249version = "0.5.5"
2250source = "registry+https://github.com/rust-lang/crates.io-index"2250source = "registry+https://github.com/rust-lang/crates.io-index"
2251checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"2251checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
2252dependencies = [2252dependencies = [
2253 "libc",2253 "libc",
2254 "windows-sys 0.48.0",2254 "windows-sys 0.48.0",
23052305
2306[[package]]2306[[package]]
2307name = "syn"2307name = "syn"
2308version = "2.0.38"2308version = "2.0.43"
2309source = "registry+https://github.com/rust-lang/crates.io-index"2309source = "registry+https://github.com/rust-lang/crates.io-index"
2310checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"2310checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
2311dependencies = [2311dependencies = [
2312 "proc-macro2",2312 "proc-macro2",
2313 "quote",2313 "quote",
23422342
2343[[package]]2343[[package]]
2344name = "tempfile"2344name = "tempfile"
2345version = "3.8.1"2345version = "3.9.0"
2346source = "registry+https://github.com/rust-lang/crates.io-index"2346source = "registry+https://github.com/rust-lang/crates.io-index"
2347checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"2347checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
2348dependencies = [2348dependencies = [
2349 "cfg-if",2349 "cfg-if",
2350 "fastrand",2350 "fastrand",
2351 "redox_syscall 0.4.1",2351 "redox_syscall",
2352 "rustix",2352 "rustix",
2353 "windows-sys 0.48.0",2353 "windows-sys 0.52.0",
2354]2354]
23552355
2356[[package]]2356[[package]]
2357name = "termcolor"2357name = "termcolor"
2358version = "1.3.0"2358version = "1.4.0"
2359source = "registry+https://github.com/rust-lang/crates.io-index"2359source = "registry+https://github.com/rust-lang/crates.io-index"
2360checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64"2360checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449"
2361dependencies = [2361dependencies = [
2362 "winapi-util",2362 "winapi-util",
2363]2363]
23802380
2381[[package]]2381[[package]]
2382name = "thiserror"2382name = "thiserror"
2383version = "1.0.50"2383version = "1.0.53"
2384source = "registry+https://github.com/rust-lang/crates.io-index"2384source = "registry+https://github.com/rust-lang/crates.io-index"
2385checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"2385checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09"
2386dependencies = [2386dependencies = [
2387 "thiserror-impl",2387 "thiserror-impl",
2388]2388]
23892389
2390[[package]]2390[[package]]
2391name = "thiserror-impl"2391name = "thiserror-impl"
2392version = "1.0.50"2392version = "1.0.53"
2393source = "registry+https://github.com/rust-lang/crates.io-index"2393source = "registry+https://github.com/rust-lang/crates.io-index"
2394checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"2394checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19"
2395dependencies = [2395dependencies = [
2396 "proc-macro2",2396 "proc-macro2",
2397 "quote",2397 "quote",
2398 "syn 2.0.38",2398 "syn 2.0.43",
2399]2399]
24002400
2401[[package]]2401[[package]]
24102410
2411[[package]]2411[[package]]
2412name = "time"2412name = "time"
2413version = "0.3.30"2413version = "0.3.31"
2414source = "registry+https://github.com/rust-lang/crates.io-index"2414source = "registry+https://github.com/rust-lang/crates.io-index"
2415checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5"2415checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e"
2416dependencies = [2416dependencies = [
2417 "deranged",2417 "deranged",
2418 "powerfmt",2418 "powerfmt",
24292429
2430[[package]]2430[[package]]
2431name = "time-macros"2431name = "time-macros"
2432version = "0.2.15"2432version = "0.2.16"
2433source = "registry+https://github.com/rust-lang/crates.io-index"2433source = "registry+https://github.com/rust-lang/crates.io-index"
2434checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"2434checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f"
2435dependencies = [2435dependencies = [
2436 "time-core",2436 "time-core",
2437]2437]
24382438
2439[[package]]2439[[package]]
2440name = "tinystr"2440name = "tinystr"
2441version = "0.7.2"2441version = "0.7.5"
2442source = "registry+https://github.com/rust-lang/crates.io-index"2442source = "registry+https://github.com/rust-lang/crates.io-index"
2443checksum = "8faa444297615a4e020acb64146b0603c9c395c03a97c17fd9028816d3b4d63e"2443checksum = "83c02bf3c538ab32ba913408224323915f4ef9a6d61c0e85d493f355921c0ece"
2444dependencies = [2444dependencies = [
2445 "displaydoc",2445 "displaydoc",
2446]2446]
24472447
2448[[package]]2448[[package]]
2449name = "tokio"2449name = "tokio"
2450version = "1.33.0"2450version = "1.35.1"
2451source = "registry+https://github.com/rust-lang/crates.io-index"2451source = "registry+https://github.com/rust-lang/crates.io-index"
2452checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"2452checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
2453dependencies = [2453dependencies = [
2454 "backtrace",2454 "backtrace",
2455 "bytes",2455 "bytes",
24662466
2467[[package]]2467[[package]]
2468name = "tokio-macros"2468name = "tokio-macros"
2469version = "2.1.0"2469version = "2.2.0"
2470source = "registry+https://github.com/rust-lang/crates.io-index"2470source = "registry+https://github.com/rust-lang/crates.io-index"
2471checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"2471checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
2472dependencies = [2472dependencies = [
2473 "proc-macro2",2473 "proc-macro2",
2474 "quote",2474 "quote",
2475 "syn 2.0.38",2475 "syn 2.0.43",
2476]2476]
24772477
2478[[package]]2478[[package]]
25102510
2511[[package]]2511[[package]]
2512name = "toml"2512name = "toml"
2513version = "0.8.0"2513version = "0.8.8"
2514source = "registry+https://github.com/rust-lang/crates.io-index"2514source = "registry+https://github.com/rust-lang/crates.io-index"
2515checksum = "c226a7bba6d859b63c92c4b4fe69c5b6b72d0cb897dbc8e6012298e6154cb56e"2515checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
2516dependencies = [2516dependencies = [
2517 "serde",2517 "serde",
2518 "serde_spanned",2518 "serde_spanned",
25222522
2523[[package]]2523[[package]]
2524name = "toml_datetime"2524name = "toml_datetime"
2525version = "0.6.3"2525version = "0.6.5"
2526source = "registry+https://github.com/rust-lang/crates.io-index"2526source = "registry+https://github.com/rust-lang/crates.io-index"
2527checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"2527checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
2528dependencies = [2528dependencies = [
2529 "serde",2529 "serde",
2530]2530]
25312531
2532[[package]]2532[[package]]
2533name = "toml_edit"2533name = "toml_edit"
2534version = "0.20.0"2534version = "0.21.0"
2535source = "registry+https://github.com/rust-lang/crates.io-index"2535source = "registry+https://github.com/rust-lang/crates.io-index"
2536checksum = "8ff63e60a958cefbb518ae1fd6566af80d9d4be430a33f3723dfc47d1d411d95"2536checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
2537dependencies = [2537dependencies = [
2538 "indexmap",2538 "indexmap",
2539 "serde",2539 "serde",
2561dependencies = [2561dependencies = [
2562 "proc-macro2",2562 "proc-macro2",
2563 "quote",2563 "quote",
2564 "syn 2.0.38",2564 "syn 2.0.43",
2565]2565]
25662566
2567[[package]]2567[[package]]
25882588
2589[[package]]2589[[package]]
2590name = "tracing-log"2590name = "tracing-log"
2591version = "0.1.3"2591version = "0.2.0"
2592source = "registry+https://github.com/rust-lang/crates.io-index"2592source = "registry+https://github.com/rust-lang/crates.io-index"
2593checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"2593checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
2594dependencies = [2594dependencies = [
2595 "lazy_static",
2596 "log",2595 "log",
2596 "once_cell",
2597 "tracing-core",2597 "tracing-core",
2598]2598]
25992599
2600[[package]]2600[[package]]
2601name = "tracing-subscriber"2601name = "tracing-subscriber"
2602version = "0.3.17"2602version = "0.3.18"
2603source = "registry+https://github.com/rust-lang/crates.io-index"2603source = "registry+https://github.com/rust-lang/crates.io-index"
2604checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"2604checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
2605dependencies = [2605dependencies = [
2606 "matchers",2606 "matchers",
2607 "nu-ansi-term",2607 "nu-ansi-term",
26322632
2633[[package]]2633[[package]]
2634name = "unic-langid"2634name = "unic-langid"
2635version = "0.9.1"2635version = "0.9.4"
2636source = "registry+https://github.com/rust-lang/crates.io-index"2636source = "registry+https://github.com/rust-lang/crates.io-index"
2637checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f"2637checksum = "238722e6d794ed130f91f4ea33e01fcff4f188d92337a21297892521c72df516"
2638dependencies = [2638dependencies = [
2639 "unic-langid-impl",2639 "unic-langid-impl",
2640]2640]
26412641
2642[[package]]2642[[package]]
2643name = "unic-langid-impl"2643name = "unic-langid-impl"
2644version = "0.9.1"2644version = "0.9.4"
2645source = "registry+https://github.com/rust-lang/crates.io-index"2645source = "registry+https://github.com/rust-lang/crates.io-index"
2646checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff"2646checksum = "4bd55a2063fdea4ef1f8633243a7b0524cbeef1905ae04c31a1c9b9775c55bc6"
2647dependencies = [2647dependencies = [
2648 "serde",2648 "serde",
2649 "tinystr",2649 "tinystr",
27722772
2773[[package]]2773[[package]]
2774name = "wasm-bindgen"2774name = "wasm-bindgen"
2775version = "0.2.87"2775version = "0.2.89"
2776source = "registry+https://github.com/rust-lang/crates.io-index"2776source = "registry+https://github.com/rust-lang/crates.io-index"
2777checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"2777checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
2778dependencies = [2778dependencies = [
2779 "cfg-if",2779 "cfg-if",
2780 "wasm-bindgen-macro",2780 "wasm-bindgen-macro",
2781]2781]
27822782
2783[[package]]2783[[package]]
2784name = "wasm-bindgen-backend"2784name = "wasm-bindgen-backend"
2785version = "0.2.87"2785version = "0.2.89"
2786source = "registry+https://github.com/rust-lang/crates.io-index"2786source = "registry+https://github.com/rust-lang/crates.io-index"
2787checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"2787checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
2788dependencies = [2788dependencies = [
2789 "bumpalo",2789 "bumpalo",
2790 "log",2790 "log",
2791 "once_cell",2791 "once_cell",
2792 "proc-macro2",2792 "proc-macro2",
2793 "quote",2793 "quote",
2794 "syn 2.0.38",2794 "syn 2.0.43",
2795 "wasm-bindgen-shared",2795 "wasm-bindgen-shared",
2796]2796]
27972797
2798[[package]]2798[[package]]
2799name = "wasm-bindgen-macro"2799name = "wasm-bindgen-macro"
2800version = "0.2.87"2800version = "0.2.89"
2801source = "registry+https://github.com/rust-lang/crates.io-index"2801source = "registry+https://github.com/rust-lang/crates.io-index"
2802checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"2802checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
2803dependencies = [2803dependencies = [
2804 "quote",2804 "quote",
2805 "wasm-bindgen-macro-support",2805 "wasm-bindgen-macro-support",
2806]2806]
28072807
2808[[package]]2808[[package]]
2809name = "wasm-bindgen-macro-support"2809name = "wasm-bindgen-macro-support"
2810version = "0.2.87"2810version = "0.2.89"
2811source = "registry+https://github.com/rust-lang/crates.io-index"2811source = "registry+https://github.com/rust-lang/crates.io-index"
2812checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"2812checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
2813dependencies = [2813dependencies = [
2814 "proc-macro2",2814 "proc-macro2",
2815 "quote",2815 "quote",
2816 "syn 2.0.38",2816 "syn 2.0.43",
2817 "wasm-bindgen-backend",2817 "wasm-bindgen-backend",
2818 "wasm-bindgen-shared",2818 "wasm-bindgen-shared",
2819]2819]
28202820
2821[[package]]2821[[package]]
2822name = "wasm-bindgen-shared"2822name = "wasm-bindgen-shared"
2823version = "0.2.87"2823version = "0.2.89"
2824source = "registry+https://github.com/rust-lang/crates.io-index"2824source = "registry+https://github.com/rust-lang/crates.io-index"
2825checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"2825checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
28262826
2827[[package]]2827[[package]]
2828name = "winapi"2828name = "winapi"
2856checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"2856checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
28572857
2858[[package]]2858[[package]]
2859name = "windows"2859name = "windows-core"
2860version = "0.48.0"2860version = "0.52.0"
2861source = "registry+https://github.com/rust-lang/crates.io-index"2861source = "registry+https://github.com/rust-lang/crates.io-index"
2862checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"2862checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
2863dependencies = [2863dependencies = [
2864 "windows-targets 0.48.5",2864 "windows-targets 0.52.0",
2865]2865]
28662866
2867[[package]]2867[[package]]
2882 "windows-targets 0.48.5",2882 "windows-targets 0.48.5",
2883]2883]
2884
2885[[package]]
2886name = "windows-sys"
2887version = "0.52.0"
2888source = "registry+https://github.com/rust-lang/crates.io-index"
2889checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
2890dependencies = [
2891 "windows-targets 0.52.0",
2892]
28842893
2885[[package]]2894[[package]]
2886name = "windows-targets"2895name = "windows-targets"
2912 "windows_x86_64_msvc 0.48.5",2921 "windows_x86_64_msvc 0.48.5",
2913]2922]
2923
2924[[package]]
2925name = "windows-targets"
2926version = "0.52.0"
2927source = "registry+https://github.com/rust-lang/crates.io-index"
2928checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
2929dependencies = [
2930 "windows_aarch64_gnullvm 0.52.0",
2931 "windows_aarch64_msvc 0.52.0",
2932 "windows_i686_gnu 0.52.0",
2933 "windows_i686_msvc 0.52.0",
2934 "windows_x86_64_gnu 0.52.0",
2935 "windows_x86_64_gnullvm 0.52.0",
2936 "windows_x86_64_msvc 0.52.0",
2937]
29142938
2915[[package]]2939[[package]]
2916name = "windows_aarch64_gnullvm"2940name = "windows_aarch64_gnullvm"
2924source = "registry+https://github.com/rust-lang/crates.io-index"2948source = "registry+https://github.com/rust-lang/crates.io-index"
2925checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"2949checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
2950
2951[[package]]
2952name = "windows_aarch64_gnullvm"
2953version = "0.52.0"
2954source = "registry+https://github.com/rust-lang/crates.io-index"
2955checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
29262956
2927[[package]]2957[[package]]
2928name = "windows_aarch64_msvc"2958name = "windows_aarch64_msvc"
2936source = "registry+https://github.com/rust-lang/crates.io-index"2966source = "registry+https://github.com/rust-lang/crates.io-index"
2937checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"2967checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
2968
2969[[package]]
2970name = "windows_aarch64_msvc"
2971version = "0.52.0"
2972source = "registry+https://github.com/rust-lang/crates.io-index"
2973checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
29382974
2939[[package]]2975[[package]]
2940name = "windows_i686_gnu"2976name = "windows_i686_gnu"
2948source = "registry+https://github.com/rust-lang/crates.io-index"2984source = "registry+https://github.com/rust-lang/crates.io-index"
2949checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"2985checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
2986
2987[[package]]
2988name = "windows_i686_gnu"
2989version = "0.52.0"
2990source = "registry+https://github.com/rust-lang/crates.io-index"
2991checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
29502992
2951[[package]]2993[[package]]
2952name = "windows_i686_msvc"2994name = "windows_i686_msvc"
2960source = "registry+https://github.com/rust-lang/crates.io-index"3002source = "registry+https://github.com/rust-lang/crates.io-index"
2961checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"3003checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
3004
3005[[package]]
3006name = "windows_i686_msvc"
3007version = "0.52.0"
3008source = "registry+https://github.com/rust-lang/crates.io-index"
3009checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
29623010
2963[[package]]3011[[package]]
2964name = "windows_x86_64_gnu"3012name = "windows_x86_64_gnu"
2972source = "registry+https://github.com/rust-lang/crates.io-index"3020source = "registry+https://github.com/rust-lang/crates.io-index"
2973checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"3021checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
3022
3023[[package]]
3024name = "windows_x86_64_gnu"
3025version = "0.52.0"
3026source = "registry+https://github.com/rust-lang/crates.io-index"
3027checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
29743028
2975[[package]]3029[[package]]
2976name = "windows_x86_64_gnullvm"3030name = "windows_x86_64_gnullvm"
2984source = "registry+https://github.com/rust-lang/crates.io-index"3038source = "registry+https://github.com/rust-lang/crates.io-index"
2985checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"3039checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
3040
3041[[package]]
3042name = "windows_x86_64_gnullvm"
3043version = "0.52.0"
3044source = "registry+https://github.com/rust-lang/crates.io-index"
3045checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
29863046
2987[[package]]3047[[package]]
2988name = "windows_x86_64_msvc"3048name = "windows_x86_64_msvc"
2996source = "registry+https://github.com/rust-lang/crates.io-index"3056source = "registry+https://github.com/rust-lang/crates.io-index"
2997checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"3057checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
3058
3059[[package]]
3060name = "windows_x86_64_msvc"
3061version = "0.52.0"
3062source = "registry+https://github.com/rust-lang/crates.io-index"
3063checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
29983064
2999[[package]]3065[[package]]
3000name = "winnow"3066name = "winnow"
3001version = "0.5.15"3067version = "0.5.31"
3002source = "registry+https://github.com/rust-lang/crates.io-index"3068source = "registry+https://github.com/rust-lang/crates.io-index"
3003checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"3069checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c"
3004dependencies = [3070dependencies = [
3005 "memchr",3071 "memchr",
3006]3072]
30243090
3025[[package]]3091[[package]]
3026name = "zeroize"3092name = "zeroize"
3027version = "1.6.0"3093version = "1.7.0"
3028source = "registry+https://github.com/rust-lang/crates.io-index"3094source = "registry+https://github.com/rust-lang/crates.io-index"
3029checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"3095checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
3030dependencies = [3096dependencies = [
3031 "zeroize_derive",3097 "zeroize_derive",
3032]3098]
3039dependencies = [3105dependencies = [
3040 "proc-macro2",3106 "proc-macro2",
3041 "quote",3107 "quote",
3042 "syn 2.0.38",3108 "syn 2.0.43",
3043]3109]
30443110
modifiedcmds/fleet/Cargo.tomldiffbeforeafterboth
1[package]1[package]
2name = "fleet"2name = "fleet"
3description = "NixOS configuration management"3description = "NixOS configuration management"
4version = "0.1.0"4version = "0.2.0"
5authors = ["Yaroslav Bolyukin <iam@lach.pw>"]5authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
6edition = "2021"6edition = "2021"
77
modifiedcmds/fleet/src/better_nix_eval.rsdiffbeforeafterboth
9use std::sync::{Arc, OnceLock};9use std::sync::{Arc, OnceLock};
1010
11use anyhow::{anyhow, bail, ensure, Context, Result};11use anyhow::{anyhow, bail, ensure, Context, Result};
12use better_command::{ClonableHandler, NixHandler, Handler, NoopHandler};12use better_command::{ClonableHandler, Handler, NixHandler, NoopHandler};
13use futures::StreamExt;13use futures::StreamExt;
14use itertools::Itertools;14use itertools::Itertools;
15use r2d2::{Pool, PooledConnection};15use r2d2::{Pool, PooledConnection};
302 let v = self.execute_expression_string(fexpr).await?;302 let v = self
303 .execute_expression_string(fexpr)
304 .await
305 .context("string expression")?;
303 Ok(serde_json::from_str(&v)?)306 serde_json::from_str(&v).context("json parse")
304 }307 }
305 async fn execute_expression_wrapping(308 async fn execute_expression_wrapping(
306 &mut self,309 &mut self,
450453
451#[macro_export]454#[macro_export]
452macro_rules! nix_expr_inner {455macro_rules! nix_expr_inner {
456 //(@munch_object FIXME: value should be arbitrary nix_expr_inner input... Time to write proc-macro?
457 (@obj($o:ident) $field:ident, $($tt:tt)*) => {{
458 $o.obj_key(
459 NixExprBuilder::string(stringify!($field)),
460 NixExprBuilder::field($field),
461 );
462 nix_expr_inner!(@obj($o) $($tt)*);
463 }};
464 (@obj($o:ident) $field:ident: $v:block, $($tt:tt)*) => {{
465 $o.obj_key(
466 NixExprBuilder::string(stringify!($field)),
467 NixExprBuilder::serialized(&$v),
468 );
469 nix_expr_inner!(@obj($o) $($tt)*);
470 }};
471 (@obj($o:ident)) => {{}};
453 (Obj { $($ident:ident: $($val:tt)+),* $(,)? }) => {{472 (Obj { $($tt:tt)* }) => {{
454 use $crate::better_nix_eval::NixExprBuilder;473 use $crate::{better_nix_eval::NixExprBuilder, nix_expr_inner};
455 let mut out = NixExprBuilder::object();474 let mut out = NixExprBuilder::object();
456 $(
457 out.obj_key(
458 NixExprBuilder::string(stringify!($ident)),
459 $crate::nix_expr_inner!($($val)+),475 nix_expr_inner!(@obj(out) $($tt)*);
460 );
461 )*
462 out.end_obj();476 out.end_obj();
463 out477 out
464 }};478 }};
522 $o.push(Index::ExprApply($crate::nix_expr_inner!($($var)+)));536 $o.push(Index::ExprApply($crate::nix_expr_inner!($($var)+)));
523 nix_go!(@o($o) $($tt)*);537 nix_go!(@o($o) $($tt)*);
524 };538 };
539 (@o($o:ident) | $($var:tt)*) => {
540 $o.push(Index::Pipe($crate::nix_expr_inner!($($var)+)));
541 };
525 (@o($o:ident)) => {};542 (@o($o:ident)) => {};
526 ($field:ident $($tt:tt)+) => {{543 ($field:ident $($tt:tt)+) => {{
527 use $crate::{nix_go, better_nix_eval::Index};544 use $crate::{nix_go, better_nix_eval::Index};
545 Apply(String),562 Apply(String),
546 Expr(NixExprBuilder),563 Expr(NixExprBuilder),
547 ExprApply(NixExprBuilder),564 ExprApply(NixExprBuilder),
565 Pipe(NixExprBuilder),
548}566}
549impl Index {567impl Index {
550 pub fn var(v: impl AsRef<str>) -> Self {568 pub fn var(v: impl AsRef<str>) -> Self {
582 Index::ExprApply(e) => {600 Index::ExprApply(e) => {
583 write!(f, "<apply>({})", e.out)601 write!(f, "<apply>({})", e.out)
584 }602 }
603 Index::Pipe(e) => {
604 write!(f, "<map>({})", e.out)
605 }
585 }606 }
586 }607 }
587}608}
604 session: NixSession,625 session: NixSession,
605 value: Option<u32>,626 value: Option<u32>,
606}627}
607fn context(full_path: Option<&[Index]>, query: &str) -> String {628fn context(op: &str, full_path: Option<&[Index]>, query: &str) -> String {
608 if let Some(full_path) = &full_path {629 if let Some(full_path) = &full_path {
609 format!("full path: {}", PathDisplay(full_path))630 format!("on {op}, full path: {}", PathDisplay(full_path))
610 } else {631 } else {
611 format!("query: {query:?}")632 format!("query: {query:?}")
612 }633 }
628 .await649 .await
629 .execute_assign(query)650 .execute_assign(query)
630 .await651 .await
631 .with_context(|| context(None, query))?;652 .with_context(|| context("new root", None, query))?;
632 Ok(Self(Arc::new(FieldInner {653 Ok(Self(Arc::new(FieldInner {
633 full_path: None,654 full_path: None,
634 session,655 session,
686 query.push_str(&index);707 query.push_str(&index);
687 query = format!("({query})");708 query = format!("({query})");
688 }709 }
710 Index::Pipe(v) => {
711 let index = Field::new(self.0.session.clone(), &v.out).await?;
712 used_fields.push(index.clone());
713 let index = format!("sess_field_{}", index.0.value.expect("value"));
714 query = format!("({index} {query})");
715 }
689 }716 }
690 }717 }
691718
720 .await747 .await
721 .execute_expression_to_json(&query)748 .execute_expression_to_json(&query)
722 .await749 .await
723 .with_context(|| context(self.0.full_path.as_deref(), &query))750 .with_context(|| context("as_json", self.0.full_path.as_deref(), &query))
724 }751 }
725 pub async fn has_field(&self, name: &str) -> Result<bool> {752 pub async fn has_field(&self, name: &str) -> Result<bool> {
726 let id = self.0.value.expect("can't list root fields");753 let id = self.0.value.expect("can't list root fields");
733 .await760 .await
734 .execute_expression_to_json(&query)761 .execute_expression_to_json(&query)
735 .await762 .await
736 .with_context(|| context(self.0.full_path.as_deref(), &query))763 .with_context(|| context("has_field", self.0.full_path.as_deref(), &query))
737 }764 }
738 pub async fn list_fields(&self) -> Result<Vec<String>> {765 pub async fn list_fields(&self) -> Result<Vec<String>> {
739 let id = self.0.value.expect("can't list root fields");766 let id = self.0.value.expect("can't list root fields");
745 .await772 .await
746 .execute_expression_to_json(&query)773 .execute_expression_to_json(&query)
747 .await774 .await
748 .with_context(|| context(self.0.full_path.as_deref(), &query))775 .with_context(|| context("list field", self.0.full_path.as_deref(), &query))
749 }776 }
750 pub async fn type_of(&self) -> Result<String> {777 pub async fn type_of(&self) -> Result<String> {
751 let id = self.0.value.expect("can't list root fields");778 let id = self.0.value.expect("can't list root fields");
757 .await784 .await
758 .execute_expression_to_json(&query)785 .execute_expression_to_json(&query)
759 .await786 .await
760 .with_context(|| context(self.0.full_path.as_deref(), &query))787 .with_context(|| context("type_of", self.0.full_path.as_deref(), &query))
761 }788 }
789 pub async fn import(&self) -> Result<Self> {
790 let import = Self::new(self.0.session.clone(), "import").await?;
791 Ok(nix_go!(self | import))
792 }
762 pub async fn build(&self) -> Result<HashMap<String, PathBuf>> {793 pub async fn build(&self) -> Result<HashMap<String, PathBuf>> {
763 let id = self.0.value.expect("can't use build on not-value");794 let id = self.0.value.expect("can't use build on not-value");
764 let query = format!(":b sess_field_{id}");795 let query = format!(":b sess_field_{id}");
773 ensure!(804 ensure!(
774 !vid.is_empty(),805 !vid.is_empty(),
775 "build failed: {}",806 "build failed: {}",
776 context(self.0.full_path.as_deref(), &query),807 context("build", self.0.full_path.as_deref(), &query),
777 );808 );
778 let Some(vid) = vid.strip_prefix("This derivation produced the following outputs:\n")809 let Some(vid) = vid.strip_prefix("This derivation produced the following outputs:\n")
779 else {810 else {
modifiedcmds/fleet/src/cmds/build_systems.rsdiffbeforeafterboth
53 fn build_attr(&self) -> String {53 fn build_attr(&self) -> String {
54 match self {54 match self {
55 PackageAction::SdImage => "sdImage".to_owned(),55 PackageAction::SdImage => "sdImage".to_owned(),
56 PackageAction::InstallationCd => "installationCd".to_owned(),56 PackageAction::InstallationCd => "isoImage".to_owned(),
57 }57 }
58 }58 }
59}59}
178 if !build.disable_rollback {178 if !build.disable_rollback {
179 let _span = info_span!("preparing").entered();179 let _span = info_span!("preparing").entered();
180 info!("preparing for rollback");180 info!("preparing for rollback");
181 let generation = get_current_generation(&host).await?;181 let generation = get_current_generation(host).await?;
182 info!(182 info!(
183 "rollback target would be {} {}",183 "rollback target would be {} {}",
184 generation.id, generation.datetime184 generation.id, generation.datetime
234 let mut switch_script = built.clone();234 let mut switch_script = built.clone();
235 switch_script.push("bin");235 switch_script.push("bin");
236 switch_script.push("switch-to-configuration");236 switch_script.push("switch-to-configuration");
237 let mut cmd = host.cmd(switch_script).await?;237 let mut cmd = host.cmd(switch_script).in_current_span().await?;
238 cmd.arg(action.name());238 cmd.arg(action.name());
239 if let Err(e) = cmd.sudo().run().in_current_span().await {239 if let Err(e) = cmd.sudo().run().in_current_span().await {
240 error!("failed to activate: {e}");240 error!("failed to activate: {e}");
285 info!("building");285 info!("building");
286 let host = config.host(&host).await?;286 let host = config.host(&host).await?;
287 let action = Action::from(self.subcommand.clone());287 let action = Action::from(self.subcommand.clone());
288 let fleet_field = &config.fleet_field;288 let fleet_config = &config.config_field;
289 let drv = nix_go!(289 let drv = nix_go!(
290 fleet_field.buildSystems(Obj {290 fleet_config.hosts[{ &host.name }].nixosSystem.config.system.build[{ action.build_attr() }]
291 localSystem: { config.local_system.clone() }
292 })[{ action.build_attr() }][{ &host.name }]
293 );291 );
294 let outputs = drv.build().await.map_err(|e| {292 let outputs = drv.build().await.map_err(|e| {
295 if action.build_attr() == "sdImage" {293 if action.build_attr() == "sdImage" {
modifiedcmds/fleet/src/cmds/info.rsdiffbeforeafterboth
37 InfoCmd::ListHosts { ref tagged } => {37 InfoCmd::ListHosts { ref tagged } => {
38 'host: for host in config.list_hosts().await? {38 'host: for host in config.list_hosts().await? {
39 if !tagged.is_empty() {39 if !tagged.is_empty() {
40 let fleet_field = &config.fleet_field;40 let config = &config.config_unchecked_field;
41 let tags: Vec<String> =41 let tags: Vec<String> =
42 nix_go_json!(fleet_field.configuredSystems[{ host.name }].config.tags);42 nix_go_json!(config.hosts[{ host.name }].nixosSystem.config.tags);
43 for tag in tagged {43 for tag in tagged {
44 if !tags.contains(tag) {44 if !tags.contains(tag) {
45 continue 'host;45 continue 'host;
modifiedcmds/fleet/src/cmds/secrets/mod.rsdiffbeforeafterboth
10use futures::StreamExt;10use futures::StreamExt;
11use itertools::Itertools;11use itertools::Itertools;
12use owo_colors::OwoColorize;12use owo_colors::OwoColorize;
13use serde::Deserialize;
13use std::{14use std::{
14 collections::HashSet,15 collections::{BTreeSet, HashSet},
15 io::{self, Cursor, Read},16 io::{self, Cursor, Read},
16 path::PathBuf,17 path::PathBuf,
17};18};
18use tabled::{Table, Tabled};19use tabled::{Table, Tabled};
19use tokio::fs::read_to_string;20use tokio::fs::read_to_string;
20use tracing::{info, info_span, warn};21use tracing::{error, info, info_span, warn, Instrument};
2122
22#[derive(Parser)]23#[derive(Parser)]
23pub enum Secret {24pub enum Secret {
92 List {},93 List {},
93}94}
9495
96#[tracing::instrument(skip(config, secret, field, prefer_identities))]
95async fn generate_shared(97async fn update_owner_set(
98 secret_name: &str,
99 config: &Config,
100 mut secret: FleetSharedSecret,
101 field: Field,
102 updated_set: &[String],
103 prefer_identities: &[String],
104) -> Result<FleetSharedSecret> {
105 let original_set = secret.owners.clone();
106
107 let set = original_set.iter().collect::<BTreeSet<_>>();
108 let expected_set = updated_set.iter().collect::<BTreeSet<_>>();
109
110 if set == expected_set {
111 info!("no need to update owner list, it is already correct");
112 return Ok(secret);
113 }
114
115 let should_regenerate = if set.difference(&expected_set).next().is_some() {
116 // TODO: Remove this warning for revokable secrets.
117 warn!("host was removed from secret owners, but until this host rebuild, the secret will still be stored on it.");
118 nix_go_json!(field.regenerateOnOwnerRemoved)
119 } else if expected_set.difference(&set).next().is_some() {
120 nix_go_json!(field.regenerateOnOwnerAdded)
121 } else {
122 false
123 };
124
125 if should_regenerate {
126 info!("secret is owner-dependent, will regenerate");
127 let generated = generate_shared(config, secret_name, field, updated_set.to_vec()).await?;
128 Ok(generated)
129 } else {
130 let identity_holder = if !prefer_identities.is_empty() {
131 prefer_identities
132 .iter()
133 .find(|i| original_set.iter().any(|s| s == *i))
134 } else {
135 secret.owners.first()
136 };
137 let Some(identity_holder) = identity_holder else {
138 bail!("no available holder found");
139 };
140
141 if let Some(data) = secret.secret.secret {
142 let host = config.host(identity_holder).await?;
143 let encrypted = host.reencrypt(data, updated_set.to_vec()).await?;
144 secret.secret.secret = Some(encrypted);
145 }
146
147 secret.owners = updated_set.to_vec();
148 Ok(secret)
149 }
150}
151
152#[derive(Deserialize)]
153#[serde(rename_all = "camelCase")]
154enum GeneratorKind {
155 Impure,
156}
157
158async fn generate_impure(
96 config: &Config,159 config: &Config,
97 display_name: &str,160 _display_name: &str,
98 secret: Field,161 secret: Field,
162 default_generator: Field,
163 owners: &[String],
99) -> Result<FleetSharedSecret> {164) -> Result<FleetSecret> {
100 Ok(if secret.has_field("generateImpure").await? {
101 let config_field = &config.config_unchecked_field;165 let config_field = &config.config_unchecked_field;
102 let generate = nix_go!(secret.generateImpure);166 let generator = nix_go!(secret.generator);
103 let owners: Vec<String> = nix_go_json!(secret.expectedOwners);
104167
105 let on: String = nix_go_json!(generate.on);168 let on: String = nix_go_json!(default_generator.impureOn);
106 let call_package = nix_go!(169 let call_package = nix_go!(
107 config_field.buildableSystems(Obj {170 config_field.buildableSystems(Obj {
108 localSystem: { config.local_system.clone() }171 localSystem: { config.local_system.clone() },
115178
116 let host = config.host(&on).await?;179 let host = config.host(&on).await?;
117180
118 let generator = nix_go!(call_package(generate.generator)(Obj {}));181 let generator = nix_go!(call_package(generator)(Obj {}));
119 let generator = generator.build().await?;182 let generator = generator.build().await?;
120 let generator = generator183 let generator = generator
121 .get("out")184 .get("out")
122 .ok_or_else(|| anyhow!("missing generateImpure out"))?;185 .ok_or_else(|| anyhow!("missing generateImpure out"))?;
123 let generator = host.remote_derivation(generator).await?;186 let generator = host.remote_derivation(generator).await?;
124187
125 let mut recipients = String::new();188 let mut recipients = String::new();
126 for owner in &owners {189 for owner in owners {
127 let key = config.key(owner).await?;190 let key = config.key(owner).await?;
128 recipients.push_str(&format!("-r \"{key}\" "));191 recipients.push_str(&format!("-r \"{key}\" "));
129 }192 }
133196
134 let mut gen = host.cmd(generator).await?;197 let mut gen = host.cmd(generator).await?;
135 gen.env("rageArgs", recipients).env("out", &out);198 gen.env("rageArgs", recipients).env("out", &out);
136 gen.run().await?;199 gen.run().await.context("impure generator")?;
137200
138 {201 {
139 let marker = host.read_file_text(format!("{out}/marker")).await?;202 let marker = host.read_file_text(format!("{out}/marker")).await?;
145 if let Some(secret) = &secret {208 if let Some(secret) = &secret {
146 ensure!(209 ensure!(
147 age::Decryptor::new(Cursor::new(&secret)).is_ok(),210 age::Decryptor::new(Cursor::new(&secret)).is_ok(),
148 "builder produced non-encrypted value as secret, this is highly insecure"211 "builder produced non-encrypted value as secret, this is highly insecure, and not allowed."
149 );212 );
150 }213 }
151214
152 let created_at = host.read_file_value(format!("{out}/created_at")).await?;215 let created_at = host.read_file_value(format!("{out}/created_at")).await?;
153 let expires_at = host.read_file_value(format!("{out}/expires_at")).await.ok();216 let expires_at = host.read_file_value(format!("{out}/expires_at")).await.ok();
154217
155 FleetSharedSecret {
156 owners,
157 secret: FleetSecret {218 Ok(FleetSecret {
158 created_at,219 created_at,
159 expires_at,220 expires_at,
160 public,221 public,
161 secret: secret.map(SecretData),222 secret: secret.map(SecretData),
162 },223 })
163 }
164 } else {
165 bail!("no generator defined for {display_name}")
166 })
167}224}
225async fn generate(
226 config: &Config,
227 display_name: &str,
228 secret: Field,
229 owners: &[String],
230) -> Result<FleetSecret> {
231 let generator = nix_go!(secret.generator);
232 // Can't properly check on nix module system level
233 {
234 let gen_ty = generator.type_of().await?;
235 if gen_ty == "null" {
236 bail!("secret has no generator defined, can't automatically generate it.");
237 }
238 if gen_ty != "lambda" {
239 bail!("generator should be lambda, got {gen_ty}");
240 }
241 }
242 let default_pkgs = &config.default_pkgs;
243 let default_call_package = nix_go!(default_pkgs.callPackage);
244 // Generators provide additional information in passthru, to access
245 // passthru we should call generator, but information about where this generator is supposed to build
246 // is located in passthru... Thus evaluating generator on host.
247 //
248 // Maybe it is also possible to do some magic with __functor?
249 //
250 // I don't want to make modules always responsible for additional secret data anyway,
251 // so it should be in derivation, and not in the secret data itself.
252 let default_generator = nix_go!(default_call_package(generator)(Obj {}));
253
254 let kind: GeneratorKind = nix_go_json!(default_generator.generatorKind);
255
256 match kind {
257 GeneratorKind::Impure => {
258 generate_impure(config, display_name, secret, default_generator, owners).await
259 }
260 }
261}
262async fn generate_shared(
263 config: &Config,
264 display_name: &str,
265 secret: Field,
266 expected_owners: Vec<String>,
267) -> Result<FleetSharedSecret> {
268 // let owners: Vec<String> = nix_go_json!(secret.expectedOwners);
269 Ok(FleetSharedSecret {
270 secret: generate(config, display_name, secret, &expected_owners).await?,
271 owners: expected_owners,
272 })
273}
168274
169async fn parse_public(275async fn parse_public(
170 public: Option<String>,276 public: Option<String>,
270 machines = shared.owners;376 machines = shared.owners;
271 }377 }
272378
273 let recipients = config379 let recipients = config.recipients(machines.clone()).await?;
274 .recipients(&machines.iter().map(String::as_str).collect_vec())
275 .await?;
276380
277 let secret = {381 let secret = {
362 remove_machines,466 remove_machines,
363 prefer_identities,467 prefer_identities,
364 } => {468 } => {
365 let mut secret = config.shared_secret(&name)?;469 let secret = config.shared_secret(&name)?;
366 if secret.secret.secret.is_none() {470 if secret.secret.secret.is_none() {
367 bail!("no secret");471 bail!("no secret");
368 }472 }
381 return Ok(());485 return Ok(());
382 }486 }
383
384 if target_machines == initial_machines {
385 warn!("secret owners are already correct");
386 return Ok(());
387 }
388487
389 let identity_holder = if !prefer_identities.is_empty() {488 let config_field = &config.config_unchecked_field;
390 prefer_identities
391 .iter()
392 .find(|i| initial_machines.iter().any(|s| s == *i))
393 } else {
394 secret.owners.first()
395 };
396 let Some(identity_holder) = identity_holder else {489 let config_field = nix_go!(config_field.configUnchecked);
397 bail!("no available holder found");
398 };
399 let target_recipients = futures::stream::iter(&target_machines)490 let field = nix_go!(config_field.sharedSecrets[{ name }]);
400 .then(|m| async { config.key(m).await })
401 .collect::<Vec<_>>()
402 .await;
403 let target_recipients =
404 target_recipients.into_iter().collect::<Result<Vec<_>>>()?;
405491
406 if let Some(data) = secret.secret.secret {492 let updated = update_owner_set(
493 &name,
494 config,
495 secret,
496 field,
497 &target_machines,
407 let host = config.host(&identity_holder).await?;498 &prefer_identities,
499 )
408 let encrypted = host.reencrypt(data, target_recipients).await?;500 .await?;
409 secret.secret.secret = Some(encrypted);
410 }
411
412 secret.owners = target_machines;
413 config.replace_shared(name, secret);501 config.replace_shared(name, updated);
414 }502 }
415 Secret::Regenerate { prefer_identities } => {503 Secret::Regenerate { prefer_identities } => {
504 info!("checking for secrets to regenerate");
416 {505 {
506 let _span = info_span!("shared").entered();
417 let expected_shared_set = config507 let expected_shared_set = config
418 .list_configured_shared()508 .list_configured_shared()
419 .await?509 .await?
420 .into_iter()510 .into_iter()
421 .collect::<HashSet<_>>();511 .collect::<HashSet<_>>();
422 let shared_set = config.list_shared().into_iter().collect::<HashSet<_>>();512 let shared_set = config.list_shared().into_iter().collect::<HashSet<_>>();
423 for removed in expected_shared_set.difference(&shared_set) {513 for missing in expected_shared_set.difference(&shared_set) {
424 info!("generating secret: {removed}");
425 let config_field = &config.config_unchecked_field;514 let config_field = &config.config_unchecked_field;
426 let config_field = nix_go!(config_field.configUnchecked);515 let config_field = nix_go!(config_field.configUnchecked);
427 let secret = nix_go!(config_field.sharedSecrets[{ removed }]);516 let secret = nix_go!(config_field.sharedSecrets[{ missing }]);
517 let expected_owners: Option<Vec<String>> =
518 nix_go_json!(secret.expectedOwners);
519 let Some(expected_owners) = expected_owners else {
520 // TODO: Might still need to regenerate
521 continue;
522 };
523 info!("generating secret: {missing}");
428 let shared = generate_shared(config, removed, secret).await?;524 let shared = generate_shared(config, missing, secret, expected_owners)
525 .in_current_span()
526 .await?;
429 config.replace_shared(removed.to_string(), shared)527 config.replace_shared(missing.to_string(), shared)
430 }528 }
431 }529 }
530 for host in config.list_hosts().await? {
531 let _span = info_span!("host", host = host.name).entered();
532 let expected_set = host
533 .list_configured_secrets()
534 .in_current_span()
535 .await?
536 .into_iter()
537 .collect::<HashSet<_>>();
538 let stored_set = config
539 .list_secrets(&host.name)
540 .into_iter()
541 .collect::<HashSet<_>>();
542 for missing in expected_set.difference(&stored_set) {
543 info!("generating secret: {missing}");
544 let secret = host.secret_field(missing).in_current_span().await?;
545 let generated =
546 match generate(config, missing, secret, &[host.name.clone()])
547 .in_current_span()
548 .await
549 {
550 Ok(v) => v,
551 Err(e) => {
552 error!("{e}");
553 continue;
554 }
555 };
556 config.insert_secret(&host.name, missing.to_string(), generated)
557 }
558 }
432 let mut to_remove = Vec::new();559 let mut to_remove = Vec::new();
433 for name in &config.list_shared() {560 for name in &config.list_shared() {
434 info!("updating secret: {name}");561 info!("updating secret: {name}");
435 let mut data = config.shared_secret(name)?;562 let data = config.shared_secret(name)?;
436 let config_field = &config.config_unchecked_field;563 let config_field = &config.config_unchecked_field;
437 let config_field = nix_go!(config_field.configUnchecked);564 let config_field = nix_go!(config_field.configUnchecked);
438 let expected_owners: Vec<String> =565 let expected_owners: Vec<String> =
442 to_remove.push(name.to_string());569 to_remove.push(name.to_string());
443 continue;570 continue;
444 }571 }
445 let set = data.owners.iter().collect::<HashSet<_>>();
446 let expected_set = expected_owners.iter().collect::<HashSet<_>>();
447 let should_remove = set.difference(&expected_set).next().is_some();
448 if set == expected_set {
449 info!("secret data is ok");
450 continue;
451 }
452572
453 let secret = nix_go!(config_field.sharedSecrets[{ name }]);573 let secret = nix_go!(config_field.sharedSecrets[{ name }]);
454 let owner_dependent: bool = nix_go_json!(secret.ownerDependent);
455 let regenerate_on_remove: bool = nix_go_json!(secret.regenerateOnOwnerRemoved);
456 #[allow(clippy::nonminimal_bool)]
457 if !owner_dependent && !(should_remove && regenerate_on_remove) {
458 warn!("reencrypting secret '{name}' for new owner set");
459 // TODO: force regeneration
460 if should_remove {
461 warn!("secret will not be regenerated for removed machines, and until host rebuild, they will still possess the ability to decode secret");
462 }
463
464 let identity_holder = if !prefer_identities.is_empty() {
465 prefer_identities
466 .iter()
467 .find(|i| data.owners.iter().any(|s| s == *i))
468 } else {
469 data.owners.first()
470 };
471 let Some(identity_holder) = identity_holder else {
472 bail!("no available holder found");
473 };
474
475 let target_recipients = futures::stream::iter(&expected_owners)
476 .then(|m| async { config.key(m).await })
477 .collect::<Vec<_>>()
478 .await;
479 let target_recipients =
480 target_recipients.into_iter().collect::<Result<Vec<_>>>()?;
481
482 if let Some(secret) = data.secret.secret {
483 let host = config.host(identity_holder).await?;
484 let encrypted = host.reencrypt(secret, target_recipients).await?;
485
486 data.secret.secret = Some(encrypted);
487 }
488 data.owners = expected_owners;
489 config.replace_shared(name.to_owned(), data);574 config.replace_shared(
490 } else {575 name.to_owned(),
576 update_owner_set(
577 &name,
491 let shared = generate_shared(config, name, secret).await?;578 config,
492 config.replace_shared(name.to_owned(), shared)579 data,
493 }580 secret,
581 &expected_owners,
582 &prefer_identities,
583 )
584 .await?,
585 );
494 }586 }
495 for k in to_remove {587 for k in to_remove {
496 config.remove_shared(&k);588 config.remove_shared(&k);
modifiedcmds/fleet/src/command.rsdiffbeforeafterboth
1use std::thread::sleep;
2use std::time::Duration;
3use std::{ffi::OsStr, pin, process::Stdio, sync::Arc, task::Poll};1use std::{ffi::OsStr, pin, process::Stdio, sync::Arc, task::Poll};
42
5use anyhow::{anyhow, Result};3use anyhow::{anyhow, Result};
9use openssh::{OverSsh, OwningCommand, Session};7use openssh::{OverSsh, OwningCommand, Session};
10use tokio::{io::AsyncRead, process::Command, select};8use tokio::{io::AsyncRead, process::Command, select};
11use tokio_util::codec::{BytesCodec, FramedRead, LinesCodec};9use tokio_util::codec::{BytesCodec, FramedRead, LinesCodec};
12use tracing::{info, debug};10use tracing::debug;
1311
14fn escape_bash(input: &str, out: &mut String) {12fn escape_bash(input: &str, out: &mut String) {
15 const TO_ESCAPE: &str = "$ !\"#&'()*,;<>?[\\]^`{|}";13 const TO_ESCAPE: &str = "$ !\"#&'()*,;<>?[\\]^`{|}";
162 self160 self
163 }161 }
164 pub fn sudo(mut self) -> Self {162 pub fn sudo(mut self) -> Self {
163 // TODO: Multiple escalation strategies.
164 // Maybe escalation should be moved to ConfigHost, to also support cases
165 // when there is no sudo on remote machine, but instead we can reconnect
166 // as root using ssh?
165 if std::env::var_os("NO_SUDO").is_some() {167 if std::env::var_os("NO_SUDO").is_some() {
166 let mut out = Self::new("su");168 let mut out = Self::new("su");
167 out.ssh_session = self.ssh_session.take();169 out.ssh_session = self.ssh_session.take();
267) -> Result<Option<Vec<u8>>> {269) -> Result<Option<Vec<u8>>> {
268 cmd.stderr(Stdio::piped());270 cmd.stderr(Stdio::piped());
269 cmd.stdout(Stdio::piped());271 cmd.stdout(Stdio::piped());
270 debug!("running command {cmd:?} on local");272 debug!("running command {str:?} on local");
271 let mut child = cmd.spawn()?;273 let mut child = cmd.spawn()?;
272 let mut stderr = child.stderr.take().unwrap();274 let mut stderr = child.stderr.take().unwrap();
273 let stdout = child.stdout.take().unwrap();275 let stdout = child.stdout.take().unwrap();
328 err_handler: &mut dyn Handler,330 err_handler: &mut dyn Handler,
329 mut out_handler: Option<&mut dyn Handler>,331 mut out_handler: Option<&mut dyn Handler>,
330) -> Result<Option<Vec<u8>>> {332) -> Result<Option<Vec<u8>>> {
331 debug!("running command {cmd:?} over ssh");333 debug!("running command {str:?} over ssh");
332 cmd.stderr(openssh::Stdio::piped());334 cmd.stderr(openssh::Stdio::piped());
333 cmd.stdout(openssh::Stdio::piped());335 cmd.stdout(openssh::Stdio::piped());
334 let mut child = cmd.spawn().await?;336 let mut child = cmd.spawn().await?;
modifiedcmds/fleet/src/host.rsdiffbeforeafterboth
14use openssh::SessionBuilder;14use openssh::SessionBuilder;
15use serde::de::DeserializeOwned;15use serde::de::DeserializeOwned;
16use tempfile::NamedTempFile;16use tempfile::NamedTempFile;
17use tracing::instrument;
1718
18use crate::{19use crate::{
19 better_nix_eval::{Field, NixSessionPool},20 better_nix_eval::{Field, NixSessionPool},
28 pub opts: FleetOpts,29 pub opts: FleetOpts,
29 pub data: Mutex<FleetData>,30 pub data: Mutex<FleetData>,
30 pub nix_args: Vec<OsString>,31 pub nix_args: Vec<OsString>,
31 /// fleetConfigurations.<name>.<localSystem>32 /// fleet_config.config
32 pub fleet_field: Field,33 pub config_field: Field,
33 /// fleet_config.configUnchecked34 /// fleet_config.unchecked.config
34 pub config_field: Field,35 pub config_unchecked_field: Field,
35 /// fleet_config.unchecked36
37 /// import nixpkgs {system = local};
36 pub config_unchecked_field: Field,38 pub default_pkgs: Field,
37}39}
3840
39#[derive(Clone)]41#[derive(Clone)]
48}50}
4951
50pub struct ConfigHost {52pub struct ConfigHost {
53 config: Config,
51 pub name: String,54 pub name: String,
52 pub local: bool,55 pub local: bool,
53 pub session: OnceLock<Arc<openssh::Session>>,56 pub session: OnceLock<Arc<openssh::Session>>,
57
58 pub nixos_config: Field,
54}59}
55impl ConfigHost {60impl ConfigHost {
56 async fn open_session(&self) -> Result<Arc<openssh::Session>> {61 async fn open_session(&self) -> Result<Arc<openssh::Session>> {
64 let session = session69 let session = session
65 .connect(&self.name)70 .connect(&self.name)
66 .await71 .await
67 .map_err(|e| anyhow!("ssh error: {e}"))?;72 .map_err(|e| anyhow!("ssh error while connecting to {}: {e}", self.name))?;
68 let session = Arc::new(session);73 let session = Arc::new(session);
69 self.session.set(session.clone()).expect("TOCTOU happened");74 self.session.set(session.clone()).expect("TOCTOU happened");
70 Ok(session)75 Ok(session)
119 let mut cmd = self.cmd("fleet-install-secrets").await?;124 let mut cmd = self.cmd("fleet-install-secrets").await?;
120 cmd.arg("reencrypt").eqarg("--secret", data.encode_z85());125 cmd.arg("reencrypt").eqarg("--secret", data.encode_z85());
121 for target in targets {126 for target in targets {
127 let key = self.config.key(&target).await?;
122 cmd.eqarg("--targets", target);128 cmd.eqarg("--targets", key);
123 }129 }
124 let encoded = cmd130 let encoded = cmd
125 .sudo()131 .sudo()
139 .arg("--substitute-on-destination")145 .arg("--substitute-on-destination")
140 .comparg("--to", format!("ssh-ng://{}", self.name))146 .comparg("--to", format!("ssh-ng://{}", self.name))
141 .arg(path);147 .arg(path);
142 nix.run_nix().await?;148 nix.run_nix().await.context("nix copy")?;
143 Ok(path.to_owned())149 Ok(path.to_owned())
144 }150 }
145 pub async fn systemctl_stop(&self, name: &str) -> Result<()> {151 pub async fn systemctl_stop(&self, name: &str) -> Result<()> {
162 cmd.run().await168 cmd.run().await
163 }169 }
170
171 pub async fn list_configured_secrets(&self) -> Result<Vec<String>> {
172 let nixos = &self.nixos_config;
173 let secrets = nix_go!(nixos.secrets);
174 let mut out = Vec::new();
175 for name in secrets.list_fields().await? {
176 let secret = nix_go!(secrets[{ name }]);
177 let is_shared: bool = nix_go_json!(secret.shared);
178 if is_shared {
179 continue;
180 }
181 out.push(name);
182 }
183 Ok(out)
184 }
185 pub async fn secret_field(&self, name: &str) -> Result<Field> {
186 let nixos = &self.nixos_config;
187 Ok(nix_go!(nixos.secrets[{ name }]))
188 }
164}189}
165190
166impl Config {191impl Config {
178 }203 }
179204
180 pub async fn host(&self, name: &str) -> Result<ConfigHost> {205 pub async fn host(&self, name: &str) -> Result<ConfigHost> {
206 let config = &self.config_unchecked_field;
207 let nixos_config = nix_go!(config.configuredSystems[{ name }].config);
181 Ok(ConfigHost {208 Ok(ConfigHost {
209 config: self.clone(),
182 name: name.to_owned(),210 name: name.to_owned(),
183 local: self.is_local(name),211 local: self.is_local(name),
184 session: OnceLock::new(),212 session: OnceLock::new(),
213 nixos_config,
185 })214 })
186 }215 }
187 pub async fn list_hosts(&self) -> Result<Vec<ConfigHost>> {216 pub async fn list_hosts(&self) -> Result<Vec<ConfigHost>> {
188 let fleet_field = &self.fleet_field;217 let config = &self.config_unchecked_field;
189 let names = nix_go!(fleet_field.configuredHosts).list_fields().await?;218 let names = nix_go!(config.hosts).list_fields().await?;
190 let mut out = vec![];219 let mut out = vec![];
191 for name in names {220 for name in names {
192 out.push(ConfigHost {221 out.push(self.host(&name).await?);
193 local: self.is_local(&name),
194 name,
195 session: OnceLock::new(),
196 })
197 }222 }
198 Ok(out)223 Ok(out)
199 }224 }
200 pub async fn system_config(&self, host: &str) -> Result<Field> {225 pub async fn system_config(&self, host: &str) -> Result<Field> {
201 let fleet_field = &self.fleet_field;226 let fleet_field = &self.config_unchecked_field;
202 Ok(nix_go!(fleet_field.configuredSystems[{ host }].config))227 Ok(nix_go!(fleet_field.hosts[{ host }].nixosSystem.config))
203 }228 }
204229
205 pub(super) fn data(&self) -> MutexGuard<FleetData> {230 pub(super) fn data(&self) -> MutexGuard<FleetData> {
233 data.shared_secrets.remove(secret);258 data.shared_secrets.remove(secret);
234 }259 }
260
261 pub fn list_secrets(&self, host: &str) -> Vec<String> {
262 let data = self.data();
263 let Some(secrets) = data.host_secrets.get(host) else {
264 return Vec::new();
265 };
266 secrets.keys().cloned().collect()
267 }
235268
236 pub fn has_secret(&self, host: &str, secret: &str) -> bool {269 pub fn has_secret(&self, host: &str, secret: &str) -> bool {
237 let data = self.data();270 let data = self.data();
319 let pool = NixSessionPool::new(directory.as_os_str().to_owned(), nix_args.clone()).await?;352 let pool = NixSessionPool::new(directory.as_os_str().to_owned(), nix_args.clone()).await?;
320 let root_field = pool.get().await?;353 let root_field = pool.get().await?;
321354
322 if self.local_system == "detect" {
323 let builtins_field = Field::field(root_field.clone(), "builtins").await?;355 let builtins_field = Field::field(root_field.clone(), "builtins").await?;
356 if self.local_system == "detect" {
324 self.local_system = nix_go_json!(builtins_field.currentSystem);357 self.local_system = nix_go_json!(builtins_field.currentSystem);
325 }358 }
326 let local_system = self.local_system.clone();359 let local_system = self.local_system.clone();
327360
328 let fleet_root = Field::field(root_field, "fleetConfigurations").await?;361 let fleet_root = Field::field(root_field, "fleetConfigurations").await?;
329
330 let fleet_field = nix_go!(fleet_root.default);362 let fleet_field = nix_go!(fleet_root.default);
363
331 let config_field = nix_go!(fleet_field.configUnchecked);364 let config_field = nix_go!(fleet_field.config);
332 let config_unchecked_field = nix_go!(fleet_field.unchecked);365 let config_unchecked_field = nix_go!(fleet_field.unchecked.config);
366
367 let import = nix_go!(builtins_field.import);
368 let overlays = nix_go!(fleet_field.overlays);
369 let nixpkgs = nix_go!(fleet_field.nixpkgs | import);
370
371 let default_pkgs = nix_go!(nixpkgs(Obj {
372 overlays,
373 system: { self.local_system.clone() },
374 }));
333375
334 let mut fleet_data_path = directory.clone();376 let mut fleet_data_path = directory.clone();
335 fleet_data_path.push("fleet.nix");377 fleet_data_path.push("fleet.nix");
342 data,384 data,
343 local_system,385 local_system,
344 nix_args,386 nix_args,
345 fleet_field,
346 config_field,387 config_field,
347 config_unchecked_field,388 config_unchecked_field,
389 default_pkgs,
348 })))390 })))
349 }391 }
350}392}
modifiedcmds/fleet/src/keys.rsdiffbeforeafterboth
43 age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))43 age::ssh::Recipient::from_str(&key).map_err(|e| anyhow!("parse recipient error: {:?}", e))
44 }44 }
4545
46 pub async fn recipients(&self, hosts: &[&str]) -> Result<Vec<impl Recipient>> {46 pub async fn recipients(&self, hosts: Vec<String>) -> Result<Vec<impl Recipient>> {
47 futures::stream::iter(hosts.iter())47 futures::stream::iter(hosts.iter())
48 .then(|m| self.recipient(m))48 .then(|m| self.recipient(m.as_ref()))
49 .try_collect::<Vec<_>>()49 .try_collect::<Vec<_>>()
50 .await50 .await
51 }51 }
modifiedcmds/fleet/src/main.rsdiffbeforeafterboth
12mod fleetdata;12mod fleetdata;
1313
14use std::ffi::OsString;14use std::ffi::OsString;
15use std::io::{stderr, stdout, Write};
16use std::process::exit;
15use std::time::Duration;17use std::time::Duration;
1618
17use anyhow::{bail, Result};19use anyhow::{bail, Result};
24use host::{Config, FleetOpts};26use host::{Config, FleetOpts};
25use human_repr::HumanCount;27use human_repr::HumanCount;
26use indicatif::{ProgressState, ProgressStyle};28use indicatif::{ProgressState, ProgressStyle};
27use tracing::info;29use tracing::{error, info};
28use tracing::{info_span, Instrument};30use tracing::{info_span, Instrument};
29use tracing_indicatif::IndicatifLayer;31use tracing_indicatif::IndicatifLayer;
30use tracing_subscriber::{prelude::*, EnvFilter};32use tracing_subscriber::{prelude::*, EnvFilter};
81}83}
8284
83#[derive(Parser)]85#[derive(Parser)]
84#[clap(version = "1.0", author)]86#[clap(version, author)]
85struct RootOpts {87struct RootOpts {
86 #[clap(flatten)]88 #[clap(flatten)]
87 fleet_opts: FleetOpts,89 fleet_opts: FleetOpts,
136 ),138 ),
137 );139 );
138140
139 let filter = EnvFilter::from_default_env();141 let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
140142
141 tracing_subscriber::registry()143 tracing_subscriber::registry()
142 .with(144 .with(
143 tracing_subscriber::fmt::layer()145 tracing_subscriber::fmt::layer()
144 .without_time()146 .without_time()
145 .with_target(false)147 .with_target(true)
146 .with_writer(indicatif_layer.get_stderr_writer())148 .with_writer(indicatif_layer.get_stderr_writer())
147 .with_filter(filter), // .withou,149 .with_filter(filter), // .withou,
148 )150 )
149 .with(indicatif_layer)151 .with(indicatif_layer)
150 .init();152 .init();
151}153}
152154
153#[tokio::main]155#[tokio::main]
156async fn main() {
157 setup_logging();
158 if let Err(e) = main_real().await {
159 error!("{e:#}");
160 exit(1);
161 }
162}
163
154async fn main() -> Result<()> {164async fn main_real() -> Result<()> {
155 setup_logging();
156 let _ = better_nix_eval::TOKIO_RUNTIME.set(tokio::runtime::Handle::current());165 let _ = better_nix_eval::TOKIO_RUNTIME.set(tokio::runtime::Handle::current());
157166
158 let nix_args = std::env::var_os("NIX_ARGS")167 let nix_args = std::env::var_os("NIX_ARGS")
modifiedflake.lockdiffbeforeafterboth
38 },38 },
39 "nixpkgs": {39 "nixpkgs": {
40 "locked": {40 "locked": {
41 "lastModified": 1703705939,41 "lastModified": 1703974965,
42 "narHash": "sha256-9s2Ep3NyRDj9HUgfv2TQUwQEanRUAmeXkvKIr/o1XbY=",42 "narHash": "sha256-dvZjLuAcLnv25bqStTL2ZICC5YSs8aynF5amRM+I6UM=",
43 "owner": "nixos",43 "owner": "nixos",
44 "repo": "nixpkgs",44 "repo": "nixpkgs",
45 "rev": "1ada32da4ba24d7310653c9ac54888bee463f455",45 "rev": "9f434bd436e2bb5615827469ed651e30c26daada",
46 "type": "github"46 "type": "github"
47 },47 },
48 "original": {48 "original": {
67 ]67 ]
68 },68 },
69 "locked": {69 "locked": {
70 "lastModified": 1703643208,70 "lastModified": 1703902408,
71 "narHash": "sha256-UL4KO8JxnD5rOycwHqBAf84lExF1/VnYMDC7b/wpPDU=",71 "narHash": "sha256-qXdWvu+tlgNjeoz8yQMRKSom6QyRROfgpmeOhwbujqw=",
72 "owner": "oxalica",72 "owner": "oxalica",
73 "repo": "rust-overlay",73 "repo": "rust-overlay",
74 "rev": "ce117f3e0de8262be8cd324ee6357775228687cf",74 "rev": "319f57cd2c34348c55970a4bf2b35afe82088681",
75 "type": "github"75 "type": "github"
76 },76 },
77 "original": {77 "original": {
modifiedflake.nixdiffbeforeafterboth
29 llvmPkgs = pkgs.buildPackages.llvmPackages_11;29 llvmPkgs = pkgs.buildPackages.llvmPackages_11;
30 rust =30 rust =
31 (pkgs.rustChannelOf {31 (pkgs.rustChannelOf {
32 date = "2023-12-26";32 date = "2023-12-29";
33 channel = "nightly";33 channel = "nightly";
34 })34 })
35 .default35 .default
modifiedlib/default.nixdiffbeforeafterboth
1{flake-utils}: {1{flake-utils}: {
2 fleetConfiguration = {2 fleetConfiguration = {
3 # TODO: Provide by fleet, instead of requesting user to provide it.
4 # This is not good that user needs to provide it, as it becomes a flake data, and fleet arbitrarily rewriting it
5 # always dirnets the flake. Instead, fleetConfiguration should return function, parameters of which should be filled
6 # by fleet itself, which is possible since fleet moving to nix repl execution.
3 data,7 data,
4 nixpkgs,8 nixpkgs,
9 overlays ? [],
5 hosts,10 hosts,
6 ...11 modules,
12 globalModules ? [],
7 } @ allConfig: let13 }: let
8 hostNames = nixpkgs.lib.attrNames hosts;14 hostNames = nixpkgs.lib.attrNames hosts;
9 config = builtins.removeAttrs allConfig ["nixpkgs" "data"];
10 fleetLib = import ./fleetLib.nix {15 fleetLib = import ./fleetLib.nix {
11 inherit nixpkgs hostNames;16 inherit nixpkgs hostNames;
12 };17 };
13 in let18 in let
14 root = nixpkgs.lib.evalModules {19 root = nixpkgs.lib.evalModules {
15 modules = (import ../modules/fleet/_modules.nix) ++ [config data];20 modules =
21 (import ../modules/fleet/_modules.nix)
22 ++ [
23 data
24 ({...}: {
25 inherit globalModules hosts;
26 })
27 ]
28 ++ modules;
16 specialArgs = {29 specialArgs = {
17 inherit nixpkgs fleetLib;30 inherit nixpkgs fleetLib;
18 };31 };
25 withData = {38 withData = {
26 root,39 root,
27 data,40 data,
28 }: rec {41 }: {
29 configuredHosts = root.config.hosts;42 configuredHosts = root.config.hosts;
30 configuredUncheckedHosts = root.config.hosts;
31 configuredSystems = configuredSystemsWithExtraModules [];
32 configuredSystemsWithExtraModules = extraModules:
33 nixpkgs.lib.listToAttrs (
34 map
35 (
36 name: {
37 inherit name;
38 value = nixpkgs.lib.nixosSystem {
39 system = configuredHosts.${name}.system;
40 modules = configuredHosts.${name}.modules ++ extraModules;
41 specialArgs = {
42 inherit fleetLib;
43 fleet = fleetLib.hostsToAttrs (host: configuredSystems.${host}.config);
44 };
45 };
46 }
47 )
48 (builtins.attrNames root.config.hosts)
49 );
50 buildableSystems = {localSystem}: let
51 buildConfigurationModule = {config, ...}: {
52 # Equivalent to nixpkgs.localSystem
53 # nixpkgs.system = localSystem;
54 nixpkgs.buildPlatform.system = localSystem;
55 };
56 in
57 configuredSystemsWithExtraModules [
58 buildConfigurationModule
59 ];
60 buildSystems = {localSystem}: let
61 buildConfigurationModule = {config, ...}: {
62 # Equivalent to nixpkgs.localSystem
63 # nixpkgs.system = localSystem;
64 nixpkgs.buildPlatform.system = localSystem;
65 };
66 in {
67 toplevel = builtins.mapAttrs (_name: value: value.config.system.build.toplevel) (configuredSystemsWithExtraModules [
68 buildConfigurationModule
69 ({...}: {
70 buildTarget = "toplevel";
71 })
72 ]);
73 sdImage = builtins.mapAttrs (_name: value: value.config.system.build.sdImage) (configuredSystemsWithExtraModules [
74 buildConfigurationModule
75 #(nixpkgs + "/nixos/modules/installer/sd-card/sd-image-aarch64-installer.nix")
76 ({...}: {
77 buildTarget = "sd-image";
78 })
79 ]);
80 installationCd = builtins.mapAttrs (_name: value: value.config.system.build.isoImage) (configuredSystemsWithExtraModules [
81 buildConfigurationModule
82 (nixpkgs + "/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix")
83 ({lib, ...}: {
84 buildTarget = "installation-cd";
85 # Needed for https://github.com/NixOS/nixpkgs/issues/58959
86 boot.supportedFilesystems = lib.mkForce ["btrfs" "reiserfs" "vfat" "f2fs" "xfs" "ntfs" "cifs"];
87 })
88 ]);
89 };
90 configUnchecked = root.config;43 config = root.config;
91 };44 };
92 defaultData = withData {45 defaultData = withData {
93 inherit data;46 inherit data;
94 root = checkedRoot;47 root = checkedRoot;
95 };48 };
96 uncheckedData = withData {inherit data root;};49 uncheckedData = withData {inherit data root;};
97 in rec {50 in {
98 inherit (defaultData) configuredHosts configuredSystems buildSystems configUnchecked buildableSystems;51 inherit nixpkgs overlays;
99 unchecked = {
100 inherit (uncheckedData) configuredHosts configuredSystems buildSystems configUnchecked buildableSystems;52 inherit (defaultData) configuredHosts configuredSystems config buildableSystems;
101 };
102 injectData = data: let53 unchecked = {
103 injectedData = withData data;
104 in {
105 inherit (injectedData) configuredHosts configuredSystems buildSystems configUnchecked;54 inherit (uncheckedData) configuredHosts configuredSystems config buildableSystems;
106 };55 };
107 };56 };
108}57}
modifiedmodules/fleet/meta.nixdiffbeforeafterboth
2 lib,
3 fleetLib,
4 config,
5 nixpkgs,
6 ...
7}:
2let8with lib; let
3 host = with types; {9 hostModule = with types;
10 {...} @ hostConfig: {
4 options = {11 options = {
5 modules = mkOption {12 modules = mkOption {
6 type = listOf (mkOptionType {13 type = listOf (mkOptionType {
20 type = str;27 type = str;
21 description = "Encryption key";28 description = "Encryption key";
22 };29 };
30 nixosSystem = mkOption {
31 type = unspecified;
32 description = "Nixos configuration";
33 };
23 };34 };
35 config.nixosSystem = nixpkgs.lib.nixosSystem {
36 inherit (hostConfig.config) system modules;
37 specialArgs = {
38 inherit fleetLib;
39 fleet = fleetLib.hostsToAttrs (host: config.hosts.${host}.nixosSystem.config);
40 };
41 };
24 };42 };
43 overlayType = mkOptionType {
44 name = "nixpkgs-overlay";
45 description = "nixpkgs overlay";
46 check = lib.isFunction;
47 merge = lib.mergeOneOption;
48 };
25in49in {
26{
27 options = with types; {50 options = with types; {
28 hosts = mkOption {51 hosts = mkOption {
29 type = attrsOf (submodule host);52 type = attrsOf (submodule hostModule);
30 default = { };53 default = {};
31 description = "Configurations of individual hosts";54 description = "Configurations of individual hosts";
32 };55 };
40 description = "Modules, which should be added to every system";63 description = "Modules, which should be added to every system";
41 default = [ ];64 default = [];
42 };65 };
66 overlays = mkOption {
67 default = [];
68 type = listOf overlayType;
69 };
43 };70 };
44 config = {71 config = {
45 hosts = fleetLib.hostsToAttrs (host: {72 hosts = fleetLib.hostsToAttrs (host: {
46 modules = config.globalModules;73 modules =
74 config.globalModules
75 ++ [
76 ({...}: {
77 nixpkgs.overlays = config.overlays;
78 })
79 ];
47 });80 });
48 globalModules = import ../../nixos/modules/module-list.nix;81 globalModules = import ../../nixos/modules/module-list.nix;
49 };82 };
modifiedmodules/fleet/secrets.nixdiffbeforeafterboth
1{ lib, fleetLib, config, ... }: with lib; with fleetLib;1{ lib, fleetLib, config, ... }: with lib; with fleetLib;
2let2let
3 sharedSecret = with types; {3 sharedSecret = with types; ({config, ...}: {
4 options = {4 options = {
5 expectedOwners = mkOption {5 expectedOwners = mkOption {
6 type = listOf str;6 type = nullOr (listOf str);
7 description = ''7 description = ''
8 List of hosts to encrypt secret for8 List of hosts to encrypt secret for. null if managed by user (= via owners field from fleet.nix)
99
10 Secrets would be decrypted and stored to /run/secrets/$\{name} on owners10 Secrets would be decrypted and stored to /run/secrets/$\{name} on owners
11 '';11 '';
12 default = [ ];
13 };12 };
13 # TODO: Aren't those options may be just desugared to data/expectedData?
14 ownerDependent = mkOption {14 regenerateOnOwnerAdded = mkOption {
15 type = bool;15 type = bool;
16 description = "Is this secret owner-dependent, and needs to be regenerated on ownership set change, or it may be just reencrypted";16 description = ''
17 Is this secret owner-dependent, and needs to be regenerated on ownership set change, or it may be just reencrypted.
18
19 You want to have this option set to true, when this secret contains some reference to its owners, i.e x509 SANs.
20 '';
17 };21 };
18 generateImpure = mkOption {
19 type = unspecified;
20 };
21 generator = mkOption {22 regenerateOnOwnerRemoved = mkOption {
22 type = nullOr (submodule {
23 packages = mkOption {
24 type = attrsOf package;
25 description = ''23 default = config.regenerateOnOwnerAdded;
26 Derivation to execute for shared secret generation (key = system).
27 This derivation should produce directory, with exactly two files:
28 - publicData
29 - encryptedSecretData
30
31 If null - secret value may only be created manually.
32 '';
33 };
34 expectedData = mkOption {
35 type = types.unspecified;24 type = bool;
36 description = "Data expected to be used for secret generation, if doesn't match specified - secret should be regenerated";
37 };
38 dependencies = mkOption {
39 type = listOf str;
40 description = ''25 description = ''
41 List of secrets, on which this secret depends.26 Should this secret be removed on owner removal, or it may be just reencrypted
4227
43 During generation, generator command will be ran on host, which already has specified secrets generated.28 Most probably its value should be equal to regenerateOnOwnerAdded, override only if you know what are you doing.
44 '';29 Contrary to regenerateOnOwnerAdded, you may want to set this option to false, when host permissions are revoked
45 default = [];30 in some other way than by this secret ownership, I.e by firewall/etc.
46 };31 '';
47 data = mkOption {
48 type = types.unspecified;
49 description = "Data used for secret generation. Imported from fleet.nix";
50 default = null;
51 internal = true;
52 };
53 });
54 default = null;
55 };32 };
56 expireIn = mkOption {33 generator = mkOption {
57 type = nullOr int;34 type = nullOr unspecified;
58 description = "Time in hours, in which this secret should be regenerated";35 description = "Derivation to evaluate for secret generation";
59 default = null;36 default = null;
60 };37 };
61 createdAt = mkOption {38 createdAt = mkOption {
62 type = nullOr str;39 type = nullOr str;
40 description = "When this secret was (re)generated";
63 default = null;41 default = null;
64 };42 };
65 expiresAt = mkOption {43 expiresAt = mkOption {
66 type = nullOr str;44 type = nullOr str;
45 description = "On which date this secret will expire, someone should regenerate this secret before it expires.";
67 default = null;46 default = null;
68 };47 };
6948
78 '';57 '';
79 default = [ ];58 default = [ ];
80 };59 };
60 # TODO: Make secret generator generate arbitrary number of secret/public parts?
61 # Make it generate a folder, where all files except suffixed by .enc are public, and the rest are secret?
62 # How should modules refer to those files then?
81 public = mkOption {63 public = mkOption {
82 type = nullOr str;64 type = nullOr str;
83 description = "Secret public data. Imported from fleet.nix";65 description = "Secret public data. Imported from fleet.nix";
90 internal = true;72 internal = true;
91 };73 };
92 };74 };
93 };75 });
94 hostSecret = with types; {76 hostSecret = with types; {
95 options = {77 options = {
96 createdAt = mkOption {78 createdAt = mkOption {
132 config = {114 config = {
133 assertions = mapAttrsToList115 assertions = mapAttrsToList
134 (name: secret: {116 (name: secret: {
135 assertion = builtins.sort (a: b: a < b) secret.owners == builtins.sort (a: b: a < b) secret.expectedOwners;117 assertion = secret.expectedOwners == null || builtins.sort (a: b: a < b) secret.owners == builtins.sort (a: b: a < b) secret.expectedOwners;
136 message = "Shared secret ${name} is expected to be encrypted for ${builtins.toJSON secret.expectedOwners}, but it is encrypted for ${builtins.toJSON secret.owners}. Run fleet secrets regenerate to fix";118 message = "Shared secret ${name} is expected to be encrypted for ${builtins.toJSON secret.expectedOwners}, but it is encrypted for ${builtins.toJSON secret.owners}. Run fleet secrets regenerate to fix";
137 })119 })
138 config.sharedSecrets;120 config.sharedSecrets;
141 let123 let
142 cleanupSecret = (secretName: v: {124 cleanupSecret = (secretName: v: {
143 inherit (v) public secret;125 inherit (v) public secret;
126 shared = true;
144 });127 });
145 in128 in
146 [129 [
modifiednixos/secrets.nixdiffbeforeafterboth
5let5let
6 sysConfig = config;6 sysConfig = config;
7 secretType = types.submodule ({ config, ... }: {7 secretType = types.submodule ({ config, ... }: {
8 config = let secretName = config._module.args.name; in rec {8 config = let secretName = config._module.args.name; in {
9 stableSecretPath = mkOptionDefault "/run/secrets/secret-stable-${secretName}";9 stableSecretPath = mkOptionDefault "/run/secrets/secret-stable-${secretName}";
10 secretPath = mkOptionDefault "/run/secrets/secret-${config.secretHash}-${secretName}";10 secretPath = mkOptionDefault "/run/secrets/secret-${config.secretHash}-${secretName}";
11 secretHash = mkOptionDefault (if config.secret != null then (builtins.hashString "sha1" config.secret) else throw "secret is not defined for secret ${secretName}");11 secretHash = mkOptionDefault (if config.secret != null then (builtins.hashString "sha1" config.secret) else throw "secret is not defined for secret ${secretName}");
14 publicPath = mkOptionDefault "/run/secrets/public-${config.publicHash}-${secretName}";14 publicPath = mkOptionDefault "/run/secrets/public-${config.publicHash}-${secretName}";
15 publicHash = mkOptionDefault (if config.public != null then (builtins.hashString "sha1" config.public) else throw "public is not defined for secret ${secretName}");15 publicHash = mkOptionDefault (if config.public != null then (builtins.hashString "sha1" config.public) else throw "public is not defined for secret ${secretName}");
16 };16 };
17 options = {17 options = with types; {
18 shared = mkOption {
19 description = "Is this secret owned by this machine, or propagated from shared secrets";
20 default = false;
21 };
22
23 generator = mkOption {
24 type = nullOr unspecified;
25 description = "Derivation to evaluate for secret generation";
26 default = null;
27 };
28
18 public = mkOption {29 public = mkOption {
19 type = types.nullOr types.str;30 type = nullOr str;
20 description = "Secret public data";31 description = "Secret public data";
21 default = null;32 default = null;
22 };33 };
23 secret = mkOption {34 secret = mkOption {
24 type = types.nullOr types.str;35 type = nullOr str;
25 description = "Encrypted secret data";36 description = "Encrypted secret data";
26 default = null;37 default = null;
27 };38 };
28 mode = mkOption {39 mode = mkOption {
29 type = types.str;40 type = str;
30 description = "Secret mode";41 description = "Secret mode";
31 default = "0440";42 default = "0440";
32 };43 };
33 owner = mkOption {44 owner = mkOption {
34 type = types.str;45 type = str;
35 description = "Owner of the secret";46 description = "Owner of the secret";
36 default = "root";47 default = "root";
37 };48 };
38 group = mkOption {49 group = mkOption {
39 type = types.str;50 type = str;
40 description = "Group of the secret";51 description = "Group of the secret";
41 default = sysConfig.users.users.${config.owner}.group;52 default = sysConfig.users.users.${config.owner}.group;
42 };53 };
4354
44 secretHash = mkOption {55 secretHash = mkOption {
45 type = types.str;56 type = str;
46 description = "Hash of .secret field";57 description = "Hash of .secret field";
47 };58 };
48 publicHash = mkOption {59 publicHash = mkOption {
49 type = types.str;60 type = str;
50 description = "Hash of .public field";61 description = "Hash of .public field";
51 };62 };
5263
53 stableSecretPath = mkOption {64 stableSecretPath = mkOption {
54 type = types.str;65 type = str;
55 description = ''66 description = ''
56 Use this, if target process supports re-reading of secret from disk,67 Use this, if target process supports re-reading of secret from disk,
57 and doesn't needs to be restarted when secret is updated in file68 and doesn't needs to be restarted when secret is updated in file
58 '';69 '';
59 };70 };
60 secretPath = mkOption {71 secretPath = mkOption {
61 type = types.str;72 type = str;
62 description = "Path to decrypted secret, suffixed with contents hash";73 description = "Path to decrypted secret, suffixed with contents hash";
63 };74 };
6475
65 stablePublicPath = mkOption {76 stablePublicPath = mkOption {
66 type = types.str;77 type = str;
67 description = ''78 description = ''
68 Use this, if target process supports re-reading of secret from disk,79 Use this, if target process supports re-reading of secret from disk,
69 and doesn't needs to be restarted when secret is updated in file80 and doesn't needs to be restarted when secret is updated in file
70 '';81 '';
71 };82 };
72 publicPath = mkOption {83 publicPath = mkOption {
73 type = types.str;84 type = str;
74 description = "Path to the public part of secret";85 description = "Path to the public part of secret";
75 };86 };
76 };87 };