diff options
| author | diogo464 <[email protected]> | 2024-01-01 18:13:30 +0000 |
|---|---|---|
| committer | diogo464 <[email protected]> | 2024-01-01 18:13:30 +0000 |
| commit | 48d563959b3d6cbe6edc7921cfa1fd22935177d2 (patch) | |
| tree | 59a0518e1309f073172870652bbd00a935065e3c | |
init
| -rw-r--r-- | .gitea/workflows/build.yaml | 11 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Cargo.lock | 922 | ||||
| -rw-r--r-- | Cargo.toml | 21 | ||||
| -rw-r--r-- | README.md | 30 | ||||
| -rw-r--r-- | src/cfg.rs | 90 | ||||
| -rw-r--r-- | src/main.rs | 135 | ||||
| -rw-r--r-- | src/zfs.rs | 87 |
8 files changed, 1297 insertions, 0 deletions
diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..af317fd --- /dev/null +++ b/.gitea/workflows/build.yaml | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | name: build | ||
| 2 | on: [push] | ||
| 3 | jobs: | ||
| 4 | build: | ||
| 5 | runs-on: [ubuntu-latest] | ||
| 6 | steps: | ||
| 7 | - name: Checkout repository | ||
| 8 | uses: actions/checkout@v4 | ||
| 9 | - uses: dtolnay/rust-toolchain@nightly | ||
| 10 | - name: Build | ||
| 11 | run: cargo build --release | ||
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore | |||
| @@ -0,0 +1 @@ | |||
| /target | |||
diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..50a974f --- /dev/null +++ b/Cargo.lock | |||
| @@ -0,0 +1,922 @@ | |||
| 1 | # This file is automatically @generated by Cargo. | ||
| 2 | # It is not intended for manual editing. | ||
| 3 | version = 3 | ||
| 4 | |||
| 5 | [[package]] | ||
| 6 | name = "addr2line" | ||
| 7 | version = "0.21.0" | ||
| 8 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" | ||
| 10 | dependencies = [ | ||
| 11 | "gimli", | ||
| 12 | ] | ||
| 13 | |||
| 14 | [[package]] | ||
| 15 | name = "adler" | ||
| 16 | version = "1.0.2" | ||
| 17 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" | ||
| 19 | |||
| 20 | [[package]] | ||
| 21 | name = "aho-corasick" | ||
| 22 | version = "1.1.2" | ||
| 23 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 24 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" | ||
| 25 | dependencies = [ | ||
| 26 | "memchr", | ||
| 27 | ] | ||
| 28 | |||
| 29 | [[package]] | ||
| 30 | name = "android-tzdata" | ||
| 31 | version = "0.1.1" | ||
| 32 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 33 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" | ||
| 34 | |||
| 35 | [[package]] | ||
| 36 | name = "android_system_properties" | ||
| 37 | version = "0.1.5" | ||
| 38 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 39 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" | ||
| 40 | dependencies = [ | ||
| 41 | "libc", | ||
| 42 | ] | ||
| 43 | |||
| 44 | [[package]] | ||
| 45 | name = "anstream" | ||
| 46 | version = "0.6.5" | ||
| 47 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 48 | checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" | ||
| 49 | dependencies = [ | ||
| 50 | "anstyle", | ||
| 51 | "anstyle-parse", | ||
| 52 | "anstyle-query", | ||
| 53 | "anstyle-wincon", | ||
| 54 | "colorchoice", | ||
| 55 | "utf8parse", | ||
| 56 | ] | ||
| 57 | |||
| 58 | [[package]] | ||
| 59 | name = "anstyle" | ||
| 60 | version = "1.0.4" | ||
| 61 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 62 | checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" | ||
| 63 | |||
| 64 | [[package]] | ||
| 65 | name = "anstyle-parse" | ||
| 66 | version = "0.2.3" | ||
| 67 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 68 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" | ||
| 69 | dependencies = [ | ||
| 70 | "utf8parse", | ||
| 71 | ] | ||
| 72 | |||
| 73 | [[package]] | ||
| 74 | name = "anstyle-query" | ||
| 75 | version = "1.0.2" | ||
| 76 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 77 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" | ||
| 78 | dependencies = [ | ||
| 79 | "windows-sys", | ||
| 80 | ] | ||
| 81 | |||
| 82 | [[package]] | ||
| 83 | name = "anstyle-wincon" | ||
| 84 | version = "3.0.2" | ||
| 85 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 86 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" | ||
| 87 | dependencies = [ | ||
| 88 | "anstyle", | ||
| 89 | "windows-sys", | ||
| 90 | ] | ||
| 91 | |||
| 92 | [[package]] | ||
| 93 | name = "autocfg" | ||
| 94 | version = "1.1.0" | ||
| 95 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 96 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" | ||
| 97 | |||
| 98 | [[package]] | ||
| 99 | name = "backtrace" | ||
| 100 | version = "0.3.69" | ||
| 101 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 102 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" | ||
| 103 | dependencies = [ | ||
| 104 | "addr2line", | ||
| 105 | "cc", | ||
| 106 | "cfg-if", | ||
| 107 | "libc", | ||
| 108 | "miniz_oxide", | ||
| 109 | "object", | ||
| 110 | "rustc-demangle", | ||
| 111 | ] | ||
| 112 | |||
| 113 | [[package]] | ||
| 114 | name = "bumpalo" | ||
| 115 | version = "3.14.0" | ||
| 116 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 117 | checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" | ||
| 118 | |||
| 119 | [[package]] | ||
| 120 | name = "cc" | ||
| 121 | version = "1.0.83" | ||
| 122 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 123 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" | ||
| 124 | dependencies = [ | ||
| 125 | "libc", | ||
| 126 | ] | ||
| 127 | |||
| 128 | [[package]] | ||
| 129 | name = "cfg-if" | ||
| 130 | version = "1.0.0" | ||
| 131 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 132 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" | ||
| 133 | |||
| 134 | [[package]] | ||
| 135 | name = "chrono" | ||
| 136 | version = "0.4.31" | ||
| 137 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 138 | checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" | ||
| 139 | dependencies = [ | ||
| 140 | "android-tzdata", | ||
| 141 | "iana-time-zone", | ||
| 142 | "js-sys", | ||
| 143 | "num-traits", | ||
| 144 | "wasm-bindgen", | ||
| 145 | "windows-targets 0.48.5", | ||
| 146 | ] | ||
| 147 | |||
| 148 | [[package]] | ||
| 149 | name = "clap" | ||
| 150 | version = "4.4.12" | ||
| 151 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 152 | checksum = "dcfab8ba68f3668e89f6ff60f5b205cea56aa7b769451a59f34b8682f51c056d" | ||
| 153 | dependencies = [ | ||
| 154 | "clap_builder", | ||
| 155 | "clap_derive", | ||
| 156 | ] | ||
| 157 | |||
| 158 | [[package]] | ||
| 159 | name = "clap_builder" | ||
| 160 | version = "4.4.12" | ||
| 161 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 162 | checksum = "fb7fb5e4e979aec3be7791562fcba452f94ad85e954da024396433e0e25a79e9" | ||
| 163 | dependencies = [ | ||
| 164 | "anstream", | ||
| 165 | "anstyle", | ||
| 166 | "clap_lex", | ||
| 167 | "strsim", | ||
| 168 | ] | ||
| 169 | |||
| 170 | [[package]] | ||
| 171 | name = "clap_derive" | ||
| 172 | version = "4.4.7" | ||
| 173 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 174 | checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" | ||
| 175 | dependencies = [ | ||
| 176 | "heck", | ||
| 177 | "proc-macro2", | ||
| 178 | "quote", | ||
| 179 | "syn", | ||
| 180 | ] | ||
| 181 | |||
| 182 | [[package]] | ||
| 183 | name = "clap_lex" | ||
| 184 | version = "0.6.0" | ||
| 185 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 186 | checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" | ||
| 187 | |||
| 188 | [[package]] | ||
| 189 | name = "color-eyre" | ||
| 190 | version = "0.6.2" | ||
| 191 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 192 | checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204" | ||
| 193 | dependencies = [ | ||
| 194 | "backtrace", | ||
| 195 | "color-spantrace", | ||
| 196 | "eyre", | ||
| 197 | "indenter", | ||
| 198 | "once_cell", | ||
| 199 | "owo-colors", | ||
| 200 | "tracing-error", | ||
| 201 | ] | ||
| 202 | |||
| 203 | [[package]] | ||
| 204 | name = "color-spantrace" | ||
| 205 | version = "0.2.1" | ||
| 206 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 207 | checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" | ||
| 208 | dependencies = [ | ||
| 209 | "once_cell", | ||
| 210 | "owo-colors", | ||
| 211 | "tracing-core", | ||
| 212 | "tracing-error", | ||
| 213 | ] | ||
| 214 | |||
| 215 | [[package]] | ||
| 216 | name = "colorchoice" | ||
| 217 | version = "1.0.0" | ||
| 218 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 219 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" | ||
| 220 | |||
| 221 | [[package]] | ||
| 222 | name = "core-foundation-sys" | ||
| 223 | version = "0.8.6" | ||
| 224 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 225 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" | ||
| 226 | |||
| 227 | [[package]] | ||
| 228 | name = "cron" | ||
| 229 | version = "0.12.0" | ||
| 230 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 231 | checksum = "1ff76b51e4c068c52bfd2866e1567bee7c567ae8f24ada09fd4307019e25eab7" | ||
| 232 | dependencies = [ | ||
| 233 | "chrono", | ||
| 234 | "nom", | ||
| 235 | "once_cell", | ||
| 236 | ] | ||
| 237 | |||
| 238 | [[package]] | ||
| 239 | name = "equivalent" | ||
| 240 | version = "1.0.1" | ||
| 241 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 242 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" | ||
| 243 | |||
| 244 | [[package]] | ||
| 245 | name = "eyre" | ||
| 246 | version = "0.6.11" | ||
| 247 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 248 | checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" | ||
| 249 | dependencies = [ | ||
| 250 | "indenter", | ||
| 251 | "once_cell", | ||
| 252 | ] | ||
| 253 | |||
| 254 | [[package]] | ||
| 255 | name = "gimli" | ||
| 256 | version = "0.28.1" | ||
| 257 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 258 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" | ||
| 259 | |||
| 260 | [[package]] | ||
| 261 | name = "hashbrown" | ||
| 262 | version = "0.14.3" | ||
| 263 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 264 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" | ||
| 265 | |||
| 266 | [[package]] | ||
| 267 | name = "heck" | ||
| 268 | version = "0.4.1" | ||
| 269 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 270 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" | ||
| 271 | |||
| 272 | [[package]] | ||
| 273 | name = "iana-time-zone" | ||
| 274 | version = "0.1.59" | ||
| 275 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 276 | checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" | ||
| 277 | dependencies = [ | ||
| 278 | "android_system_properties", | ||
| 279 | "core-foundation-sys", | ||
| 280 | "iana-time-zone-haiku", | ||
| 281 | "js-sys", | ||
| 282 | "wasm-bindgen", | ||
| 283 | "windows-core", | ||
| 284 | ] | ||
| 285 | |||
| 286 | [[package]] | ||
| 287 | name = "iana-time-zone-haiku" | ||
| 288 | version = "0.1.2" | ||
| 289 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 290 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" | ||
| 291 | dependencies = [ | ||
| 292 | "cc", | ||
| 293 | ] | ||
| 294 | |||
| 295 | [[package]] | ||
| 296 | name = "indenter" | ||
| 297 | version = "0.3.3" | ||
| 298 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 299 | checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" | ||
| 300 | |||
| 301 | [[package]] | ||
| 302 | name = "indexmap" | ||
| 303 | version = "2.1.0" | ||
| 304 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 305 | checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" | ||
| 306 | dependencies = [ | ||
| 307 | "equivalent", | ||
| 308 | "hashbrown", | ||
| 309 | ] | ||
| 310 | |||
| 311 | [[package]] | ||
| 312 | name = "js-sys" | ||
| 313 | version = "0.3.66" | ||
| 314 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 315 | checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" | ||
| 316 | dependencies = [ | ||
| 317 | "wasm-bindgen", | ||
| 318 | ] | ||
| 319 | |||
| 320 | [[package]] | ||
| 321 | name = "lazy_static" | ||
| 322 | version = "1.4.0" | ||
| 323 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 324 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | ||
| 325 | |||
| 326 | [[package]] | ||
| 327 | name = "libc" | ||
| 328 | version = "0.2.151" | ||
| 329 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 330 | checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" | ||
| 331 | |||
| 332 | [[package]] | ||
| 333 | name = "log" | ||
| 334 | version = "0.4.20" | ||
| 335 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 336 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" | ||
| 337 | |||
| 338 | [[package]] | ||
| 339 | name = "matchers" | ||
| 340 | version = "0.1.0" | ||
| 341 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 342 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" | ||
| 343 | dependencies = [ | ||
| 344 | "regex-automata 0.1.10", | ||
| 345 | ] | ||
| 346 | |||
| 347 | [[package]] | ||
| 348 | name = "memchr" | ||
| 349 | version = "2.7.1" | ||
| 350 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 351 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" | ||
| 352 | |||
| 353 | [[package]] | ||
| 354 | name = "minimal-lexical" | ||
| 355 | version = "0.2.1" | ||
| 356 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 357 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" | ||
| 358 | |||
| 359 | [[package]] | ||
| 360 | name = "miniz_oxide" | ||
| 361 | version = "0.7.1" | ||
| 362 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 363 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" | ||
| 364 | dependencies = [ | ||
| 365 | "adler", | ||
| 366 | ] | ||
| 367 | |||
| 368 | [[package]] | ||
| 369 | name = "nom" | ||
| 370 | version = "7.1.3" | ||
| 371 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 372 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" | ||
| 373 | dependencies = [ | ||
| 374 | "memchr", | ||
| 375 | "minimal-lexical", | ||
| 376 | ] | ||
| 377 | |||
| 378 | [[package]] | ||
| 379 | name = "nu-ansi-term" | ||
| 380 | version = "0.46.0" | ||
| 381 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 382 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" | ||
| 383 | dependencies = [ | ||
| 384 | "overload", | ||
| 385 | "winapi", | ||
| 386 | ] | ||
| 387 | |||
| 388 | [[package]] | ||
| 389 | name = "num-traits" | ||
| 390 | version = "0.2.17" | ||
| 391 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 392 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" | ||
| 393 | dependencies = [ | ||
| 394 | "autocfg", | ||
| 395 | ] | ||
| 396 | |||
| 397 | [[package]] | ||
| 398 | name = "object" | ||
| 399 | version = "0.32.2" | ||
| 400 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 401 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" | ||
| 402 | dependencies = [ | ||
| 403 | "memchr", | ||
| 404 | ] | ||
| 405 | |||
| 406 | [[package]] | ||
| 407 | name = "once_cell" | ||
| 408 | version = "1.19.0" | ||
| 409 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 410 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" | ||
| 411 | |||
| 412 | [[package]] | ||
| 413 | name = "overload" | ||
| 414 | version = "0.1.1" | ||
| 415 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 416 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" | ||
| 417 | |||
| 418 | [[package]] | ||
| 419 | name = "owo-colors" | ||
| 420 | version = "3.5.0" | ||
| 421 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 422 | checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" | ||
| 423 | |||
| 424 | [[package]] | ||
| 425 | name = "pin-project-lite" | ||
| 426 | version = "0.2.13" | ||
| 427 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 428 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" | ||
| 429 | |||
| 430 | [[package]] | ||
| 431 | name = "proc-macro2" | ||
| 432 | version = "1.0.71" | ||
| 433 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 434 | checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" | ||
| 435 | dependencies = [ | ||
| 436 | "unicode-ident", | ||
| 437 | ] | ||
| 438 | |||
| 439 | [[package]] | ||
| 440 | name = "quote" | ||
| 441 | version = "1.0.33" | ||
| 442 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 443 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" | ||
| 444 | dependencies = [ | ||
| 445 | "proc-macro2", | ||
| 446 | ] | ||
| 447 | |||
| 448 | [[package]] | ||
| 449 | name = "regex" | ||
| 450 | version = "1.10.2" | ||
| 451 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 452 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" | ||
| 453 | dependencies = [ | ||
| 454 | "aho-corasick", | ||
| 455 | "memchr", | ||
| 456 | "regex-automata 0.4.3", | ||
| 457 | "regex-syntax 0.8.2", | ||
| 458 | ] | ||
| 459 | |||
| 460 | [[package]] | ||
| 461 | name = "regex-automata" | ||
| 462 | version = "0.1.10" | ||
| 463 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 464 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" | ||
| 465 | dependencies = [ | ||
| 466 | "regex-syntax 0.6.29", | ||
| 467 | ] | ||
| 468 | |||
| 469 | [[package]] | ||
| 470 | name = "regex-automata" | ||
| 471 | version = "0.4.3" | ||
| 472 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 473 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" | ||
| 474 | dependencies = [ | ||
| 475 | "aho-corasick", | ||
| 476 | "memchr", | ||
| 477 | "regex-syntax 0.8.2", | ||
| 478 | ] | ||
| 479 | |||
| 480 | [[package]] | ||
| 481 | name = "regex-syntax" | ||
| 482 | version = "0.6.29" | ||
| 483 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 484 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" | ||
| 485 | |||
| 486 | [[package]] | ||
| 487 | name = "regex-syntax" | ||
| 488 | version = "0.8.2" | ||
| 489 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 490 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" | ||
| 491 | |||
| 492 | [[package]] | ||
| 493 | name = "rustc-demangle" | ||
| 494 | version = "0.1.23" | ||
| 495 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 496 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" | ||
| 497 | |||
| 498 | [[package]] | ||
| 499 | name = "serde" | ||
| 500 | version = "1.0.193" | ||
| 501 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 502 | checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" | ||
| 503 | dependencies = [ | ||
| 504 | "serde_derive", | ||
| 505 | ] | ||
| 506 | |||
| 507 | [[package]] | ||
| 508 | name = "serde_derive" | ||
| 509 | version = "1.0.193" | ||
| 510 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 511 | checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" | ||
| 512 | dependencies = [ | ||
| 513 | "proc-macro2", | ||
| 514 | "quote", | ||
| 515 | "syn", | ||
| 516 | ] | ||
| 517 | |||
| 518 | [[package]] | ||
| 519 | name = "serde_spanned" | ||
| 520 | version = "0.6.5" | ||
| 521 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 522 | checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" | ||
| 523 | dependencies = [ | ||
| 524 | "serde", | ||
| 525 | ] | ||
| 526 | |||
| 527 | [[package]] | ||
| 528 | name = "sharded-slab" | ||
| 529 | version = "0.1.7" | ||
| 530 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 531 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" | ||
| 532 | dependencies = [ | ||
| 533 | "lazy_static", | ||
| 534 | ] | ||
| 535 | |||
| 536 | [[package]] | ||
| 537 | name = "smallvec" | ||
| 538 | version = "1.11.2" | ||
| 539 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 540 | checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" | ||
| 541 | |||
| 542 | [[package]] | ||
| 543 | name = "strsim" | ||
| 544 | version = "0.10.0" | ||
| 545 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 546 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" | ||
| 547 | |||
| 548 | [[package]] | ||
| 549 | name = "syn" | ||
| 550 | version = "2.0.43" | ||
| 551 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 552 | checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" | ||
| 553 | dependencies = [ | ||
| 554 | "proc-macro2", | ||
| 555 | "quote", | ||
| 556 | "unicode-ident", | ||
| 557 | ] | ||
| 558 | |||
| 559 | [[package]] | ||
| 560 | name = "thread_local" | ||
| 561 | version = "1.1.7" | ||
| 562 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 563 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" | ||
| 564 | dependencies = [ | ||
| 565 | "cfg-if", | ||
| 566 | "once_cell", | ||
| 567 | ] | ||
| 568 | |||
| 569 | [[package]] | ||
| 570 | name = "toml" | ||
| 571 | version = "0.8.8" | ||
| 572 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 573 | checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" | ||
| 574 | dependencies = [ | ||
| 575 | "serde", | ||
| 576 | "serde_spanned", | ||
| 577 | "toml_datetime", | ||
| 578 | "toml_edit", | ||
| 579 | ] | ||
| 580 | |||
| 581 | [[package]] | ||
| 582 | name = "toml_datetime" | ||
| 583 | version = "0.6.5" | ||
| 584 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 585 | checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" | ||
| 586 | dependencies = [ | ||
| 587 | "serde", | ||
| 588 | ] | ||
| 589 | |||
| 590 | [[package]] | ||
| 591 | name = "toml_edit" | ||
| 592 | version = "0.21.0" | ||
| 593 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 594 | checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" | ||
| 595 | dependencies = [ | ||
| 596 | "indexmap", | ||
| 597 | "serde", | ||
| 598 | "serde_spanned", | ||
| 599 | "toml_datetime", | ||
| 600 | "winnow", | ||
| 601 | ] | ||
| 602 | |||
| 603 | [[package]] | ||
| 604 | name = "tracing" | ||
| 605 | version = "0.1.40" | ||
| 606 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 607 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" | ||
| 608 | dependencies = [ | ||
| 609 | "pin-project-lite", | ||
| 610 | "tracing-attributes", | ||
| 611 | "tracing-core", | ||
| 612 | ] | ||
| 613 | |||
| 614 | [[package]] | ||
| 615 | name = "tracing-attributes" | ||
| 616 | version = "0.1.27" | ||
| 617 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 618 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" | ||
| 619 | dependencies = [ | ||
| 620 | "proc-macro2", | ||
| 621 | "quote", | ||
| 622 | "syn", | ||
| 623 | ] | ||
| 624 | |||
| 625 | [[package]] | ||
| 626 | name = "tracing-core" | ||
| 627 | version = "0.1.32" | ||
| 628 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 629 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" | ||
| 630 | dependencies = [ | ||
| 631 | "once_cell", | ||
| 632 | "valuable", | ||
| 633 | ] | ||
| 634 | |||
| 635 | [[package]] | ||
| 636 | name = "tracing-error" | ||
| 637 | version = "0.2.0" | ||
| 638 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 639 | checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" | ||
| 640 | dependencies = [ | ||
| 641 | "tracing", | ||
| 642 | "tracing-subscriber", | ||
| 643 | ] | ||
| 644 | |||
| 645 | [[package]] | ||
| 646 | name = "tracing-log" | ||
| 647 | version = "0.2.0" | ||
| 648 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 649 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" | ||
| 650 | dependencies = [ | ||
| 651 | "log", | ||
| 652 | "once_cell", | ||
| 653 | "tracing-core", | ||
| 654 | ] | ||
| 655 | |||
| 656 | [[package]] | ||
| 657 | name = "tracing-subscriber" | ||
| 658 | version = "0.3.18" | ||
| 659 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 660 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" | ||
| 661 | dependencies = [ | ||
| 662 | "matchers", | ||
| 663 | "nu-ansi-term", | ||
| 664 | "once_cell", | ||
| 665 | "regex", | ||
| 666 | "sharded-slab", | ||
| 667 | "smallvec", | ||
| 668 | "thread_local", | ||
| 669 | "tracing", | ||
| 670 | "tracing-core", | ||
| 671 | "tracing-log", | ||
| 672 | ] | ||
| 673 | |||
| 674 | [[package]] | ||
| 675 | name = "unicode-ident" | ||
| 676 | version = "1.0.12" | ||
| 677 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 678 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" | ||
| 679 | |||
| 680 | [[package]] | ||
| 681 | name = "utf8parse" | ||
| 682 | version = "0.2.1" | ||
| 683 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 684 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" | ||
| 685 | |||
| 686 | [[package]] | ||
| 687 | name = "valuable" | ||
| 688 | version = "0.1.0" | ||
| 689 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 690 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" | ||
| 691 | |||
| 692 | [[package]] | ||
| 693 | name = "wasm-bindgen" | ||
| 694 | version = "0.2.89" | ||
| 695 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 696 | checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" | ||
| 697 | dependencies = [ | ||
| 698 | "cfg-if", | ||
| 699 | "wasm-bindgen-macro", | ||
| 700 | ] | ||
| 701 | |||
| 702 | [[package]] | ||
| 703 | name = "wasm-bindgen-backend" | ||
| 704 | version = "0.2.89" | ||
| 705 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 706 | checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" | ||
| 707 | dependencies = [ | ||
| 708 | "bumpalo", | ||
| 709 | "log", | ||
| 710 | "once_cell", | ||
| 711 | "proc-macro2", | ||
| 712 | "quote", | ||
| 713 | "syn", | ||
| 714 | "wasm-bindgen-shared", | ||
| 715 | ] | ||
| 716 | |||
| 717 | [[package]] | ||
| 718 | name = "wasm-bindgen-macro" | ||
| 719 | version = "0.2.89" | ||
| 720 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 721 | checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" | ||
| 722 | dependencies = [ | ||
| 723 | "quote", | ||
| 724 | "wasm-bindgen-macro-support", | ||
| 725 | ] | ||
| 726 | |||
| 727 | [[package]] | ||
| 728 | name = "wasm-bindgen-macro-support" | ||
| 729 | version = "0.2.89" | ||
| 730 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 731 | checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" | ||
| 732 | dependencies = [ | ||
| 733 | "proc-macro2", | ||
| 734 | "quote", | ||
| 735 | "syn", | ||
| 736 | "wasm-bindgen-backend", | ||
| 737 | "wasm-bindgen-shared", | ||
| 738 | ] | ||
| 739 | |||
| 740 | [[package]] | ||
| 741 | name = "wasm-bindgen-shared" | ||
| 742 | version = "0.2.89" | ||
| 743 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 744 | checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" | ||
| 745 | |||
| 746 | [[package]] | ||
| 747 | name = "winapi" | ||
| 748 | version = "0.3.9" | ||
| 749 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 750 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | ||
| 751 | dependencies = [ | ||
| 752 | "winapi-i686-pc-windows-gnu", | ||
| 753 | "winapi-x86_64-pc-windows-gnu", | ||
| 754 | ] | ||
| 755 | |||
| 756 | [[package]] | ||
| 757 | name = "winapi-i686-pc-windows-gnu" | ||
| 758 | version = "0.4.0" | ||
| 759 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 760 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||
| 761 | |||
| 762 | [[package]] | ||
| 763 | name = "winapi-x86_64-pc-windows-gnu" | ||
| 764 | version = "0.4.0" | ||
| 765 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 766 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | ||
| 767 | |||
| 768 | [[package]] | ||
| 769 | name = "windows-core" | ||
| 770 | version = "0.52.0" | ||
| 771 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 772 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" | ||
| 773 | dependencies = [ | ||
| 774 | "windows-targets 0.52.0", | ||
| 775 | ] | ||
| 776 | |||
| 777 | [[package]] | ||
| 778 | name = "windows-sys" | ||
| 779 | version = "0.52.0" | ||
| 780 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 781 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" | ||
| 782 | dependencies = [ | ||
| 783 | "windows-targets 0.52.0", | ||
| 784 | ] | ||
| 785 | |||
| 786 | [[package]] | ||
| 787 | name = "windows-targets" | ||
| 788 | version = "0.48.5" | ||
| 789 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 790 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" | ||
| 791 | dependencies = [ | ||
| 792 | "windows_aarch64_gnullvm 0.48.5", | ||
| 793 | "windows_aarch64_msvc 0.48.5", | ||
| 794 | "windows_i686_gnu 0.48.5", | ||
| 795 | "windows_i686_msvc 0.48.5", | ||
| 796 | "windows_x86_64_gnu 0.48.5", | ||
| 797 | "windows_x86_64_gnullvm 0.48.5", | ||
| 798 | "windows_x86_64_msvc 0.48.5", | ||
| 799 | ] | ||
| 800 | |||
| 801 | [[package]] | ||
| 802 | name = "windows-targets" | ||
| 803 | version = "0.52.0" | ||
| 804 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 805 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" | ||
| 806 | dependencies = [ | ||
| 807 | "windows_aarch64_gnullvm 0.52.0", | ||
| 808 | "windows_aarch64_msvc 0.52.0", | ||
| 809 | "windows_i686_gnu 0.52.0", | ||
| 810 | "windows_i686_msvc 0.52.0", | ||
| 811 | "windows_x86_64_gnu 0.52.0", | ||
| 812 | "windows_x86_64_gnullvm 0.52.0", | ||
| 813 | "windows_x86_64_msvc 0.52.0", | ||
| 814 | ] | ||
| 815 | |||
| 816 | [[package]] | ||
| 817 | name = "windows_aarch64_gnullvm" | ||
| 818 | version = "0.48.5" | ||
| 819 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 820 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" | ||
| 821 | |||
| 822 | [[package]] | ||
| 823 | name = "windows_aarch64_gnullvm" | ||
| 824 | version = "0.52.0" | ||
| 825 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 826 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" | ||
| 827 | |||
| 828 | [[package]] | ||
| 829 | name = "windows_aarch64_msvc" | ||
| 830 | version = "0.48.5" | ||
| 831 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 832 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" | ||
| 833 | |||
| 834 | [[package]] | ||
| 835 | name = "windows_aarch64_msvc" | ||
| 836 | version = "0.52.0" | ||
| 837 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 838 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" | ||
| 839 | |||
| 840 | [[package]] | ||
| 841 | name = "windows_i686_gnu" | ||
| 842 | version = "0.48.5" | ||
| 843 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 844 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" | ||
| 845 | |||
| 846 | [[package]] | ||
| 847 | name = "windows_i686_gnu" | ||
| 848 | version = "0.52.0" | ||
| 849 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 850 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" | ||
| 851 | |||
| 852 | [[package]] | ||
| 853 | name = "windows_i686_msvc" | ||
| 854 | version = "0.48.5" | ||
| 855 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 856 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" | ||
| 857 | |||
| 858 | [[package]] | ||
| 859 | name = "windows_i686_msvc" | ||
| 860 | version = "0.52.0" | ||
| 861 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 862 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" | ||
| 863 | |||
| 864 | [[package]] | ||
| 865 | name = "windows_x86_64_gnu" | ||
| 866 | version = "0.48.5" | ||
| 867 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 868 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" | ||
| 869 | |||
| 870 | [[package]] | ||
| 871 | name = "windows_x86_64_gnu" | ||
| 872 | version = "0.52.0" | ||
| 873 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 874 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" | ||
| 875 | |||
| 876 | [[package]] | ||
| 877 | name = "windows_x86_64_gnullvm" | ||
| 878 | version = "0.48.5" | ||
| 879 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 880 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" | ||
| 881 | |||
| 882 | [[package]] | ||
| 883 | name = "windows_x86_64_gnullvm" | ||
| 884 | version = "0.52.0" | ||
| 885 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 886 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" | ||
| 887 | |||
| 888 | [[package]] | ||
| 889 | name = "windows_x86_64_msvc" | ||
| 890 | version = "0.48.5" | ||
| 891 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 892 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" | ||
| 893 | |||
| 894 | [[package]] | ||
| 895 | name = "windows_x86_64_msvc" | ||
| 896 | version = "0.52.0" | ||
| 897 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 898 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" | ||
| 899 | |||
| 900 | [[package]] | ||
| 901 | name = "winnow" | ||
| 902 | version = "0.5.31" | ||
| 903 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 904 | checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c" | ||
| 905 | dependencies = [ | ||
| 906 | "memchr", | ||
| 907 | ] | ||
| 908 | |||
| 909 | [[package]] | ||
| 910 | name = "zsnap" | ||
| 911 | version = "0.1.0" | ||
| 912 | dependencies = [ | ||
| 913 | "chrono", | ||
| 914 | "clap", | ||
| 915 | "color-eyre", | ||
| 916 | "cron", | ||
| 917 | "eyre", | ||
| 918 | "serde", | ||
| 919 | "toml", | ||
| 920 | "tracing", | ||
| 921 | "tracing-subscriber", | ||
| 922 | ] | ||
diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..221fcd3 --- /dev/null +++ b/Cargo.toml | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | [package] | ||
| 2 | name = "zsnap" | ||
| 3 | version = "0.1.0" | ||
| 4 | edition = "2021" | ||
| 5 | |||
| 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
| 7 | |||
| 8 | [dependencies] | ||
| 9 | chrono = "0.4.31" | ||
| 10 | clap = { version = "4.4.12", features = ["env", "derive"] } | ||
| 11 | color-eyre = "0.6.2" | ||
| 12 | cron = "0.12.0" | ||
| 13 | eyre = "0.6.11" | ||
| 14 | serde = { version = "1.0.193", features = ["derive"] } | ||
| 15 | toml = "0.8.8" | ||
| 16 | tracing = "0.1.40" | ||
| 17 | tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } | ||
| 18 | |||
| 19 | [profile.release] | ||
| 20 | strip = true | ||
| 21 | opt-level = "z" | ||
diff --git a/README.md b/README.md new file mode 100644 index 0000000..864dfdf --- /dev/null +++ b/README.md | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | # zsnap | ||
| 2 | |||
| 3 | zsnap [--config zsnap.toml] run | ||
| 4 | zsnap [--config zsnap.toml] snapshot --tag my-tag dataset | ||
| 5 | zsnap [--config zsnap.toml] prune [--tag my-tag] [--keep n] dataset | ||
| 6 | |||
| 7 | ```zsnap.toml | ||
| 8 | [dataset."blackmesa/k8s"] | ||
| 9 | schedules = ["hourly", "daily", "weekly", "monthly"] | ||
| 10 | recursive = true | ||
| 11 | |||
| 12 | [dataset."blackmesa/gitea"] | ||
| 13 | schedules = ["hourly", "daily", "weekly", "monthly"] | ||
| 14 | |||
| 15 | [schedule.hourly] | ||
| 16 | cron = "@hourly" | ||
| 17 | keep = 24 | ||
| 18 | |||
| 19 | [schedule.daily] | ||
| 20 | cron = "@daily" | ||
| 21 | keep = 7 | ||
| 22 | |||
| 23 | [schedule.weekly] | ||
| 24 | cron = "@weekly" | ||
| 25 | keep = 4 | ||
| 26 | |||
| 27 | [schedule.monthly] | ||
| 28 | cron = "@monthly" | ||
| 29 | keep = 6 | ||
| 30 | ``` | ||
diff --git a/src/cfg.rs b/src/cfg.rs new file mode 100644 index 0000000..6c3740c --- /dev/null +++ b/src/cfg.rs | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | use std::{collections::HashMap, path::Path, str::FromStr}; | ||
| 2 | |||
| 3 | use eyre::{Context, Result}; | ||
| 4 | use serde::Deserialize; | ||
| 5 | |||
| 6 | #[derive(Debug, Default)] | ||
| 7 | pub struct Config { | ||
| 8 | pub datasets: Vec<Dataset>, | ||
| 9 | pub schedules: Vec<Schedule>, | ||
| 10 | } | ||
| 11 | |||
| 12 | impl Config { | ||
| 13 | pub fn dataset(&self, name: &str) -> Option<&Dataset> { | ||
| 14 | self.datasets.iter().find(|d| d.name == name) | ||
| 15 | } | ||
| 16 | |||
| 17 | pub fn tag(&self, tag: &str) -> Option<&Schedule> { | ||
| 18 | self.schedules.iter().find(|s| s.tag == tag) | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | #[derive(Debug, Clone)] | ||
| 23 | pub struct Dataset { | ||
| 24 | pub name: String, | ||
| 25 | pub schedules: Vec<String>, | ||
| 26 | pub recursive: bool, | ||
| 27 | } | ||
| 28 | |||
| 29 | impl Dataset { | ||
| 30 | pub fn has_tag(&self, tag: &str) -> bool { | ||
| 31 | self.schedules.iter().any(|s| s == tag) | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | #[derive(Debug, Clone)] | ||
| 36 | pub struct Schedule { | ||
| 37 | pub tag: String, | ||
| 38 | pub cron: cron::Schedule, | ||
| 39 | pub keep: usize, | ||
| 40 | } | ||
| 41 | |||
| 42 | #[derive(Debug, Deserialize)] | ||
| 43 | struct TomlConfig { | ||
| 44 | dataset: HashMap<String, TomlDataset>, | ||
| 45 | schedule: HashMap<String, TomlSchedule>, | ||
| 46 | } | ||
| 47 | |||
| 48 | #[derive(Debug, Deserialize)] | ||
| 49 | struct TomlDataset { | ||
| 50 | recursive: Option<bool>, | ||
| 51 | schedules: Vec<String>, | ||
| 52 | } | ||
| 53 | |||
| 54 | #[derive(Debug, Deserialize)] | ||
| 55 | struct TomlSchedule { | ||
| 56 | cron: String, | ||
| 57 | keep: usize, | ||
| 58 | } | ||
| 59 | |||
| 60 | pub fn read(path: &Path) -> Result<Config> { | ||
| 61 | let content = std::fs::read_to_string(path)?; | ||
| 62 | let config = toml::from_str::<TomlConfig>(&content)?; | ||
| 63 | |||
| 64 | let mut datasets = Vec::new(); | ||
| 65 | let mut schedules = Vec::new(); | ||
| 66 | |||
| 67 | for (name, dataset) in config.dataset { | ||
| 68 | let schedules = dataset.schedules; | ||
| 69 | let recursive = dataset.recursive; | ||
| 70 | |||
| 71 | datasets.push(Dataset { | ||
| 72 | name, | ||
| 73 | schedules, | ||
| 74 | recursive: recursive.unwrap_or_default(), | ||
| 75 | }); | ||
| 76 | } | ||
| 77 | |||
| 78 | for (name, schedule) in config.schedule { | ||
| 79 | let cron = cron::Schedule::from_str(&schedule.cron) | ||
| 80 | .with_context(|| format!("parsing cron schedule: '{}'", &schedule.cron))?; | ||
| 81 | let keep = schedule.keep; | ||
| 82 | |||
| 83 | schedules.push(Schedule { tag: name, cron, keep }); | ||
| 84 | } | ||
| 85 | |||
| 86 | Ok(Config { | ||
| 87 | datasets, | ||
| 88 | schedules, | ||
| 89 | }) | ||
| 90 | } | ||
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e31764d --- /dev/null +++ b/src/main.rs | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | #![feature(try_blocks)] | ||
| 2 | use std::path::PathBuf; | ||
| 3 | |||
| 4 | use clap::Parser; | ||
| 5 | use eyre::{Context, Result}; | ||
| 6 | |||
| 7 | mod cfg; | ||
| 8 | mod zfs; | ||
| 9 | |||
| 10 | #[derive(Debug, Parser)] | ||
| 11 | struct Args { | ||
| 12 | /// Path to the configuration file | ||
| 13 | #[clap(long, env = "ZSNAP_CONFIG")] | ||
| 14 | config: Option<PathBuf>, | ||
| 15 | |||
| 16 | #[clap(subcommand)] | ||
| 17 | command: Subcommand, | ||
| 18 | } | ||
| 19 | |||
| 20 | #[derive(Debug, Parser)] | ||
| 21 | enum Subcommand { | ||
| 22 | Run(RunArgs), | ||
| 23 | Snapshot(SnapshotArgs), | ||
| 24 | Prune(PruneArgs), | ||
| 25 | } | ||
| 26 | |||
| 27 | #[derive(Debug, Parser)] | ||
| 28 | struct RunArgs {} | ||
| 29 | |||
| 30 | #[derive(Debug, Parser)] | ||
| 31 | struct SnapshotArgs { | ||
| 32 | /// the tag to snapshot with | ||
| 33 | #[clap(long)] | ||
| 34 | tag: String, | ||
| 35 | |||
| 36 | #[clap(long)] | ||
| 37 | recursive: bool, | ||
| 38 | |||
| 39 | /// the datasets to snapshot | ||
| 40 | dataset: Vec<String>, | ||
| 41 | } | ||
| 42 | |||
| 43 | #[derive(Debug, Parser)] | ||
| 44 | struct PruneArgs { | ||
| 45 | /// the tag to prune | ||
| 46 | #[clap(long)] | ||
| 47 | tag: String, | ||
| 48 | |||
| 49 | /// the number of snapshots to keep | ||
| 50 | #[clap(long)] | ||
| 51 | keep: usize, | ||
| 52 | |||
| 53 | /// whether to prune recursively | ||
| 54 | #[clap(long)] | ||
| 55 | recursive: bool, | ||
| 56 | |||
| 57 | /// the datasets to prune | ||
| 58 | dataset: Vec<String>, | ||
| 59 | } | ||
| 60 | |||
| 61 | fn main() -> Result<()> { | ||
| 62 | color_eyre::install()?; | ||
| 63 | tracing_subscriber::fmt::init(); | ||
| 64 | |||
| 65 | let args = Args::parse(); | ||
| 66 | let config = match args.config { | ||
| 67 | Some(config_path) => cfg::read(&config_path).context("reading config")?, | ||
| 68 | None => Default::default(), | ||
| 69 | }; | ||
| 70 | |||
| 71 | match args.command { | ||
| 72 | Subcommand::Run(_) => cmd_run(config), | ||
| 73 | Subcommand::Snapshot(args) => cmd_snapshot(args), | ||
| 74 | Subcommand::Prune(args) => cmd_prune(args), | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | fn cmd_run(config: cfg::Config) -> Result<()> { | ||
| 79 | for schedule in config.schedules { | ||
| 80 | let datasets = config.datasets.clone(); | ||
| 81 | std::thread::spawn(move || snapshot_mainloop(schedule, datasets)); | ||
| 82 | } | ||
| 83 | loop { | ||
| 84 | std::thread::park(); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | fn cmd_snapshot(args: SnapshotArgs) -> Result<()> { | ||
| 89 | for dataset in args.dataset { | ||
| 90 | zfs::snapshot_create(&args.tag, &dataset, args.recursive)?; | ||
| 91 | } | ||
| 92 | Ok(()) | ||
| 93 | } | ||
| 94 | |||
| 95 | fn cmd_prune(args: PruneArgs) -> Result<()> { | ||
| 96 | for dataset in args.dataset { | ||
| 97 | zfs::snapshot_prune(&args.tag, &dataset, args.recursive, args.keep)?; | ||
| 98 | } | ||
| 99 | Ok(()) | ||
| 100 | } | ||
| 101 | |||
| 102 | fn snapshot_mainloop(schedule: cfg::Schedule, datasets: Vec<cfg::Dataset>) { | ||
| 103 | for next_trigger in schedule.cron.upcoming(chrono::Utc) { | ||
| 104 | let now = chrono::Utc::now().timestamp(); | ||
| 105 | let next = next_trigger.timestamp(); | ||
| 106 | let sleep = next.saturating_sub(now) as u64; | ||
| 107 | std::thread::sleep(std::time::Duration::from_secs(sleep)); | ||
| 108 | |||
| 109 | for dataset in datasets.iter().filter(|d| d.has_tag(&schedule.tag)) { | ||
| 110 | if let Err(err) = zfs::snapshot_create(&schedule.tag, &dataset.name, dataset.recursive) | ||
| 111 | { | ||
| 112 | tracing::error!( | ||
| 113 | tag = schedule.tag, | ||
| 114 | dataset = dataset.name, | ||
| 115 | "failed to create snapshot: {:#}", | ||
| 116 | err | ||
| 117 | ); | ||
| 118 | } | ||
| 119 | |||
| 120 | if let Err(err) = zfs::snapshot_prune( | ||
| 121 | &schedule.tag, | ||
| 122 | &dataset.name, | ||
| 123 | dataset.recursive, | ||
| 124 | schedule.keep, | ||
| 125 | ) { | ||
| 126 | tracing::error!( | ||
| 127 | tag = schedule.tag, | ||
| 128 | dataset = dataset.name, | ||
| 129 | "failed to prune snapshots: {:#}", | ||
| 130 | err | ||
| 131 | ); | ||
| 132 | } | ||
| 133 | } | ||
| 134 | } | ||
| 135 | } | ||
diff --git a/src/zfs.rs b/src/zfs.rs new file mode 100644 index 0000000..380efa6 --- /dev/null +++ b/src/zfs.rs | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | use std::process::Command; | ||
| 2 | |||
| 3 | use eyre::{Context, Result}; | ||
| 4 | |||
| 5 | const PROPERTY_TAG: &str = "zsnap:tag"; | ||
| 6 | |||
| 7 | #[derive(Debug)] | ||
| 8 | struct ZfsSnapshot { | ||
| 9 | name: String, | ||
| 10 | dataset: String, | ||
| 11 | time: chrono::DateTime<chrono::Utc>, | ||
| 12 | tag: String, | ||
| 13 | } | ||
| 14 | |||
| 15 | pub fn snapshot_create(tag: &str, dataset: &str, recursive: bool) -> Result<()> { | ||
| 16 | let time = chrono::Utc::now(); | ||
| 17 | let name = format!("{}@{}", dataset, time.format("zsnap_%Y-%m-%d_%H-%M-%S")); | ||
| 18 | let rec = if recursive { "-r" } else { "" }; | ||
| 19 | let cmd = format!("zfs snapshot -o {PROPERTY_TAG}={tag} {rec} {name}"); | ||
| 20 | let _output = run_shell_command(&cmd)?; | ||
| 21 | Ok(()) | ||
| 22 | } | ||
| 23 | |||
| 24 | pub fn snapshot_prune(tag: &str, dataset: &str, recursive: bool, keep: usize) -> Result<()> { | ||
| 25 | let mut snapshots = zfs_snapshot_list()? | ||
| 26 | .into_iter() | ||
| 27 | .filter(|s| s.dataset == dataset && s.tag == tag) | ||
| 28 | .collect::<Vec<_>>(); | ||
| 29 | snapshots.sort_by_key(|s| s.time); | ||
| 30 | snapshots.reverse(); | ||
| 31 | tracing::trace!("snapshots for dataset '{dataset}': {snapshots:?}"); | ||
| 32 | tracing::trace!("skipping {keep} snapshots"); | ||
| 33 | |||
| 34 | for snapshot in snapshots.into_iter().skip(keep) { | ||
| 35 | tracing::debug!(name = snapshot.name.as_str(), "destroying snapshot"); | ||
| 36 | let rec = if recursive { "-r" } else { "" }; | ||
| 37 | let cmd = format!("zfs destroy {} {}", rec, snapshot.name); | ||
| 38 | let _output = run_shell_command(&cmd)?; | ||
| 39 | } | ||
| 40 | |||
| 41 | Ok(()) | ||
| 42 | } | ||
| 43 | |||
| 44 | fn zfs_snapshot_list() -> Result<Vec<ZfsSnapshot>> { | ||
| 45 | fn parse_line(line: &str) -> Option<ZfsSnapshot> { | ||
| 46 | let mut parts = line.split('\t'); | ||
| 47 | let name = parts.next()?; | ||
| 48 | let tag = parts.next()?; | ||
| 49 | |||
| 50 | let mut parts = name.split('@'); | ||
| 51 | let dataset = parts.next()?; | ||
| 52 | let time = parts.next()?; | ||
| 53 | let time = chrono::NaiveDateTime::parse_from_str(time, "zsnap_%Y-%m-%d_%H-%M-%S").ok()?; | ||
| 54 | |||
| 55 | if tag == "-" { | ||
| 56 | return None; | ||
| 57 | } | ||
| 58 | |||
| 59 | Some(ZfsSnapshot { | ||
| 60 | name: name.to_string(), | ||
| 61 | dataset: dataset.to_string(), | ||
| 62 | time: time.and_utc(), | ||
| 63 | tag: tag.to_string(), | ||
| 64 | }) | ||
| 65 | } | ||
| 66 | |||
| 67 | let output = run_shell_command(&format!("zfs list -H -t snapshot -o name,{PROPERTY_TAG}"))?; | ||
| 68 | Ok(output.lines().filter_map(parse_line).collect()) | ||
| 69 | } | ||
| 70 | |||
| 71 | fn run_shell_command(cmd: &str) -> Result<String> { | ||
| 72 | tracing::debug!("running shell command '{cmd}'"); | ||
| 73 | let output = Command::new("/bin/sh") | ||
| 74 | .arg("-c") | ||
| 75 | .arg(cmd) | ||
| 76 | .output() | ||
| 77 | .with_context(|| format!("running shell command '{cmd}'"))?; | ||
| 78 | if !output.status.success() { | ||
| 79 | let stderr = String::from_utf8(output.stderr).context("converting shell output to utf8")?; | ||
| 80 | let stderr = stderr.trim(); | ||
| 81 | tracing::error!("shell command failed: '{stderr}'"); | ||
| 82 | return Err(eyre::eyre!("shell command failed: '{stderr}'")); | ||
| 83 | } | ||
| 84 | let output = String::from_utf8(output.stdout).context("converting shell output to utf8")?; | ||
| 85 | tracing::trace!("shell command output: '{output}'"); | ||
| 86 | Ok(output) | ||
| 87 | } | ||
