git.delta.rocks / jrsonnet / refs/commits / 1470de8a447c

difftreelog

feat minimal rollback support

Lach2025-06-18parent: #11412de.patch.diff
in: trunk

20 files changed

modifiedCargo.lockdiffbeforeafterboth
83 "i18n-embed",83 "i18n-embed",
84 "i18n-embed-fl",84 "i18n-embed-fl",
85 "lazy_static",85 "lazy_static",
86 "nom",86 "nom 7.1.3",
87 "num-traits",87 "num-traits",
88 "pin-project",88 "pin-project",
89 "rand",89 "rand 0.8.5",
90 "rsa",90 "rsa",
91 "rust-embed",91 "rust-embed",
92 "scrypt",92 "scrypt",
107 "cookie-factory",107 "cookie-factory",
108 "hkdf",108 "hkdf",
109 "io_tee",109 "io_tee",
110 "nom",110 "nom 7.1.3",
111 "rand",111 "rand 0.8.5",
112 "secrecy",112 "secrecy",
113 "sha2",113 "sha2",
114]114]
233dependencies = [233dependencies = [
234 "proc-macro2",234 "proc-macro2",
235 "quote",235 "quote",
236 "syn 2.0.87",236 "syn",
237]237]
238238
239[[package]]239[[package]]
240name = "async-trait"240name = "async-trait"
241version = "0.1.83"241version = "0.1.88"
242source = "registry+https://github.com/rust-lang/crates.io-index"242source = "registry+https://github.com/rust-lang/crates.io-index"
243checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"243checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
244dependencies = [244dependencies = [
245 "proc-macro2",245 "proc-macro2",
246 "quote",246 "quote",
247 "syn 2.0.87",247 "syn",
248]248]
249249
250[[package]]250[[package]]
395 "regex",395 "regex",
396 "rustc-hash",396 "rustc-hash",
397 "shlex",397 "shlex",
398 "syn 2.0.87",398 "syn",
399 "which",399 "which",
400]400]
401401
402[[package]]402[[package]]
403name = "bitflags"403name = "bitflags"
404version = "2.6.0"404version = "2.9.1"
405source = "registry+https://github.com/rust-lang/crates.io-index"405source = "registry+https://github.com/rust-lang/crates.io-index"
406checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"406checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
407dependencies = [407dependencies = [
408 "serde",408 "serde",
409]409]
493source = "registry+https://github.com/rust-lang/crates.io-index"493source = "registry+https://github.com/rust-lang/crates.io-index"
494checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"494checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
495dependencies = [495dependencies = [
496 "nom",496 "nom 7.1.3",
497]497]
498498
499[[package]]499[[package]]
534534
535[[package]]535[[package]]
536name = "chrono"536name = "chrono"
537version = "0.4.38"537version = "0.4.41"
538source = "registry+https://github.com/rust-lang/crates.io-index"538source = "registry+https://github.com/rust-lang/crates.io-index"
539checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"539checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
540dependencies = [540dependencies = [
541 "android-tzdata",541 "android-tzdata",
542 "iana-time-zone",542 "iana-time-zone",
543 "js-sys",543 "js-sys",
544 "num-traits",544 "num-traits",
545 "serde",545 "serde",
546 "wasm-bindgen",546 "wasm-bindgen",
547 "windows-targets",547 "windows-link",
548]548]
549549
550[[package]]550[[package]]
609source = "registry+https://github.com/rust-lang/crates.io-index"609source = "registry+https://github.com/rust-lang/crates.io-index"
610checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"610checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
611dependencies = [611dependencies = [
612 "heck 0.5.0",612 "heck",
613 "proc-macro2",613 "proc-macro2",
614 "quote",614 "quote",
615 "syn 2.0.87",615 "syn",
616]616]
617617
618[[package]]618[[package]]
646source = "registry+https://github.com/rust-lang/crates.io-index"646source = "registry+https://github.com/rust-lang/crates.io-index"
647checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"647checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
648
649[[package]]
650name = "convert_case"
651version = "0.7.1"
652source = "registry+https://github.com/rust-lang/crates.io-index"
653checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7"
654dependencies = [
655 "unicode-segmentation",
656]
648657
649[[package]]658[[package]]
650name = "cookie-factory"659name = "cookie-factory"
684693
685[[package]]694[[package]]
686name = "crossterm"695name = "crossterm"
687version = "0.28.1"696version = "0.29.0"
688source = "registry+https://github.com/rust-lang/crates.io-index"697source = "registry+https://github.com/rust-lang/crates.io-index"
689checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"698checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
690dependencies = [699dependencies = [
691 "bitflags",700 "bitflags",
692 "crossterm_winapi",701 "crossterm_winapi",
702 "derive_more",
703 "document-features",
693 "filedescriptor",704 "filedescriptor",
694 "mio",705 "mio",
695 "parking_lot",706 "parking_lot",
696 "rustix",707 "rustix 1.0.7",
697 "signal-hook",708 "signal-hook",
698 "signal-hook-mio",709 "signal-hook-mio",
699 "winapi",710 "winapi",
715checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"726checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
716dependencies = [727dependencies = [
717 "generic-array",728 "generic-array",
718 "rand_core",729 "rand_core 0.6.4",
719 "typenum",730 "typenum",
720]731]
721732
752dependencies = [763dependencies = [
753 "proc-macro2",764 "proc-macro2",
754 "quote",765 "quote",
755 "syn 2.0.87",766 "syn",
756]767]
757768
758[[package]]769[[package]]
781792
782[[package]]793[[package]]
783name = "deranged"794name = "deranged"
784version = "0.3.11"795version = "0.4.0"
785source = "registry+https://github.com/rust-lang/crates.io-index"796source = "registry+https://github.com/rust-lang/crates.io-index"
786checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"797checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
787dependencies = [798dependencies = [
788 "powerfmt",799 "powerfmt",
789 "serde",800 "serde",
790]801]
802
803[[package]]
804name = "derive_more"
805version = "2.0.1"
806source = "registry+https://github.com/rust-lang/crates.io-index"
807checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
808dependencies = [
809 "derive_more-impl",
810]
811
812[[package]]
813name = "derive_more-impl"
814version = "2.0.1"
815source = "registry+https://github.com/rust-lang/crates.io-index"
816checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
817dependencies = [
818 "convert_case",
819 "proc-macro2",
820 "quote",
821 "syn",
822]
791823
792[[package]]824[[package]]
793name = "digest"825name = "digest"
809dependencies = [841dependencies = [
810 "proc-macro2",842 "proc-macro2",
811 "quote",843 "quote",
812 "syn 2.0.87",844 "syn",
813]845]
846
847[[package]]
848name = "document-features"
849version = "0.2.11"
850source = "registry+https://github.com/rust-lang/crates.io-index"
851checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
852dependencies = [
853 "litrs",
854]
814855
815[[package]]856[[package]]
816name = "ed25519"857name = "ed25519"
830dependencies = [871dependencies = [
831 "curve25519-dalek",872 "curve25519-dalek",
832 "ed25519",873 "ed25519",
833 "rand_core",
834 "serde",874 "serde",
835 "sha2",875 "sha2",
836 "subtle",876 "subtle",
857897
858[[package]]898[[package]]
859name = "errno"899name = "errno"
860version = "0.3.9"900version = "0.3.12"
861source = "registry+https://github.com/rust-lang/crates.io-index"901source = "registry+https://github.com/rust-lang/crates.io-index"
862checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"902checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
863dependencies = [903dependencies = [
864 "libc",904 "libc",
865 "windows-sys 0.52.0",905 "windows-sys 0.59.0",
866]906]
867907
868[[package]]908[[package]]
924 "hostname",964 "hostname",
925 "human-repr",965 "human-repr",
926 "indicatif",966 "indicatif",
927 "itertools 0.13.0",967 "itertools 0.14.0",
928 "nix-eval",968 "nix-eval",
929 "nixlike",969 "nixlike",
930 "nom",970 "nom 8.0.0",
931 "openssh",971 "openssh",
932 "owo-colors",972 "owo-colors",
933 "peg",973 "peg",
958 "futures",998 "futures",
959 "hostname",999 "hostname",
960 "indoc",1000 "indoc",
961 "itertools 0.13.0",1001 "itertools 0.14.0",
962 "nix-eval",1002 "nix-eval",
963 "nixlike",1003 "nixlike",
964 "nom",1004 "nom 8.0.0",
965 "openssh",1005 "openssh",
966 "rand",1006 "rand 0.9.1",
967 "serde",1007 "serde",
968 "serde_json",1008 "serde_json",
1009 "tabled",
969 "tempfile",1010 "tempfile",
1011 "time",
970 "tokio",1012 "tokio",
971 "tokio-util",1013 "tokio-util",
972 "tracing",1014 "tracing",
983 "ed25519-dalek",1025 "ed25519-dalek",
984 "fleet-shared",1026 "fleet-shared",
985 "hex",1027 "hex",
986 "rand",1028 "rand 0.9.1",
987 "x25519-dalek",1029 "x25519-dalek",
988]1030]
9891031
1119dependencies = [1161dependencies = [
1120 "proc-macro2",1162 "proc-macro2",
1121 "quote",1163 "quote",
1122 "syn 2.0.87",1164 "syn",
1123]1165]
11241166
1125[[package]]1167[[package]]
1170dependencies = [1212dependencies = [
1171 "cfg-if",1213 "cfg-if",
1172 "libc",1214 "libc",
1173 "wasi",1215 "wasi 0.11.0+wasi-snapshot-preview1",
1174]1216]
1217
1218[[package]]
1219name = "getrandom"
1220version = "0.3.3"
1221source = "registry+https://github.com/rust-lang/crates.io-index"
1222checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
1223dependencies = [
1224 "cfg-if",
1225 "libc",
1226 "r-efi",
1227 "wasi 0.14.2+wasi-0.2.4",
1228]
11751229
1176[[package]]1230[[package]]
1177name = "ghash"1231name = "ghash"
1238source = "registry+https://github.com/rust-lang/crates.io-index"1292source = "registry+https://github.com/rust-lang/crates.io-index"
1239checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"1293checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
1240
1241[[package]]
1242name = "heck"
1243version = "0.4.1"
1244source = "registry+https://github.com/rust-lang/crates.io-index"
1245checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
12461294
1247[[package]]1295[[package]]
1248name = "heck"1296name = "heck"
12971345
1298[[package]]1346[[package]]
1299name = "hostname"1347name = "hostname"
1300version = "0.4.0"1348version = "0.4.1"
1301source = "registry+https://github.com/rust-lang/crates.io-index"1349source = "registry+https://github.com/rust-lang/crates.io-index"
1302checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba"1350checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65"
1303dependencies = [1351dependencies = [
1304 "cfg-if",1352 "cfg-if",
1305 "libc",1353 "libc",
1306 "windows",1354 "windows-link",
1307]1355]
13081356
1309[[package]]1357[[package]]
1463 "proc-macro2",1511 "proc-macro2",
1464 "quote",1512 "quote",
1465 "strsim",1513 "strsim",
1466 "syn 2.0.87",1514 "syn",
1467 "unic-langid",1515 "unic-langid",
1468]1516]
14691517
1477 "i18n-config",1525 "i18n-config",
1478 "proc-macro2",1526 "proc-macro2",
1479 "quote",1527 "quote",
1480 "syn 2.0.87",1528 "syn",
1481]1529]
14821530
1483[[package]]1531[[package]]
1619 "either",1667 "either",
1620]1668]
1669
1670[[package]]
1671name = "itertools"
1672version = "0.14.0"
1673source = "registry+https://github.com/rust-lang/crates.io-index"
1674checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
1675dependencies = [
1676 "either",
1677]
16211678
1622[[package]]1679[[package]]
1623name = "itoa"1680name = "itoa"
16511708
1652[[package]]1709[[package]]
1653name = "libc"1710name = "libc"
1654version = "0.2.164"1711version = "0.2.174"
1655source = "registry+https://github.com/rust-lang/crates.io-index"1712source = "registry+https://github.com/rust-lang/crates.io-index"
1656checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"1713checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
16571714
1658[[package]]1715[[package]]
1659name = "libloading"1716name = "libloading"
1693source = "registry+https://github.com/rust-lang/crates.io-index"1750source = "registry+https://github.com/rust-lang/crates.io-index"
1694checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"1751checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
1752
1753[[package]]
1754name = "linux-raw-sys"
1755version = "0.9.4"
1756source = "registry+https://github.com/rust-lang/crates.io-index"
1757checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
1758
1759[[package]]
1760name = "litrs"
1761version = "0.4.1"
1762source = "registry+https://github.com/rust-lang/crates.io-index"
1763checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
16951764
1696[[package]]1765[[package]]
1697name = "lock_api"1766name = "lock_api"
1778 "hermit-abi 0.3.9",1847 "hermit-abi 0.3.9",
1779 "libc",1848 "libc",
1780 "log",1849 "log",
1781 "wasi",1850 "wasi 0.11.0+wasi-snapshot-preview1",
1782 "windows-sys 0.52.0",1851 "windows-sys 0.52.0",
1783]1852]
17841853
17901859
1791[[package]]1860[[package]]
1792name = "nix"1861name = "nix"
1793version = "0.29.0"1862version = "0.30.1"
1794source = "registry+https://github.com/rust-lang/crates.io-index"1863source = "registry+https://github.com/rust-lang/crates.io-index"
1795checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"1864checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
1796dependencies = [1865dependencies = [
1797 "bitflags",1866 "bitflags",
1798 "cfg-if",1867 "cfg-if",
1807 "anyhow",1876 "anyhow",
1808 "better-command",1877 "better-command",
1809 "futures",1878 "futures",
1810 "itertools 0.13.0",1879 "itertools 0.14.0",
1811 "nixlike",1880 "nixlike",
1812 "r2d2",1881 "r2d2",
1813 "regex",1882 "regex",
1814 "serde",1883 "serde",
1815 "serde_json",1884 "serde_json",
1816 "thiserror 2.0.3",1885 "thiserror 2.0.12",
1817 "tokio",1886 "tokio",
1818 "tokio-util",1887 "tokio-util",
1819 "tracing",1888 "tracing",
1839 "serde",1908 "serde",
1840 "serde-transcode",1909 "serde-transcode",
1841 "serde_json",1910 "serde_json",
1842 "thiserror 2.0.3",1911 "thiserror 2.0.12",
1843]1912]
18441913
1845[[package]]1914[[package]]
1871 "minimal-lexical",1940 "minimal-lexical",
1872]1941]
1942
1943[[package]]
1944name = "nom"
1945version = "8.0.0"
1946source = "registry+https://github.com/rust-lang/crates.io-index"
1947checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405"
1948dependencies = [
1949 "memchr",
1950]
18731951
1874[[package]]1952[[package]]
1875name = "nu-ansi-term"1953name = "nu-ansi-term"
1893 "num-integer",1971 "num-integer",
1894 "num-iter",1972 "num-iter",
1895 "num-traits",1973 "num-traits",
1896 "rand",1974 "rand 0.8.5",
1897 "smallvec",1975 "smallvec",
1898 "zeroize",1976 "zeroize",
1899]1977]
19632041
1964[[package]]2042[[package]]
1965name = "openssh"2043name = "openssh"
1966version = "0.11.3"2044version = "0.11.5"
1967source = "registry+https://github.com/rust-lang/crates.io-index"2045source = "registry+https://github.com/rust-lang/crates.io-index"
1968checksum = "b52987a10526b8daef7f1946b0aadfc214479f897ba624776327fd3beec2722c"2046checksum = "ea0bb128ba90e86bc55dae66031935f361cda4cbc1f011547c55a7d80079bc3e"
1969dependencies = [2047dependencies = [
1970 "libc",2048 "libc",
1971 "once_cell",2049 "once_cell",
1972 "shell-escape",2050 "shell-escape",
1973 "tempfile",2051 "tempfile",
1974 "thiserror 2.0.3",2052 "thiserror 2.0.12",
1975 "tokio",2053 "tokio",
1976]2054]
19772055
19832061
1984[[package]]2062[[package]]
1985name = "owo-colors"2063name = "owo-colors"
1986version = "4.1.0"2064version = "4.2.1"
1987source = "registry+https://github.com/rust-lang/crates.io-index"2065source = "registry+https://github.com/rust-lang/crates.io-index"
1988checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56"2066checksum = "26995317201fa17f3656c36716aed4a7c81743a9634ac4c99c0eeda495db0cec"
1989dependencies = [2067dependencies = [
1990 "supports-color 2.1.0",2068 "supports-color 2.1.0",
1991 "supports-color 3.0.1",2069 "supports-color 3.0.1",
1992]2070]
19932071
1994[[package]]2072[[package]]
1995name = "papergrid"2073name = "papergrid"
1996version = "0.12.0"2074version = "0.17.0"
1997source = "registry+https://github.com/rust-lang/crates.io-index"2075source = "registry+https://github.com/rust-lang/crates.io-index"
1998checksum = "c7419ad52a7de9b60d33e11085a0fe3df1fbd5926aa3f93d3dd53afbc9e86725"2076checksum = "6978128c8b51d8f4080631ceb2302ab51e32cc6e8615f735ee2f83fd269ae3f1"
1999dependencies = [2077dependencies = [
2000 "bytecount",2078 "bytecount",
2001 "fnv",2079 "fnv",
2002 "unicode-width 0.1.11",2080 "unicode-width 0.2.0",
2003]2081]
20042082
2005[[package]]2083[[package]]
20432121
2044[[package]]2122[[package]]
2045name = "peg"2123name = "peg"
2046version = "0.8.4"2124version = "0.8.5"
2047source = "registry+https://github.com/rust-lang/crates.io-index"2125source = "registry+https://github.com/rust-lang/crates.io-index"
2048checksum = "295283b02df346d1ef66052a757869b2876ac29a6bb0ac3f5f7cd44aebe40e8f"2126checksum = "9928cfca101b36ec5163e70049ee5368a8a1c3c6efc9ca9c5f9cc2f816152477"
2049dependencies = [2127dependencies = [
2050 "peg-macros",2128 "peg-macros",
2051 "peg-runtime",2129 "peg-runtime",
2052]2130]
20532131
2054[[package]]2132[[package]]
2055name = "peg-macros"2133name = "peg-macros"
2056version = "0.8.4"2134version = "0.8.5"
2057source = "registry+https://github.com/rust-lang/crates.io-index"2135source = "registry+https://github.com/rust-lang/crates.io-index"
2058checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426"2136checksum = "6298ab04c202fa5b5d52ba03269fb7b74550b150323038878fe6c372d8280f71"
2059dependencies = [2137dependencies = [
2060 "peg-runtime",2138 "peg-runtime",
2061 "proc-macro2",2139 "proc-macro2",
20642142
2065[[package]]2143[[package]]
2066name = "peg-runtime"2144name = "peg-runtime"
2067version = "0.8.3"2145version = "0.8.5"
2068source = "registry+https://github.com/rust-lang/crates.io-index"2146source = "registry+https://github.com/rust-lang/crates.io-index"
2069checksum = "e3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3a"2147checksum = "132dca9b868d927b35b5dd728167b2dee150eb1ad686008fc71ccb298b776fca"
20702148
2071[[package]]2149[[package]]
2072name = "pem"2150name = "pem"
2111dependencies = [2189dependencies = [
2112 "proc-macro2",2190 "proc-macro2",
2113 "quote",2191 "quote",
2114 "syn 2.0.87",2192 "syn",
2115]2193]
21162194
2117[[package]]2195[[package]]
2204checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"2282checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
2205dependencies = [2283dependencies = [
2206 "proc-macro2",2284 "proc-macro2",
2207 "syn 2.0.87",2285 "syn",
2208]2286]
2209
2210[[package]]
2211name = "proc-macro-error"
2212version = "1.0.4"
2213source = "registry+https://github.com/rust-lang/crates.io-index"
2214checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
2215dependencies = [
2216 "proc-macro-error-attr",
2217 "proc-macro2",
2218 "quote",
2219 "syn 1.0.109",
2220 "version_check",
2221]
2222
2223[[package]]
2224name = "proc-macro-error-attr"
2225version = "1.0.4"
2226source = "registry+https://github.com/rust-lang/crates.io-index"
2227checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
2228dependencies = [
2229 "proc-macro2",
2230 "quote",
2231 "version_check",
2232]
22332287
2234[[package]]2288[[package]]
2235name = "proc-macro-error-attr2"2289name = "proc-macro-error-attr2"
2250 "proc-macro-error-attr2",2304 "proc-macro-error-attr2",
2251 "proc-macro2",2305 "proc-macro2",
2252 "quote",2306 "quote",
2253 "syn 2.0.87",2307 "syn",
2254]2308]
22552309
2256[[package]]2310[[package]]
2279checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15"2333checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15"
2280dependencies = [2334dependencies = [
2281 "bytes",2335 "bytes",
2282 "heck 0.5.0",2336 "heck",
2283 "itertools 0.13.0",2337 "itertools 0.13.0",
2284 "log",2338 "log",
2285 "multimap",2339 "multimap",
2289 "prost",2343 "prost",
2290 "prost-types",2344 "prost-types",
2291 "regex",2345 "regex",
2292 "syn 2.0.87",2346 "syn",
2293 "tempfile",2347 "tempfile",
2294]2348]
22952349
2303 "itertools 0.13.0",2357 "itertools 0.13.0",
2304 "proc-macro2",2358 "proc-macro2",
2305 "quote",2359 "quote",
2306 "syn 2.0.87",2360 "syn",
2307]2361]
23082362
2309[[package]]2363[[package]]
2324 "proc-macro2",2378 "proc-macro2",
2325]2379]
2380
2381[[package]]
2382name = "r-efi"
2383version = "5.3.0"
2384source = "registry+https://github.com/rust-lang/crates.io-index"
2385checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
23262386
2327[[package]]2387[[package]]
2328name = "r2d2"2388name = "r2d2"
2342checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"2402checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
2343dependencies = [2403dependencies = [
2344 "libc",2404 "libc",
2345 "rand_chacha",2405 "rand_chacha 0.3.1",
2346 "rand_core",2406 "rand_core 0.6.4",
2347]2407]
2408
2409[[package]]
2410name = "rand"
2411version = "0.9.1"
2412source = "registry+https://github.com/rust-lang/crates.io-index"
2413checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
2414dependencies = [
2415 "rand_chacha 0.9.0",
2416 "rand_core 0.9.3",
2417]
23482418
2349[[package]]2419[[package]]
2350name = "rand_chacha"2420name = "rand_chacha"
2353checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"2423checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
2354dependencies = [2424dependencies = [
2355 "ppv-lite86",2425 "ppv-lite86",
2356 "rand_core",2426 "rand_core 0.6.4",
2357]2427]
2428
2429[[package]]
2430name = "rand_chacha"
2431version = "0.9.0"
2432source = "registry+https://github.com/rust-lang/crates.io-index"
2433checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
2434dependencies = [
2435 "ppv-lite86",
2436 "rand_core 0.9.3",
2437]
23582438
2359[[package]]2439[[package]]
2360name = "rand_core"2440name = "rand_core"
2361version = "0.6.4"2441version = "0.6.4"
2362source = "registry+https://github.com/rust-lang/crates.io-index"2442source = "registry+https://github.com/rust-lang/crates.io-index"
2363checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"2443checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
2364dependencies = [2444dependencies = [
2365 "getrandom",2445 "getrandom 0.2.15",
2366]2446]
2447
2448[[package]]
2449name = "rand_core"
2450version = "0.9.3"
2451source = "registry+https://github.com/rust-lang/crates.io-index"
2452checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
2453dependencies = [
2454 "getrandom 0.3.3",
2455]
23672456
2368[[package]]2457[[package]]
2369name = "rcgen"2458name = "rcgen"
2439dependencies = [2528dependencies = [
2440 "cc",2529 "cc",
2441 "cfg-if",2530 "cfg-if",
2442 "getrandom",2531 "getrandom 0.2.15",
2443 "libc",2532 "libc",
2444 "spin",2533 "spin",
2445 "untrusted",2534 "untrusted",
24812570
2482[[package]]2571[[package]]
2483name = "ron"2572name = "ron"
2484version = "0.8.1"2573version = "0.10.1"
2485source = "registry+https://github.com/rust-lang/crates.io-index"2574source = "registry+https://github.com/rust-lang/crates.io-index"
2486checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"2575checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f"
2487dependencies = [2576dependencies = [
2488 "base64 0.21.7",2577 "base64 0.22.1",
2489 "bitflags",2578 "bitflags",
2490 "serde",2579 "serde",
2491 "serde_derive",2580 "serde_derive",
2581 "unicode-ident",
2492]2582]
24932583
2494[[package]]2584[[package]]
2517 "num-traits",2607 "num-traits",
2518 "pkcs1",2608 "pkcs1",
2519 "pkcs8",2609 "pkcs8",
2520 "rand_core",2610 "rand_core 0.6.4",
2521 "signature",2611 "signature",
2522 "spki",2612 "spki",
2523 "subtle",2613 "subtle",
2544 "proc-macro2",2634 "proc-macro2",
2545 "quote",2635 "quote",
2546 "rust-embed-utils",2636 "rust-embed-utils",
2547 "syn 2.0.87",2637 "syn",
2548 "walkdir",2638 "walkdir",
2549]2639]
25502640
2588 "bitflags",2678 "bitflags",
2589 "errno",2679 "errno",
2590 "libc",2680 "libc",
2591 "linux-raw-sys",2681 "linux-raw-sys 0.4.14",
2592 "windows-sys 0.52.0",2682 "windows-sys 0.52.0",
2593]2683]
2684
2685[[package]]
2686name = "rustix"
2687version = "1.0.7"
2688source = "registry+https://github.com/rust-lang/crates.io-index"
2689checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
2690dependencies = [
2691 "bitflags",
2692 "errno",
2693 "libc",
2694 "linux-raw-sys 0.9.4",
2695 "windows-sys 0.59.0",
2696]
25942697
2595[[package]]2698[[package]]
2596name = "rustls"2699name = "rustls"
27212824
2722[[package]]2825[[package]]
2723name = "serde"2826name = "serde"
2724version = "1.0.215"2827version = "1.0.219"
2725source = "registry+https://github.com/rust-lang/crates.io-index"2828source = "registry+https://github.com/rust-lang/crates.io-index"
2726checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"2829checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
2727dependencies = [2830dependencies = [
2728 "serde_derive",2831 "serde_derive",
2729]2832]
27482851
2749[[package]]2852[[package]]
2750name = "serde_derive"2853name = "serde_derive"
2751version = "1.0.215"2854version = "1.0.219"
2752source = "registry+https://github.com/rust-lang/crates.io-index"2855source = "registry+https://github.com/rust-lang/crates.io-index"
2753checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"2856checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
2754dependencies = [2857dependencies = [
2755 "proc-macro2",2858 "proc-macro2",
2756 "quote",2859 "quote",
2757 "syn 2.0.87",2860 "syn",
2758]2861]
27592862
2760[[package]]2863[[package]]
2761name = "serde_json"2864name = "serde_json"
2762version = "1.0.133"2865version = "1.0.140"
2763source = "registry+https://github.com/rust-lang/crates.io-index"2866source = "registry+https://github.com/rust-lang/crates.io-index"
2764checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"2867checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
2765dependencies = [2868dependencies = [
2766 "itoa",2869 "itoa",
2767 "memchr",2870 "memchr",
2838checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"2941checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
2839dependencies = [2942dependencies = [
2840 "digest",2943 "digest",
2841 "rand_core",2944 "rand_core 0.6.4",
2842]2945]
28432946
2844[[package]]2947[[package]]
2922 "is_ci",3025 "is_ci",
2923]3026]
2924
2925[[package]]
2926name = "syn"
2927version = "1.0.109"
2928source = "registry+https://github.com/rust-lang/crates.io-index"
2929checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
2930dependencies = [
2931 "proc-macro2",
2932 "quote",
2933 "unicode-ident",
2934]
29353027
2936[[package]]3028[[package]]
2937name = "syn"3029name = "syn"
29583050
2959[[package]]3051[[package]]
2960name = "tabled"3052name = "tabled"
2961version = "0.16.0"3053version = "0.20.0"
2962source = "registry+https://github.com/rust-lang/crates.io-index"3054source = "registry+https://github.com/rust-lang/crates.io-index"
2963checksum = "77c9303ee60b9bedf722012ea29ae3711ba13a67c9b9ae28993838b63057cb1b"3055checksum = "e39a2ee1fbcd360805a771e1b300f78cc88fec7b8d3e2f71cd37bbf23e725c7d"
2964dependencies = [3056dependencies = [
2965 "papergrid",3057 "papergrid",
2966 "tabled_derive",3058 "tabled_derive",
3059 "testing_table",
2967]3060]
29683061
2969[[package]]3062[[package]]
2970name = "tabled_derive"3063name = "tabled_derive"
2971version = "0.8.0"3064version = "0.11.0"
2972source = "registry+https://github.com/rust-lang/crates.io-index"3065source = "registry+https://github.com/rust-lang/crates.io-index"
2973checksum = "bf0fb8bfdc709786c154e24a66777493fb63ae97e3036d914c8666774c477069"3066checksum = "0ea5d1b13ca6cff1f9231ffd62f15eefd72543dab5e468735f1a456728a02846"
2974dependencies = [3067dependencies = [
2975 "heck 0.4.1",3068 "heck",
2976 "proc-macro-error",3069 "proc-macro-error2",
2977 "proc-macro2",3070 "proc-macro2",
2978 "quote",3071 "quote",
2979 "syn 1.0.109",3072 "syn",
2980]3073]
29813074
2982[[package]]3075[[package]]
2983name = "tempfile"3076name = "tempfile"
2984version = "3.14.0"3077version = "3.20.0"
2985source = "registry+https://github.com/rust-lang/crates.io-index"3078source = "registry+https://github.com/rust-lang/crates.io-index"
2986checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"3079checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
2987dependencies = [3080dependencies = [
2988 "cfg-if",
2989 "fastrand",3081 "fastrand",
3082 "getrandom 0.3.3",
2990 "once_cell",3083 "once_cell",
2991 "rustix",3084 "rustix 1.0.7",
2992 "windows-sys 0.59.0",3085 "windows-sys 0.59.0",
2993]3086]
29943087
2998source = "registry+https://github.com/rust-lang/crates.io-index"3091source = "registry+https://github.com/rust-lang/crates.io-index"
2999checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef"3092checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef"
3000dependencies = [3093dependencies = [
3001 "rustix",3094 "rustix 0.38.40",
3002 "windows-sys 0.59.0",3095 "windows-sys 0.59.0",
3003]3096]
30043097
3013 "tokio",3106 "tokio",
3014]3107]
3108
3109[[package]]
3110name = "testing_table"
3111version = "0.3.0"
3112source = "registry+https://github.com/rust-lang/crates.io-index"
3113checksum = "0f8daae29995a24f65619e19d8d31dea5b389f3d853d8bf297bbf607cd0014cc"
3114dependencies = [
3115 "unicode-width 0.2.0",
3116]
30153117
3016[[package]]3118[[package]]
3017name = "text-size"3119name = "text-size"
30583160
3059[[package]]3161[[package]]
3060name = "thiserror"3162name = "thiserror"
3061version = "2.0.3"3163version = "2.0.12"
3062source = "registry+https://github.com/rust-lang/crates.io-index"3164source = "registry+https://github.com/rust-lang/crates.io-index"
3063checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa"3165checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
3064dependencies = [3166dependencies = [
3065 "thiserror-impl 2.0.3",3167 "thiserror-impl 2.0.12",
3066]3168]
30673169
3068[[package]]3170[[package]]
3073dependencies = [3175dependencies = [
3074 "proc-macro2",3176 "proc-macro2",
3075 "quote",3177 "quote",
3076 "syn 2.0.87",3178 "syn",
3077]3179]
30783180
3079[[package]]3181[[package]]
3080name = "thiserror-impl"3182name = "thiserror-impl"
3081version = "2.0.3"3183version = "2.0.12"
3082source = "registry+https://github.com/rust-lang/crates.io-index"3184source = "registry+https://github.com/rust-lang/crates.io-index"
3083checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568"3185checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
3084dependencies = [3186dependencies = [
3085 "proc-macro2",3187 "proc-macro2",
3086 "quote",3188 "quote",
3087 "syn 2.0.87",3189 "syn",
3088]3190]
30893191
3090[[package]]3192[[package]]
30993201
3100[[package]]3202[[package]]
3101name = "time"3203name = "time"
3102version = "0.3.36"3204version = "0.3.41"
3103source = "registry+https://github.com/rust-lang/crates.io-index"3205source = "registry+https://github.com/rust-lang/crates.io-index"
3104checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"3206checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
3105dependencies = [3207dependencies = [
3106 "deranged",3208 "deranged",
3107 "num-conv",3209 "num-conv",
31133215
3114[[package]]3216[[package]]
3115name = "time-core"3217name = "time-core"
3116version = "0.1.2"3218version = "0.1.4"
3117source = "registry+https://github.com/rust-lang/crates.io-index"3219source = "registry+https://github.com/rust-lang/crates.io-index"
3118checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"3220checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
31193221
3120[[package]]3222[[package]]
3121name = "time-macros"3223name = "time-macros"
3122version = "0.2.18"3224version = "0.2.22"
3123source = "registry+https://github.com/rust-lang/crates.io-index"3225source = "registry+https://github.com/rust-lang/crates.io-index"
3124checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"3226checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
3125dependencies = [3227dependencies = [
3126 "num-conv",3228 "num-conv",
3127 "time-core",3229 "time-core",
31383240
3139[[package]]3241[[package]]
3140name = "tokio"3242name = "tokio"
3141version = "1.41.1"3243version = "1.45.1"
3142source = "registry+https://github.com/rust-lang/crates.io-index"3244source = "registry+https://github.com/rust-lang/crates.io-index"
3143checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33"3245checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
3144dependencies = [3246dependencies = [
3145 "backtrace",3247 "backtrace",
3146 "bytes",3248 "bytes",
31553257
3156[[package]]3258[[package]]
3157name = "tokio-macros"3259name = "tokio-macros"
3158version = "2.4.0"3260version = "2.5.0"
3159source = "registry+https://github.com/rust-lang/crates.io-index"3261source = "registry+https://github.com/rust-lang/crates.io-index"
3160checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"3262checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
3161dependencies = [3263dependencies = [
3162 "proc-macro2",3264 "proc-macro2",
3163 "quote",3265 "quote",
3164 "syn 2.0.87",3266 "syn",
3165]3267]
31663268
3167[[package]]3269[[package]]
31893291
3190[[package]]3292[[package]]
3191name = "tokio-util"3293name = "tokio-util"
3192version = "0.7.12"3294version = "0.7.15"
3193source = "registry+https://github.com/rust-lang/crates.io-index"3295source = "registry+https://github.com/rust-lang/crates.io-index"
3194checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"3296checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df"
3195dependencies = [3297dependencies = [
3196 "bytes",3298 "bytes",
3197 "futures-core",3299 "futures-core",
3252 "prost-build",3354 "prost-build",
3253 "prost-types",3355 "prost-types",
3254 "quote",3356 "quote",
3255 "syn 2.0.87",3357 "syn",
3256]3358]
32573359
3258[[package]]3360[[package]]
3266 "indexmap 1.9.3",3368 "indexmap 1.9.3",
3267 "pin-project",3369 "pin-project",
3268 "pin-project-lite",3370 "pin-project-lite",
3269 "rand",3371 "rand 0.8.5",
3270 "slab",3372 "slab",
3271 "tokio",3373 "tokio",
3272 "tokio-util",3374 "tokio-util",
3337dependencies = [3439dependencies = [
3338 "proc-macro2",3440 "proc-macro2",
3339 "quote",3441 "quote",
3340 "syn 2.0.87",3442 "syn",
3341]3443]
33423444
3343[[package]]3445[[package]]
3456source = "registry+https://github.com/rust-lang/crates.io-index"3558source = "registry+https://github.com/rust-lang/crates.io-index"
3457checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"3559checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
3560
3561[[package]]
3562name = "unicode-segmentation"
3563version = "1.12.0"
3564source = "registry+https://github.com/rust-lang/crates.io-index"
3565checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
34583566
3459[[package]]3567[[package]]
3460name = "unicode-width"3568name = "unicode-width"
34763584
3477[[package]]3585[[package]]
3478name = "unindent"3586name = "unindent"
3479version = "0.2.3"3587version = "0.2.4"
3480source = "registry+https://github.com/rust-lang/crates.io-index"3588source = "registry+https://github.com/rust-lang/crates.io-index"
3481checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"3589checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
34823590
3483[[package]]3591[[package]]
3484name = "universal-hash"3592name = "universal-hash"
3572source = "registry+https://github.com/rust-lang/crates.io-index"3680source = "registry+https://github.com/rust-lang/crates.io-index"
3573checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"3681checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
3682
3683[[package]]
3684name = "wasi"
3685version = "0.14.2+wasi-0.2.4"
3686source = "registry+https://github.com/rust-lang/crates.io-index"
3687checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
3688dependencies = [
3689 "wit-bindgen-rt",
3690]
35743691
3575[[package]]3692[[package]]
3576name = "wasm-bindgen"3693name = "wasm-bindgen"
3594 "once_cell",3711 "once_cell",
3595 "proc-macro2",3712 "proc-macro2",
3596 "quote",3713 "quote",
3597 "syn 2.0.87",3714 "syn",
3598 "wasm-bindgen-shared",3715 "wasm-bindgen-shared",
3599]3716]
36003717
3616dependencies = [3733dependencies = [
3617 "proc-macro2",3734 "proc-macro2",
3618 "quote",3735 "quote",
3619 "syn 2.0.87",3736 "syn",
3620 "wasm-bindgen-backend",3737 "wasm-bindgen-backend",
3621 "wasm-bindgen-shared",3738 "wasm-bindgen-shared",
3622]3739]
3646 "either",3763 "either",
3647 "home",3764 "home",
3648 "once_cell",3765 "once_cell",
3649 "rustix",3766 "rustix 0.38.40",
3650]3767]
36513768
3652[[package]]3769[[package]]
3680source = "registry+https://github.com/rust-lang/crates.io-index"3797source = "registry+https://github.com/rust-lang/crates.io-index"
3681checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"3798checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
3682
3683[[package]]
3684name = "windows"
3685version = "0.52.0"
3686source = "registry+https://github.com/rust-lang/crates.io-index"
3687checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
3688dependencies = [
3689 "windows-core",
3690 "windows-targets",
3691]
36923799
3693[[package]]3800[[package]]
3694name = "windows-core"3801name = "windows-core"
3699 "windows-targets",3806 "windows-targets",
3700]3807]
3808
3809[[package]]
3810name = "windows-link"
3811version = "0.1.3"
3812source = "registry+https://github.com/rust-lang/crates.io-index"
3813checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
37013814
3702[[package]]3815[[package]]
3703name = "windows-sys"3816name = "windows-sys"
3781source = "registry+https://github.com/rust-lang/crates.io-index"3894source = "registry+https://github.com/rust-lang/crates.io-index"
3782checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"3895checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
3896
3897[[package]]
3898name = "wit-bindgen-rt"
3899version = "0.39.0"
3900source = "registry+https://github.com/rust-lang/crates.io-index"
3901checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
3902dependencies = [
3903 "bitflags",
3904]
37833905
3784[[package]]3906[[package]]
3785name = "x25519-dalek"3907name = "x25519-dalek"
3788checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"3910checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
3789dependencies = [3911dependencies = [
3790 "curve25519-dalek",3912 "curve25519-dalek",
3791 "rand_core",3913 "rand_core 0.6.4",
3792 "serde",3914 "serde",
3793 "zeroize",3915 "zeroize",
3794]3916]
38043926
3805[[package]]3927[[package]]
3806name = "z85"3928name = "z85"
3807version = "3.0.5"3929version = "3.0.6"
3808source = "registry+https://github.com/rust-lang/crates.io-index"3930source = "registry+https://github.com/rust-lang/crates.io-index"
3809checksum = "2a599daf1b507819c1121f0bf87fa37eb19daac6aff3aefefd4e6e2e0f2020fc"3931checksum = "9b3a41ce106832b4da1c065baa4c31cf640cf965fa1483816402b7f6b96f0a64"
38103932
3811[[package]]3933[[package]]
3812name = "zerocopy"3934name = "zerocopy"
3826dependencies = [3948dependencies = [
3827 "proc-macro2",3949 "proc-macro2",
3828 "quote",3950 "quote",
3829 "syn 2.0.87",3951 "syn",
3830]3952]
38313953
3832[[package]]3954[[package]]
3846dependencies = [3968dependencies = [
3847 "proc-macro2",3969 "proc-macro2",
3848 "quote",3970 "quote",
3849 "syn 2.0.87",3971 "syn",
3850]3972]
38513973
modifiedCargo.tomldiffbeforeafterboth
15anyhow = "1.0"15anyhow = "1.0"
16clap = { version = "4.5", features = ["derive", "env", "unicode", "wrap_help"] }16clap = { version = "4.5", features = ["derive", "env", "unicode", "wrap_help"] }
17clap_complete = "4.5"17clap_complete = "4.5"
18nix = { version = "0.29.0", features = ["fs", "user"] }18nix = { version = "0.30.1", features = ["fs", "user"] }
19serde = { version = "1.0", features = ["derive"] }19serde = { version = "1.0", features = ["derive"] }
20serde_json = "1.0"20serde_json = "1.0"
21tempfile = "3.10"21tempfile = "3.20"
22thiserror = "2.0.3"22thiserror = "2.0.12"
23tokio = { version = "1.36.0", features = ["fs", "macros", "rt", "rt-multi-thread", "sync", "time"] }23tokio = { version = "1.45.1", features = ["fs", "macros", "rt", "rt-multi-thread", "sync", "time"] }
24tokio-util = { version = "0.7.11", features = ["codec"] }24tokio-util = { version = "0.7.15", features = ["codec"] }
25tracing = "0.1"25tracing = "0.1"
26tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }26tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
2727
modifiedcmds/fleet/Cargo.tomldiffbeforeafterboth
5authors = ["Yaroslav Bolyukin <iam@lach.pw>"]5authors = ["Yaroslav Bolyukin <iam@lach.pw>"]
6edition.workspace = true6edition.workspace = true
7rust-version.workspace = true7rust-version.workspace = true
8default-run = "fleet"
89
9[dependencies]10[dependencies]
10age = { workspace = true, features = ["armor"] }11age = { workspace = true, features = ["armor"] }
27async-trait = "0.1"28async-trait = "0.1"
28base64 = "0.22.1"29base64 = "0.22.1"
29chrono = { version = "0.4", features = ["serde"] }30chrono = { version = "0.4", features = ["serde"] }
30crossterm = { version = "0.28.0", features = ["use-dev-tty"] }31crossterm = { version = "0.29.0", features = ["use-dev-tty"] }
31futures = "0.3"32futures = "0.3"
32hostname = "0.4.0"33hostname = "0.4.1"
33itertools = "0.13"34itertools = "0.14"
34openssh = "0.11"35openssh = "0.11"
35owo-colors = { version = "4.0", features = ["supports-color", "supports-colors"] }36owo-colors = { version = "4.2", features = ["supports-color", "supports-colors"] }
36peg = "0.8"37peg = "0.8"
37regex = "1.10"38regex = "1.11"
38shlex = "1.3"39shlex = "1.3"
39tabled = { version = "0.16" }40tabled = { version = "0.20" }
40time = { version = "0.3", features = ["serde"] }41time = { version = "0.3", features = ["serde"] }
41tokio-util = { version = "0.7", features = ["codec"] }42tokio-util = { version = "0.7", features = ["codec"] }
4243
43fleet-base = { version = "0.1.0", path = "../../crates/fleet-base" }44fleet-base = { version = "0.1.0", path = "../../crates/fleet-base" }
44human-repr = { version = "1.1", optional = true }45human-repr = { version = "1.1", optional = true }
45indicatif = { version = "0.17", optional = true }46indicatif = { version = "0.17", optional = true }
46nom = "7.1.3"47nom = "8.0.0"
47tracing-indicatif = { version = "0.3", optional = true }48tracing-indicatif = { version = "0.3", optional = true }
4849
49[features]50[features]
modifiedcmds/fleet/src/cmds/build_systems.rsdiffbeforeafterboth
1use std::{env::current_dir, os::unix::fs::symlink, path::PathBuf, time::Duration};1use std::{env::current_dir, os::unix::fs::symlink, path::PathBuf};
22
3use anyhow::{anyhow, bail, Context, Result};3use anyhow::{anyhow, Result};
4use clap::{Parser, ValueEnum};4use clap::Parser;
5use fleet_base::{5use fleet_base::{
6 deploy::{deploy_task, upload_task, DeployAction},
6 host::{Config, ConfigHost, DeployKind},7 host::{Config, DeployKind, GenerationStorage},
7 opts::FleetOpts,8 opts::FleetOpts,
8};9};
9use itertools::Itertools as _;
10use nix_eval::{nix_go, NixBuildBatch};10use nix_eval::{nix_go, NixBuildBatch};
11use tokio::{task::LocalSet, time::sleep};11use tokio::task::LocalSet;
12use tracing::{error, field, info, info_span, warn, Instrument};12use tracing::{error, field, info, info_span, warn, Instrument};
1313
14#[derive(Parser)]14#[derive(Parser)]
20 action: DeployAction,20 action: DeployAction,
21}21}
22
23#[derive(ValueEnum, Clone, Copy)]
24enum DeployAction {
25 /// Upload derivation, but do not execute the update.
26 Upload,
27 /// Upload and execute the activation script, old version will be used after reboot.
28 Test,
29 /// Upload and set as current system profile, but do not execute activation script.
30 Boot,
31 /// Upload, set current profile, and execute activation script.
32 Switch,
33}
34
35impl DeployAction {
36 pub(crate) fn name(&self) -> Option<&'static str> {
37 match self {
38 Self::Upload => None,
39 Self::Test => Some("test"),
40 Self::Boot => Some("boot"),
41 Self::Switch => Some("switch"),
42 }
43 }
44 pub(crate) fn should_switch_profile(&self) -> bool {
45 matches!(self, Self::Switch | Self::Boot)
46 }
47 pub(crate) fn should_activate(&self) -> bool {
48 matches!(self, Self::Switch | Self::Test | Self::Boot)
49 }
50 pub(crate) fn should_create_rollback_marker(&self) -> bool {
51 // Upload does nothing on the target machine, other than uploading the closure.
52 // In boot case we want to have rollback marker prepared, so that the system may rollback itself on the next boot.
53 !matches!(self, Self::Upload)
54 }
55 pub(crate) fn should_schedule_rollback_run(&self) -> bool {
56 matches!(self, Self::Switch | Self::Test)
57 }
58}
5922
60#[derive(Parser, Clone)]23#[derive(Parser, Clone)]
61pub struct BuildSystems {24pub struct BuildSystems {
65 build_attr: String,28 build_attr: String,
66}29}
67
68struct Generation {
69 id: u32,
70 current: bool,
71 datetime: String,
72}
73
74fn parse_generation_line(g: &str) -> Option<Generation> {
75 let mut parts = g.split_whitespace();
76 let id = parts.next()?;
77 let id: u32 = id.parse().ok()?;
78 let date = parts.next()?;
79 let time = parts.next()?;
80 let current = if let Some(current) = parts.next() {
81 if current == "(current)" {
82 Some(true)
83 } else {
84 None
85 }
86 } else {
87 Some(false)
88 };
89 let current = current?;
90 if parts.next().is_some() {
91 warn!("unexpected text after generation: {g}");
92 }
93 Some(Generation {
94 id,
95 current,
96 datetime: format!("{date} {time}"),
97 })
98}
99
100async fn get_current_generation(host: &ConfigHost) -> Result<Generation> {
101 let mut cmd = host.cmd("nix-env").await?;
102 cmd.comparg("--profile", "/nix/var/nix/profiles/system")
103 .arg("--list-generations");
104 // Sudo is required due to --list-generations acquiring lock on the profile.
105 let data = cmd.sudo().run_string().await?;
106 let generations = data
107 .split('\n')
108 .map(|e| e.trim())
109 .filter(|&l| !l.is_empty())
110 .filter_map(|g| {
111 let gen = parse_generation_line(g);
112 if gen.is_none() {
113 warn!("bad generation: {g}");
114 }
115 gen
116 })
117 .collect::<Vec<_>>();
118 let current = generations
119 .into_iter()
120 .filter(|g| g.current)
121 .at_most_one()
122 .map_err(|_e| anyhow!("bad list-generations output"))?
123 .ok_or_else(|| anyhow!("failed to find generation"))?;
124 Ok(current)
125}
126
127async fn deploy_task(
128 action: DeployAction,
129 host: &ConfigHost,
130 built: PathBuf,
131 specialisation: Option<String>,
132 disable_rollback: bool,
133) -> Result<()> {
134 let deploy_kind = host.deploy_kind().await?;
135 if (deploy_kind == DeployKind::NixosInstall || deploy_kind == DeployKind::NixosLustrate)
136 && !matches!(action, DeployAction::Boot | DeployAction::Upload)
137 {
138 bail!("{deploy_kind:?} deploy kind only supports boot and upload actions");
139 }
140
141 let mut failed = false;
142
143 // TODO: Lockfile, to prevent concurrent system switch?
144 // TODO: If rollback target exists - bail, it should be removed. Lockfile will not work in case if rollback
145 // is scheduler on next boot (default behavior). On current boot - rollback activator will fail due to
146 // unit name conflict in systemd-run
147 // This code is tied to rollback.nix
148 if !disable_rollback && action.should_create_rollback_marker() {
149 let _span = info_span!("preparing").entered();
150 info!("preparing for rollback");
151 let generation = get_current_generation(host).await?;
152 info!(
153 "rollback target would be {} {}",
154 generation.id, generation.datetime
155 );
156 {
157 let mut cmd = host.cmd("sh").await?;
158 cmd.arg("-c").arg(format!("mark=$(mktemp -p /etc -t fleet_rollback_marker.XXXXX) && echo -n {} > $mark && mv --no-clobber $mark /etc/fleet_rollback_marker", generation.id));
159 if let Err(e) = cmd.sudo().run().await {
160 error!("failed to set rollback marker: {e}");
161 failed = true;
162 }
163 }
164 // Activation script also starts rollback-watchdog.timer, however, it is possible that it won't be started.
165 // Kicking it on manually will work best.
166 //
167 // There wouldn't be conflict, because here we trigger start of the primary service, and systemd will
168 // only allow one instance of it.
169
170 // TODO: We should also watch how this process is going.
171 // After running this command, we have less than 3 minutes to deploy everything,
172 // if we fail to perform generation switch in time, then we will still call the activation script, and this may break something.
173 // Anyway, reboot will still help in this case.
174 if action.should_schedule_rollback_run() {
175 let mut cmd = host.cmd("systemd-run").await?;
176 cmd.comparg("--on-active", "3min")
177 .comparg("--unit", "rollback-watchdog-run")
178 .arg("systemctl")
179 .arg("start")
180 .arg("rollback-watchdog.service");
181 if let Err(e) = cmd.sudo().run().await {
182 error!("failed to schedule rollback run: {e}");
183 failed = true;
184 }
185 }
186 }
187 if deploy_kind == DeployKind::NixosLustrate {
188 // Fleet could also create this file, but as this operation is potentially disruptive,
189 // make user do it themself.
190 if !host.file_exists("/etc/NIXOS_LUSTRATE").await? {
191 bail!("/etc/NIXOS_LUSTRATE should be created on remote host");
192 }
193 // Wanted by NixOS to recognize the system as NixOS.
194 let mut cmd = host.cmd("touch").await?;
195 cmd.arg("/etc/NIXOS");
196 cmd.sudo().run().await.context("creating /etc/NIXOS")?;
197 }
198 if deploy_kind == DeployKind::NixosInstall {
199 info!(
200 "running nixos-install to switch profile, install bootloader, and perform activation"
201 );
202 let mut cmd = host.cmd("nixos-install").await?;
203 cmd.arg("--system").arg(&built).args([
204 // Channels here aren't fleet host system channels, but channels embedded in installation cd, which might be old.
205 // It is possible to copy host channels, but I would prefer non-flake nix just to be unsupported.
206 "--no-channel-copy",
207 "--root",
208 "/mnt",
209 ]);
210 if let Err(e) = cmd.sudo().run().await {
211 error!("failed to execute nixos-install: {e}");
212 failed = true;
213 }
214 } else {
215 if action.should_switch_profile() && !failed {
216 info!("switching system profile generation");
217
218 // To avoid even more problems, using nixos-install for now.
219 // // nix build is unable to work with --store argument for some reason, and nix until 2.26 didn't support copy with --profile argument,
220 // // falling back to using nix-env command
221 // // After stable NixOS starts using 2.26 - use `nix --store /mnt copy --from /mnt --profile ...` here, and instead of nix build below.
222 // let mut cmd = host.cmd("nix-env").await?;
223 // cmd.args([
224 // "--store",
225 // "/mnt",
226 // "--profile",
227 // "/mnt/nix/var/nix/profiles/system",
228 // "--set",
229 // ])
230 // .arg(&built);
231 // if let Err(e) = cmd.sudo().run_nix().await {
232 // error!("failed to switch system profile generation: {e}");
233 // failed = true;
234 // }
235 // It would also be possible to update profile atomically during copy:
236 // https://github.com/NixOS/nix/pull/11657
237 let mut cmd = host.nix_cmd().await?;
238 cmd.arg("build");
239 cmd.comparg("--profile", "/nix/var/nix/profiles/system");
240 cmd.arg(&built);
241 if let Err(e) = cmd.sudo().run_nix().await {
242 error!("failed to switch system profile generation: {e}");
243 failed = true;
244 }
245 }
246
247 // FIXME: Connection might be disconnected after activation run
248
249 if action.should_activate() && !failed {
250 let _span = info_span!("activating").entered();
251 info!("executing activation script");
252 let specialised = if let Some(specialisation) = specialisation {
253 let mut specialised = built.join("specialisation");
254 specialised.push(specialisation);
255 specialised
256 } else {
257 built.clone()
258 };
259 let switch_script = specialised.join("bin/switch-to-configuration");
260 let mut cmd = host.cmd(switch_script).in_current_span().await?;
261 if deploy_kind == DeployKind::NixosLustrate {
262 cmd.env("NIXOS_INSTALL_BOOTLOADER", "1");
263 }
264 cmd.env("FLEET_ONLINE_ACTIVATION", "1")
265 .arg(action.name().expect("upload.should_activate == false"));
266 if let Err(e) = cmd.sudo().run().in_current_span().await {
267 error!("failed to activate: {e}");
268 failed = true;
269 }
270 }
271 }
272 if action.should_create_rollback_marker() {
273 if !disable_rollback {
274 if failed {
275 if action.should_schedule_rollback_run() {
276 info!("executing rollback");
277 if let Err(e) = host
278 .systemctl_start("rollback-watchdog.service")
279 .instrument(info_span!("rollback"))
280 .await
281 {
282 error!("failed to trigger rollback: {e}")
283 }
284 }
285 } else {
286 info!("trying to mark upgrade as successful");
287 if let Err(e) = host
288 .rm_file("/etc/fleet_rollback_marker", true)
289 .in_current_span()
290 .await
291 {
292 error!("failed to remove rollback marker. This is bad, as the system will be rolled back by watchdog: {e}")
293 }
294 }
295 info!("disarming watchdog, just in case");
296 if let Err(_e) = host.systemctl_stop("rollback-watchdog.timer").await {
297 // It is ok, if there was no reboot - then timer might not be running.
298 }
299 if action.should_schedule_rollback_run() {
300 if let Err(e) = host.systemctl_stop("rollback-watchdog-run.timer").await {
301 error!("failed to disarm rollback run: {e}");
302 }
303 }
304 } else if let Err(_e) = host
305 .rm_file("/etc/fleet_rollback_marker", true)
306 .in_current_span()
307 .await
308 {
309 // Marker might not exist, yet better try to remove it.
310 }
311 }
312 Ok(())
313}
31430
315async fn build_task(31async fn build_task(
316 config: Config,32 config: Config,
328 .get("out")44 .get("out")
329 .ok_or_else(|| anyhow!("system build should produce \"out\" output"))?;45 .ok_or_else(|| anyhow!("system build should produce \"out\" output"))?;
33046
47 // We already have system profiles for backups.
331 {48 if !host.local {
332 info!("adding gc root");49 info!("adding gc root");
333 let mut cmd = config.local_host().cmd("nix").await?;50 let mut cmd = config.local_host().cmd("nix").await?;
334 cmd.arg("build")51 cmd.arg("build")
403 let config = config.clone();120 let config = config.clone();
404 let span = info_span!("deploy", host = field::display(&host.name));121 let span = info_span!("deploy", host = field::display(&host.name));
405 let hostname = host.name.clone();122 let hostname = host.name.clone();
406 let local_host = config.local_host();
407 let opts = opts.clone();123 let opts = opts.clone();
408 let batch = batch.clone();124 let batch = batch.clone();
409 if let Some(deploy_kind) = opts.action_attr::<DeployKind>(&host, "deploy_kind").await? {125 if let Some(deploy_kind) = opts.action_attr::<DeployKind>(&host, "deploy_kind").await? {
437 disable_rollback = true;153 disable_rollback = true;
438 }154 }
439155
440 if !opts.is_local(&hostname) {
441 info!("uploading system closure");
442 {
443 // TODO: Move to remote_derivation method.
444 // Alternatively, nix store make-content-addressed can be used,
445 // at least for the first deployment, to provide trusted store key.
446 //
447 // It is much slower, yet doesn't require root on the deployer machine.
448 let Ok(mut sign) = local_host.cmd("nix").await else {
449 error!("failed to setup local");
450 return;
451 };
452 // Private key for host machine is registered in nix-sign.nix
453 sign.arg("store")
454 .arg("sign")
455 .comparg("--key-file", "/etc/nix/private-key")
456 .arg("-r")
457 .arg(&built);
458 if let Err(e) = sign.sudo().run_nix().await {
459 warn!("failed to sign store paths: {e}");
460 };
461 }
462 let mut tries = 0;156 let remote_path =
463 loop {
464 match host.remote_derivation(&built).await {157 match upload_task(&config, &host, GenerationStorage::Deployer, built).await
158 {
465 Ok(remote) => {159 Ok(v) => v,
466 assert!(remote == built, "CA derivations aren't implemented");
467 break;
468 }
469 Err(e) if tries < 3 => {
470 tries += 1;
471 warn!("copy failure ({}/3): {}", tries, e);
472 sleep(Duration::from_millis(5000)).await;
473 }
474 Err(e) => {160 Err(e) => {
475 error!("upload failed: {e}");161 error!("upload failed: {e}");
476 return;162 return;
477 }163 }
478 }164 };
479 }165
480 }
481 if let Err(e) = deploy_task(166 if let Err(e) = deploy_task(
482 self.action,167 self.action,
483 &host,168 &host,
484 built,169 remote_path,
485 if let Ok(v) = opts.action_attr(&host, "specialisation").await {170 if let Ok(v) = opts.action_attr(&host, "specialisation").await {
486 v171 v
487 } else {172 } else {
modifiedcmds/fleet/src/cmds/mod.rsdiffbeforeafterboth
3pub mod info;3pub mod info;
4pub mod secrets;4pub mod secrets;
5pub mod tf;5pub mod tf;
66pub mod rollback;
addedcmds/fleet/src/cmds/rollback.rsdiffbeforeafterboth

no changes

modifiedcmds/fleet/src/main.rsdiffbeforeafterboth
10use clap::{CommandFactory, Parser};10use clap::{CommandFactory, Parser};
11use cmds::{11use cmds::{
12 build_systems::{BuildSystems, Deploy},12 build_systems::{BuildSystems, Deploy},
13 rollback::RollbackSingle,
13 complete::Complete,14 complete::Complete,
14 info::Info,15 info::Info,
15 secrets::Secret,16 secrets::Secret,
70 BuildSystems(BuildSystems),71 BuildSystems(BuildSystems),
71 /// Upload and switch system closures72 /// Upload and switch system closures
72 Deploy(Deploy),73 Deploy(Deploy),
74 /// Rollback remote machine by redeploying old generation as the new one
75 RollbackSingle(RollbackSingle),
73 /// Secret management76 /// Secret management
74 #[clap(subcommand)]77 #[clap(subcommand)]
75 Secret(Secret),78 Secret(Secret),
97 match command {100 match command {
98 Opts::BuildSystems(c) => c.run(config, &opts).await?,101 Opts::BuildSystems(c) => c.run(config, &opts).await?,
99 Opts::Deploy(d) => d.run(config, &opts).await?,102 Opts::Deploy(d) => d.run(config, &opts).await?,
103 Opts::RollbackSingle(r) => r.run(config, &opts).await?,
100 Opts::Secret(s) => s.run(config, &opts).await?,104 Opts::Secret(s) => s.run(config, &opts).await?,
101 Opts::Info(i) => i.run(config).await?,105 Opts::Info(i) => i.run(config).await?,
102 Opts::Prefetch(p) => p.run(config).await?,106 Opts::Prefetch(p) => p.run(config).await?,
modifiedcmds/generator-helper/Cargo.tomldiffbeforeafterboth
11fleet-shared.workspace = true11fleet-shared.workspace = true
1212
13base64 = "0.22.1"13base64 = "0.22.1"
14ed25519-dalek = { version = "2.1", features = ["rand_core"] }14ed25519-dalek = { version = "2.1" }
15hex = "0.4.3"15hex = "0.4.3"
16rand = "0.8.5"16rand = "0.9.1"
17x25519-dalek = "2.0.1"17x25519-dalek = { version = "2.0.1", features = ["getrandom"] }
1818
modifiedcmds/generator-helper/src/main.rsdiffbeforeafterboth
11};11};
12use anyhow::{anyhow, bail, ensure, Context, Result};12use anyhow::{anyhow, bail, ensure, Context, Result};
13use clap::{Parser, ValueEnum};13use clap::{Parser, ValueEnum};
14use ed25519_dalek::SecretKey;
14use fleet_shared::SecretData;15use fleet_shared::SecretData;
15use rand::{16use rand::{
16 distributions::{Alphanumeric, DistString, Distribution, Uniform},17 distr::{Alphanumeric, Distribution, SampleString, Uniform},
17 thread_rng, RngCore,18 rng, RngCore,
18};19};
1920
20fn write_output_file(out: &str) -> Result<File> {21fn write_output_file(out: &str) -> Result<File> {
224fn main() -> Result<()> {225fn main() -> Result<()> {
225 let opts = Opts::parse();226 let opts = Opts::parse();
226 // Assumed to be secure, seeded from secure OsRng+reseeded.227 // Assumed to be secure, seeded from secure OsRng+reseeded.
227 let mut rng = thread_rng();228 let mut rng = rng();
228229
229 match opts {230 match opts {
230 Opts::Public { output, encoding } => {231 Opts::Public { output, encoding } => {
245 use ed25519_dalek::SigningKey;246 use ed25519_dalek::SigningKey;
246247
247 let recipients = load_identities()?;248 let recipients = load_identities()?;
249 let mut secret = SecretKey::default();
250 rng.fill_bytes(&mut secret);
251 // TODO: Use SigningKey::generate after https://github.com/dalek-cryptography/curve25519-dalek/pull/762
248 let key = SigningKey::generate(&mut rng).to_keypair_bytes();252 let key = SigningKey::from_bytes(&secret).to_keypair_bytes();
249 write_public(&public, &key[32..], encoding)?;253 write_public(&public, &key[32..], encoding)?;
250 write_private(254 write_private(
251 &recipients,255 &recipients,
268 use x25519_dalek::{PublicKey, StaticSecret};272 use x25519_dalek::{PublicKey, StaticSecret};
269273
270 let recipients = load_identities()?;274 let recipients = load_identities()?;
275 // TODO: Use random_from_rng after https://github.com/dalek-cryptography/curve25519-dalek/pull/762
271 let key = StaticSecret::random_from_rng(rng);276 let key = StaticSecret::random();
272 let public_key: PublicKey = (&key).into();277 let public_key: PublicKey = (&key).into();
273 write_public(&public, public_key.as_bytes().as_slice(), encoding)?;278 write_public(&public, public_key.as_bytes().as_slice(), encoding)?;
274 write_private(&recipients, &private, key.as_bytes().as_slice(), encoding)?;279 write_private(&recipients, &private, key.as_bytes().as_slice(), encoding)?;
290 // Alphabet of Alphanumberic + symbols295 // Alphabet of Alphanumberic + symbols
291 const GEN_ASCII_SYMBOLS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";296 const GEN_ASCII_SYMBOLS: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
292 let uniform = Uniform::new(0, GEN_ASCII_SYMBOLS.len());297 let uniform =
298 Uniform::new(0, GEN_ASCII_SYMBOLS.len()).expect("range is valid");
293 (0..size)299 (0..size)
294 .map(|_| uniform.sample(&mut rng))300 .map(|_| uniform.sample(&mut rng))
295 .map(|i| GEN_ASCII_SYMBOLS[i] as char)301 .map(|i| GEN_ASCII_SYMBOLS[i] as char)
311 let mut bytes = vec![0u8; count];317 let mut bytes = vec![0u8; count];
312 if no_nuls {318 if no_nuls {
313 let rand = Uniform::new_inclusive(0x1u8, 0xffu8).sample_iter(&mut rng);319 let rand = Uniform::new_inclusive(0x1u8, 0xffu8)
320 .expect("range is valid")
321 .sample_iter(&mut rng);
314 for (byte, rand) in bytes.iter_mut().zip(rand) {322 for (byte, rand) in bytes.iter_mut().zip(rand) {
315 *byte = rand;323 *byte = rand;
modifiedcmds/terraform-provider-fleet/Cargo.tomldiffbeforeafterboth
9serde = { workspace = true, features = ["derive"] }9serde = { workspace = true, features = ["derive"] }
10tokio.workspace = true10tokio.workspace = true
1111
12async-trait = "0.1.81"12async-trait = "0.1.88"
13tf-provider = "0.2.2"13tf-provider = "0.2.2"
1414
modifiedcrates/better-command/Cargo.tomldiffbeforeafterboth
5rust-version.workspace = true5rust-version.workspace = true
66
7[dependencies]7[dependencies]
8regex = "1.10"8regex = "1.11"
9serde = { version = "1.0", features = ["derive"] }9serde = { version = "1.0", features = ["derive"] }
10serde_json = "1.0"10serde_json = "1.0"
11tracing = "0.1"11tracing = "0.1"
modifiedcrates/fleet-base/Cargo.tomldiffbeforeafterboth
8age.workspace = true8age.workspace = true
9anyhow.workspace = true9anyhow.workspace = true
10better-command.workspace = true10better-command.workspace = true
11chrono = "0.4.38"11chrono = "0.4.41"
12clap = { workspace = true, features = ["derive"] }12clap = { workspace = true, features = ["derive"] }
13fleet-shared.workspace = true13fleet-shared.workspace = true
14futures = "0.3.30"14futures = "0.3.31"
15hostname = "0.4.0"15hostname = "0.4.1"
16indoc = "2.0.6"16indoc = "2.0.6"
17itertools = "0.13.0"17itertools = "0.14.0"
18nix-eval.workspace = true18nix-eval.workspace = true
19nixlike.workspace = true19nixlike.workspace = true
20nom = "7.1.3"20nom = "8.0.0"
21openssh = "0.11.0"21openssh = "0.11.5"
22rand = "0.8.5"22rand = "0.9.1"
23serde.workspace = true23serde.workspace = true
24serde_json = "1.0.127"24serde_json = "1.0.140"
25tabled = "0.20.0"
25tempfile.workspace = true26tempfile.workspace = true
27time = { version = "0.3.41", features = ["parsing"] }
26tokio.workspace = true28tokio.workspace = true
27tokio-util = "0.7.11"29tokio-util = "0.7.15"
28tracing.workspace = true30tracing.workspace = true
2931
addedcrates/fleet-base/src/deploy.rsdiffbeforeafterboth

no changes

modifiedcrates/fleet-base/src/fleetdata.rsdiffbeforeafterboth
7use chrono::{DateTime, Utc};7use chrono::{DateTime, Utc};
8use fleet_shared::SecretData;8use fleet_shared::SecretData;
9use rand::{9use rand::{
10 distributions::{Alphanumeric, DistString},10 distr::{Alphanumeric, SampleString as _},
11 thread_rng,11 rng,
12};12};
13use serde::{de::Error, Deserialize, Serialize};13use serde::{de::Error, Deserialize, Serialize};
14use serde_json::Value;14use serde_json::Value;
47}47}
4848
49fn generate_gc_prefix() -> String {49fn generate_gc_prefix() -> String {
50 let id = Alphanumeric.sample_string(&mut thread_rng(), 8);50 let id = Alphanumeric.sample_string(&mut rng(), 8);
51 format!("fleet-gc-{id}")51 format!("fleet-gc-{id}")
52}52}
5353
modifiedcrates/fleet-base/src/host.rsdiffbeforeafterboth
15use nix_eval::{nix_go, nix_go_json, util::assert_warn, NixSession, Value};15use nix_eval::{nix_go, nix_go_json, util::assert_warn, NixSession, Value};
16use openssh::SessionBuilder;16use openssh::SessionBuilder;
17use serde::de::DeserializeOwned;17use serde::de::DeserializeOwned;
18use tabled::Tabled;
18use tempfile::NamedTempFile;19use tempfile::NamedTempFile;
20use time::{format_description, UtcDateTime};
21use tracing::warn;
1922
20use crate::{23use crate::{
21 command::MyCommand,24 command::MyCommand,
105 pub session: OnceLock<Arc<openssh::Session>>,108 pub session: OnceLock<Arc<openssh::Session>>,
106}109}
110
111#[derive(Debug, Clone, Copy)]
112pub enum GenerationStorage {
113 Deployer,
114 Machine,
115 Pusher,
116}
117impl GenerationStorage {
118 fn prefix(&self) -> &'static str {
119 match self {
120 GenerationStorage::Deployer => "deployer.",
121 GenerationStorage::Machine => "",
122 GenerationStorage::Pusher => "pusher.",
123 }
124 }
125}
126
127#[derive(Tabled, Debug)]
128pub struct Generation {
129 #[tabled(rename = "ID", format("{}", self.rollback_id()))]
130 pub id: u32,
131 #[tabled(rename = "Current")]
132 pub current: bool,
133 #[tabled(rename = "Created at")]
134 pub datetime: UtcDateTime,
135 #[tabled(format = "{:?}")]
136 pub store_path: PathBuf,
137 #[tabled(skip)]
138 pub location: GenerationStorage,
139}
140impl Generation {
141 pub fn rollback_id(&self) -> String {
142 format!("{}{}", self.location.prefix(), self.id)
143 }
144}
145
146fn parse_generation_line(g: &str) -> Option<Generation> {
147 let mut parts = g.split_whitespace();
148 let id = parts.next()?;
149 let id: u32 = id.parse().ok()?;
150 let date = parts.next()?;
151 let time = parts.next()?;
152 let current = if let Some(current) = parts.next() {
153 if current == "(current)" {
154 Some(true)
155 } else {
156 None
157 }
158 } else {
159 Some(false)
160 };
161 let current = current?;
162 if parts.next().is_some() {
163 warn!("unexpected text after generation: {g}");
164 }
165
166 let format = format_description::parse("[year]-[month]-[day] [hour]:[minute]:[second]")
167 .expect("valid format");
168 let datetime = UtcDateTime::parse(&format!("{date} {time}"), &format).ok()?;
169
170 Some(Generation {
171 id,
172 current,
173 datetime,
174 store_path: PathBuf::new(),
175 location: GenerationStorage::Machine,
176 })
177}
107// TODO: Move command helpers away with connectivity refactor178// TODO: Move command helpers away with connectivity refactor
108impl ConfigHost {179impl ConfigHost {
180 pub async fn list_generations(&self, profile: &str) -> Result<Vec<Generation>> {
181 let mut cmd = self.cmd("nix-env").await?;
182 cmd.comparg("--profile", format!("/nix/var/nix/profiles/{profile}"))
183 .arg("--list-generations")
184 .env("TZ", "UTC");
185 // Sudo is required because --list-generations tries to acquire profile lock
186 let data = cmd.sudo().run_string().await?;
187 let mut generations = data
188 .split('\n')
189 .map(|e| e.trim())
190 .filter(|&l| !l.is_empty())
191 .filter_map(|g| {
192 let gen = parse_generation_line(g);
193 if gen.is_none() {
194 warn!("bad generation: {g}");
195 };
196 gen
197 })
198 .collect::<Vec<_>>();
199 for ele in generations.iter_mut() {
200 let mut cmd = self.cmd("readlink").await?;
201 cmd.arg("--")
202 .arg(format!("/nix/var/nix/profiles/{profile}-{}-link", ele.id));
203 let path = cmd.run_string().await?;
204 ele.store_path = PathBuf::from(path.trim_end_matches("\n"));
205 }
206
207 Ok(generations)
208 }
209
109 pub fn set_deploy_kind(&self, kind: DeployKind) {210 pub fn set_deploy_kind(&self, kind: DeployKind) {
110 self.deploy_kind211 self.deploy_kind
modifiedcrates/fleet-base/src/lib.rsdiffbeforeafterboth
3pub mod host;3pub mod host;
4mod keys;4mod keys;
5pub mod opts;5pub mod opts;
66pub mod deploy;
modifiedcrates/fleet-base/src/opts.rsdiffbeforeafterboth
7};7};
88
9use anyhow::{bail, Context, Result};9use anyhow::{bail, Context, Result};
10use clap::Parser;
11use nix_eval::{nix_go, util::assert_warn, NixSessionPool, Value};10use nix_eval::{nix_go, util::assert_warn, NixSessionPool, Value};
12use nom::{11use nom::{
13 bytes::complete::take_while1,12 bytes::complete::take_while1,
14 character::complete::char,13 character::complete::char,
15 combinator::{map, opt},14 combinator::{map, opt},
16 multi::separated_list1,15 multi::separated_list1,
17 sequence::{preceded, separated_pair},16 sequence::{preceded, separated_pair},
17 Parser,
18};18};
1919
20use crate::{20use crate::{
39 }39 }
4040
41 let (input, is_tag) = map(opt(char('@')), |c| c.is_some())(input).map_err(err_to_string)?;41 let (input, is_tag) = map(opt(char('@')), |c| c.is_some())
42 .parse_complete(input)
43 .map_err(err_to_string)?;
42 let (input, name) = map(44 let (input, name) = map(
43 take_while1(|v| v != ',' && v != '?' && v != '@'),45 take_while1(|v| v != ',' && v != '?' && v != '@'),
44 str::to_owned,46 str::to_owned,
45 )(input)47 ).parse_complete(input)
46 .map_err(err_to_string)?;48 .map_err(err_to_string)?;
4749
48 let kw_item = separated_pair(50 let kw_item = separated_pair(
55 });57 });
56 let mut opt_kw = map(opt(preceded(char('?'), kw)), Option::unwrap_or_default);58 let mut opt_kw = map(opt(preceded(char('?'), kw)), Option::unwrap_or_default);
5759
58 let (input, attrs) = opt_kw(input).map_err(err_to_string)?;60 let (input, attrs) = opt_kw.parse_complete(input).map_err(err_to_string)?;
5961
60 if !input.is_empty() {62 if !input.is_empty() {
61 return Err(format!("unexpected trailing input: {input:?}"));63 return Err(format!("unexpected trailing input: {input:?}"));
68}70}
6971
70// TODO: Rename to HostSelector72// TODO: Rename to HostSelector
71#[derive(Parser, Clone)]73#[derive(clap::Parser, Clone)]
72pub struct FleetOpts {74pub struct FleetOpts {
73 /// All hosts except those would be skipped75 /// All hosts except those would be skipped
74 #[clap(long, number_of_values = 1, value_parser = host_item_parser)]76 #[clap(long, number_of_values = 1, value_parser = host_item_parser)]
modifiedcrates/fleet-shared/Cargo.tomldiffbeforeafterboth
66
7[dependencies]7[dependencies]
8base64 = "0.22.1"8base64 = "0.22.1"
9serde = "1.0.202"9serde = "1.0.219"
10unicode_categories = "0.1.1"10unicode_categories = "0.1.1"
11z85 = "3.0.5"11z85 = "3.0.6"
1212
modifiedcrates/nix-eval/Cargo.tomldiffbeforeafterboth
16tokio-util.workspace = true16tokio-util.workspace = true
17tracing.workspace = true17tracing.workspace = true
1818
19futures = "0.3.30"19futures = "0.3.31"
20itertools = "0.13.0"20itertools = "0.14.0"
21r2d2 = "0.8.10"21r2d2 = "0.8.10"
22regex = "1.10.6"22regex = "1.11.1"
23unindent = "0.2.3"23unindent = "0.2.4"
2424
25# [build-dependencies]25# [build-dependencies]
26# bindgen = "0.69.4"26# bindgen = "0.69.4"
modifiedcrates/nixlike/Cargo.tomldiffbeforeafterboth
99
10alejandra = { git = "https://github.com/kamadorueda/alejandra" }10alejandra = { git = "https://github.com/kamadorueda/alejandra" }
11linked-hash-map = "0.5.6"11linked-hash-map = "0.5.6"
12peg = "0.8.2"12peg = "0.8.5"
13ron = "0.8.1"13ron = "0.10.1"
14serde = "1.0.196"14serde = "1.0.219"
15serde-transcode = "1.1.1"15serde-transcode = "1.1.1"
16serde_json = "1.0.113"16serde_json = "1.0.140"
1717