├── .github ├── dependabot.yml └── workflows │ └── rust.yml ├── .gitignore ├── .rpm └── canister.spec ├── CHANGES.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── canister.toml.example └── src ├── application.rs ├── commands ├── deploy.rs ├── mod.rs ├── run.rs └── version.rs ├── config └── mod.rs ├── error.rs ├── gcp ├── gcr.rs ├── mod.rs ├── oauth.rs └── storage.rs ├── main.rs ├── packer.rs ├── prelude.rs └── unpacker.rs /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: '13:00' 8 | open-pull-requests-limit: 10 9 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: develop 4 | pull_request: {} 5 | 6 | name: Rust 7 | 8 | jobs: 9 | 10 | check: 11 | name: Check 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v1 15 | - uses: actions-rs/toolchain@v1 16 | with: 17 | toolchain: stable 18 | override: true 19 | - uses: actions-rs/cargo@v1 20 | with: 21 | command: check 22 | 23 | test: 24 | name: Test Suite 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v1 28 | - uses: actions-rs/toolchain@v1 29 | with: 30 | toolchain: stable 31 | override: true 32 | - uses: actions-rs/cargo@v1 33 | with: 34 | command: test 35 | 36 | fmt: 37 | name: Rustfmt 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@v1 41 | - uses: actions-rs/toolchain@v1 42 | with: 43 | toolchain: stable 44 | override: true 45 | - run: rustup component add rustfmt 46 | - uses: actions-rs/cargo@v1 47 | with: 48 | command: fmt 49 | args: --all -- --check 50 | 51 | 52 | clippy: 53 | runs-on: ubuntu-latest 54 | steps: 55 | - uses: actions/checkout@v1 56 | - uses: actions-rs/toolchain@v1 57 | with: 58 | profile: minimal 59 | toolchain: 1.74.0 # MSRV 60 | components: clippy 61 | override: true 62 | - run: cargo clippy --all --all-features -- -D warnings 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | canister.toml 4 | -------------------------------------------------------------------------------- /.rpm/canister.spec: -------------------------------------------------------------------------------- 1 | # .rpm/canister.spec created via cargo-rpm: https://github.com/RustRPM/cargo-rpm 2 | 3 | %define __spec_install_post %{nil} 4 | %define __os_install_post %{_dbpath}/brp-compress 5 | %define debug_package %{nil} 6 | 7 | Name: canister 8 | Summary: Deploy binaries from Google Container Registry (gcr.io) 9 | Version: @@VERSION@@ 10 | Release: 1 11 | License: ASL 2.0 12 | Group: Applications/System 13 | Source0: %{name}-%{version}.tar.gz 14 | URL: https://github.com/iqlusioninc/canister 15 | 16 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root 17 | 18 | %description 19 | %{summary} 20 | 21 | %prep 22 | %setup -q 23 | 24 | %install 25 | rm -rf %{buildroot} 26 | mkdir -p %{buildroot} 27 | cp -a * %{buildroot} 28 | 29 | %clean 30 | rm -rf %{buildroot} 31 | 32 | %files 33 | %defattr(-,root,root,-) 34 | %{_bindir}/* -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | ## 0.1.0 (2018-12-08) 2 | 3 | * Update to [Rust 2018]. (#12) 4 | 5 | ## 0.0.4 (2018-11-27) 6 | 7 | * Proxy support 8 | 9 | ## 0.0.1 (2018-10-12) 10 | 11 | * Initial release 12 | 13 | [Rust 2018]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html 14 | 15 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "abscissa_core" 7 | version = "0.7.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8346a52bf3fb445d5949d144c37360ad2f1d7950cfcc6d4e9e4999b1cd1bd42a" 10 | dependencies = [ 11 | "abscissa_derive", 12 | "arc-swap", 13 | "backtrace", 14 | "canonical-path", 15 | "clap", 16 | "color-eyre", 17 | "fs-err", 18 | "once_cell", 19 | "regex", 20 | "secrecy", 21 | "semver 1.0.23", 22 | "serde", 23 | "termcolor", 24 | "toml", 25 | "tracing", 26 | "tracing-log 0.1.4", 27 | "tracing-subscriber", 28 | "wait-timeout", 29 | ] 30 | 31 | [[package]] 32 | name = "abscissa_derive" 33 | version = "0.7.0" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "55bfb86e57d13c06e482c570826ddcddcc8f07fab916760e8911141d4fda8b62" 36 | dependencies = [ 37 | "ident_case", 38 | "proc-macro2", 39 | "quote", 40 | "syn 1.0.109", 41 | "synstructure", 42 | ] 43 | 44 | [[package]] 45 | name = "addr2line" 46 | version = "0.21.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 49 | dependencies = [ 50 | "gimli", 51 | ] 52 | 53 | [[package]] 54 | name = "adler" 55 | version = "1.0.2" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 58 | 59 | [[package]] 60 | name = "adler2" 61 | version = "2.0.0" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 64 | 65 | [[package]] 66 | name = "adler32" 67 | version = "1.2.0" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" 70 | 71 | [[package]] 72 | name = "ahash" 73 | version = "0.8.11" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 76 | dependencies = [ 77 | "cfg-if 1.0.0", 78 | "once_cell", 79 | "version_check", 80 | "zerocopy", 81 | ] 82 | 83 | [[package]] 84 | name = "aho-corasick" 85 | version = "1.1.3" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 88 | dependencies = [ 89 | "memchr", 90 | ] 91 | 92 | [[package]] 93 | name = "allocator-api2" 94 | version = "0.2.18" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" 97 | 98 | [[package]] 99 | name = "anstream" 100 | version = "0.6.15" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" 103 | dependencies = [ 104 | "anstyle", 105 | "anstyle-parse", 106 | "anstyle-query", 107 | "anstyle-wincon", 108 | "colorchoice", 109 | "is_terminal_polyfill", 110 | "utf8parse", 111 | ] 112 | 113 | [[package]] 114 | name = "anstyle" 115 | version = "1.0.8" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 118 | 119 | [[package]] 120 | name = "anstyle-parse" 121 | version = "0.2.5" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" 124 | dependencies = [ 125 | "utf8parse", 126 | ] 127 | 128 | [[package]] 129 | name = "anstyle-query" 130 | version = "1.1.1" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" 133 | dependencies = [ 134 | "windows-sys 0.52.0", 135 | ] 136 | 137 | [[package]] 138 | name = "anstyle-wincon" 139 | version = "3.0.4" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" 142 | dependencies = [ 143 | "anstyle", 144 | "windows-sys 0.52.0", 145 | ] 146 | 147 | [[package]] 148 | name = "arc-swap" 149 | version = "1.7.1" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" 152 | 153 | [[package]] 154 | name = "autocfg" 155 | version = "0.1.8" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" 158 | dependencies = [ 159 | "autocfg 1.3.0", 160 | ] 161 | 162 | [[package]] 163 | name = "autocfg" 164 | version = "1.3.0" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 167 | 168 | [[package]] 169 | name = "backtrace" 170 | version = "0.3.71" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" 173 | dependencies = [ 174 | "addr2line", 175 | "cc", 176 | "cfg-if 1.0.0", 177 | "libc", 178 | "miniz_oxide 0.7.4", 179 | "object", 180 | "rustc-demangle", 181 | ] 182 | 183 | [[package]] 184 | name = "base64" 185 | version = "0.10.1" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 188 | dependencies = [ 189 | "byteorder", 190 | ] 191 | 192 | [[package]] 193 | name = "bitflags" 194 | version = "1.3.2" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 197 | 198 | [[package]] 199 | name = "bitflags" 200 | version = "2.6.0" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 203 | 204 | [[package]] 205 | name = "block-buffer" 206 | version = "0.10.4" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 209 | dependencies = [ 210 | "generic-array", 211 | ] 212 | 213 | [[package]] 214 | name = "byteorder" 215 | version = "1.5.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 218 | 219 | [[package]] 220 | name = "bytes" 221 | version = "0.4.12" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" 224 | dependencies = [ 225 | "byteorder", 226 | "either", 227 | "iovec", 228 | ] 229 | 230 | [[package]] 231 | name = "bytes" 232 | version = "1.7.1" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" 235 | 236 | [[package]] 237 | name = "canister" 238 | version = "0.3.0" 239 | dependencies = [ 240 | "abscissa_core", 241 | "clap", 242 | "hex", 243 | "hyper 1.4.1", 244 | "libflate", 245 | "log", 246 | "once_cell", 247 | "os_pipe", 248 | "percent-encoding 2.3.1", 249 | "reqwest", 250 | "serde", 251 | "serde_json", 252 | "sha2", 253 | "subtle-encoding", 254 | "tar", 255 | "thiserror", 256 | "walkdir", 257 | ] 258 | 259 | [[package]] 260 | name = "canonical-path" 261 | version = "2.0.2" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" 264 | 265 | [[package]] 266 | name = "cc" 267 | version = "1.1.19" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800" 270 | dependencies = [ 271 | "shlex", 272 | ] 273 | 274 | [[package]] 275 | name = "cfg-if" 276 | version = "0.1.10" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 279 | 280 | [[package]] 281 | name = "cfg-if" 282 | version = "1.0.0" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 285 | 286 | [[package]] 287 | name = "clap" 288 | version = "4.5.19" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615" 291 | dependencies = [ 292 | "clap_builder", 293 | "clap_derive", 294 | ] 295 | 296 | [[package]] 297 | name = "clap_builder" 298 | version = "4.5.19" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b" 301 | dependencies = [ 302 | "anstream", 303 | "anstyle", 304 | "clap_lex", 305 | "strsim", 306 | ] 307 | 308 | [[package]] 309 | name = "clap_derive" 310 | version = "4.5.18" 311 | source = "registry+https://github.com/rust-lang/crates.io-index" 312 | checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" 313 | dependencies = [ 314 | "heck", 315 | "proc-macro2", 316 | "quote", 317 | "syn 2.0.77", 318 | ] 319 | 320 | [[package]] 321 | name = "clap_lex" 322 | version = "0.7.2" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" 325 | 326 | [[package]] 327 | name = "cloudabi" 328 | version = "0.0.3" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 331 | dependencies = [ 332 | "bitflags 1.3.2", 333 | ] 334 | 335 | [[package]] 336 | name = "color-eyre" 337 | version = "0.6.3" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" 340 | dependencies = [ 341 | "backtrace", 342 | "eyre", 343 | "indenter", 344 | "once_cell", 345 | "owo-colors", 346 | ] 347 | 348 | [[package]] 349 | name = "colorchoice" 350 | version = "1.0.2" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" 353 | 354 | [[package]] 355 | name = "cookie" 356 | version = "0.12.0" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" 359 | dependencies = [ 360 | "time", 361 | "url 1.7.2", 362 | ] 363 | 364 | [[package]] 365 | name = "cookie_store" 366 | version = "0.7.0" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" 369 | dependencies = [ 370 | "cookie", 371 | "failure", 372 | "idna 0.1.5", 373 | "log", 374 | "publicsuffix", 375 | "serde", 376 | "serde_json", 377 | "time", 378 | "try_from", 379 | "url 1.7.2", 380 | ] 381 | 382 | [[package]] 383 | name = "core-foundation" 384 | version = "0.9.4" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 387 | dependencies = [ 388 | "core-foundation-sys", 389 | "libc", 390 | ] 391 | 392 | [[package]] 393 | name = "core-foundation-sys" 394 | version = "0.8.7" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 397 | 398 | [[package]] 399 | name = "core2" 400 | version = "0.4.0" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" 403 | dependencies = [ 404 | "memchr", 405 | ] 406 | 407 | [[package]] 408 | name = "cpufeatures" 409 | version = "0.2.14" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" 412 | dependencies = [ 413 | "libc", 414 | ] 415 | 416 | [[package]] 417 | name = "crc32fast" 418 | version = "1.4.2" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 421 | dependencies = [ 422 | "cfg-if 1.0.0", 423 | ] 424 | 425 | [[package]] 426 | name = "crossbeam-deque" 427 | version = "0.7.4" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" 430 | dependencies = [ 431 | "crossbeam-epoch", 432 | "crossbeam-utils", 433 | "maybe-uninit", 434 | ] 435 | 436 | [[package]] 437 | name = "crossbeam-epoch" 438 | version = "0.8.2" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 441 | dependencies = [ 442 | "autocfg 1.3.0", 443 | "cfg-if 0.1.10", 444 | "crossbeam-utils", 445 | "lazy_static", 446 | "maybe-uninit", 447 | "memoffset", 448 | "scopeguard", 449 | ] 450 | 451 | [[package]] 452 | name = "crossbeam-queue" 453 | version = "0.2.3" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" 456 | dependencies = [ 457 | "cfg-if 0.1.10", 458 | "crossbeam-utils", 459 | "maybe-uninit", 460 | ] 461 | 462 | [[package]] 463 | name = "crossbeam-utils" 464 | version = "0.7.2" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 467 | dependencies = [ 468 | "autocfg 1.3.0", 469 | "cfg-if 0.1.10", 470 | "lazy_static", 471 | ] 472 | 473 | [[package]] 474 | name = "crypto-common" 475 | version = "0.1.6" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 478 | dependencies = [ 479 | "generic-array", 480 | "typenum", 481 | ] 482 | 483 | [[package]] 484 | name = "dary_heap" 485 | version = "0.3.6" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" 488 | 489 | [[package]] 490 | name = "digest" 491 | version = "0.10.7" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 494 | dependencies = [ 495 | "block-buffer", 496 | "crypto-common", 497 | ] 498 | 499 | [[package]] 500 | name = "dtoa" 501 | version = "0.4.8" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" 504 | 505 | [[package]] 506 | name = "either" 507 | version = "1.13.0" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 510 | 511 | [[package]] 512 | name = "encoding_rs" 513 | version = "0.8.34" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" 516 | dependencies = [ 517 | "cfg-if 1.0.0", 518 | ] 519 | 520 | [[package]] 521 | name = "errno" 522 | version = "0.3.9" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 525 | dependencies = [ 526 | "libc", 527 | "windows-sys 0.52.0", 528 | ] 529 | 530 | [[package]] 531 | name = "eyre" 532 | version = "0.6.12" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" 535 | dependencies = [ 536 | "indenter", 537 | "once_cell", 538 | ] 539 | 540 | [[package]] 541 | name = "failure" 542 | version = "0.1.8" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" 545 | dependencies = [ 546 | "backtrace", 547 | "failure_derive", 548 | ] 549 | 550 | [[package]] 551 | name = "failure_derive" 552 | version = "0.1.8" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" 555 | dependencies = [ 556 | "proc-macro2", 557 | "quote", 558 | "syn 1.0.109", 559 | "synstructure", 560 | ] 561 | 562 | [[package]] 563 | name = "fastrand" 564 | version = "2.1.1" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" 567 | 568 | [[package]] 569 | name = "filetime" 570 | version = "0.2.25" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" 573 | dependencies = [ 574 | "cfg-if 1.0.0", 575 | "libc", 576 | "libredox", 577 | "windows-sys 0.59.0", 578 | ] 579 | 580 | [[package]] 581 | name = "flate2" 582 | version = "1.0.33" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" 585 | dependencies = [ 586 | "crc32fast", 587 | "miniz_oxide 0.8.0", 588 | ] 589 | 590 | [[package]] 591 | name = "fnv" 592 | version = "1.0.7" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 595 | 596 | [[package]] 597 | name = "foreign-types" 598 | version = "0.3.2" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 601 | dependencies = [ 602 | "foreign-types-shared", 603 | ] 604 | 605 | [[package]] 606 | name = "foreign-types-shared" 607 | version = "0.1.1" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 610 | 611 | [[package]] 612 | name = "form_urlencoded" 613 | version = "1.2.1" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 616 | dependencies = [ 617 | "percent-encoding 2.3.1", 618 | ] 619 | 620 | [[package]] 621 | name = "fs-err" 622 | version = "2.11.0" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" 625 | dependencies = [ 626 | "autocfg 1.3.0", 627 | ] 628 | 629 | [[package]] 630 | name = "fuchsia-cprng" 631 | version = "0.1.1" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 634 | 635 | [[package]] 636 | name = "fuchsia-zircon" 637 | version = "0.3.3" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 640 | dependencies = [ 641 | "bitflags 1.3.2", 642 | "fuchsia-zircon-sys", 643 | ] 644 | 645 | [[package]] 646 | name = "fuchsia-zircon-sys" 647 | version = "0.3.3" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 650 | 651 | [[package]] 652 | name = "futures" 653 | version = "0.1.31" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" 656 | 657 | [[package]] 658 | name = "futures-cpupool" 659 | version = "0.1.8" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" 662 | dependencies = [ 663 | "futures", 664 | "num_cpus", 665 | ] 666 | 667 | [[package]] 668 | name = "generic-array" 669 | version = "0.14.7" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 672 | dependencies = [ 673 | "typenum", 674 | "version_check", 675 | ] 676 | 677 | [[package]] 678 | name = "gimli" 679 | version = "0.28.1" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 682 | 683 | [[package]] 684 | name = "h2" 685 | version = "0.1.26" 686 | source = "registry+https://github.com/rust-lang/crates.io-index" 687 | checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" 688 | dependencies = [ 689 | "byteorder", 690 | "bytes 0.4.12", 691 | "fnv", 692 | "futures", 693 | "http 0.1.21", 694 | "indexmap", 695 | "log", 696 | "slab", 697 | "string", 698 | "tokio-io", 699 | ] 700 | 701 | [[package]] 702 | name = "hashbrown" 703 | version = "0.12.3" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 706 | 707 | [[package]] 708 | name = "hashbrown" 709 | version = "0.14.5" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 712 | dependencies = [ 713 | "ahash", 714 | "allocator-api2", 715 | ] 716 | 717 | [[package]] 718 | name = "heck" 719 | version = "0.5.0" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 722 | 723 | [[package]] 724 | name = "hermit-abi" 725 | version = "0.3.9" 726 | source = "registry+https://github.com/rust-lang/crates.io-index" 727 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 728 | 729 | [[package]] 730 | name = "hex" 731 | version = "0.4.3" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 734 | 735 | [[package]] 736 | name = "http" 737 | version = "0.1.21" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" 740 | dependencies = [ 741 | "bytes 0.4.12", 742 | "fnv", 743 | "itoa 0.4.8", 744 | ] 745 | 746 | [[package]] 747 | name = "http" 748 | version = "1.1.0" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 751 | dependencies = [ 752 | "bytes 1.7.1", 753 | "fnv", 754 | "itoa 1.0.11", 755 | ] 756 | 757 | [[package]] 758 | name = "http-body" 759 | version = "0.1.0" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" 762 | dependencies = [ 763 | "bytes 0.4.12", 764 | "futures", 765 | "http 0.1.21", 766 | "tokio-buf", 767 | ] 768 | 769 | [[package]] 770 | name = "http-body" 771 | version = "1.0.1" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 774 | dependencies = [ 775 | "bytes 1.7.1", 776 | "http 1.1.0", 777 | ] 778 | 779 | [[package]] 780 | name = "httparse" 781 | version = "1.9.4" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" 784 | 785 | [[package]] 786 | name = "hyper" 787 | version = "0.12.36" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "5c843caf6296fc1f93444735205af9ed4e109a539005abb2564ae1d6fad34c52" 790 | dependencies = [ 791 | "bytes 0.4.12", 792 | "futures", 793 | "futures-cpupool", 794 | "h2", 795 | "http 0.1.21", 796 | "http-body 0.1.0", 797 | "httparse", 798 | "iovec", 799 | "itoa 0.4.8", 800 | "log", 801 | "net2", 802 | "rustc_version", 803 | "time", 804 | "tokio 0.1.22", 805 | "tokio-buf", 806 | "tokio-executor", 807 | "tokio-io", 808 | "tokio-reactor", 809 | "tokio-tcp", 810 | "tokio-threadpool", 811 | "tokio-timer", 812 | "want", 813 | ] 814 | 815 | [[package]] 816 | name = "hyper" 817 | version = "1.4.1" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" 820 | dependencies = [ 821 | "bytes 1.7.1", 822 | "http 1.1.0", 823 | "http-body 1.0.1", 824 | "tokio 1.40.0", 825 | ] 826 | 827 | [[package]] 828 | name = "hyper-tls" 829 | version = "0.3.2" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" 832 | dependencies = [ 833 | "bytes 0.4.12", 834 | "futures", 835 | "hyper 0.12.36", 836 | "native-tls", 837 | "tokio-io", 838 | ] 839 | 840 | [[package]] 841 | name = "ident_case" 842 | version = "1.0.1" 843 | source = "registry+https://github.com/rust-lang/crates.io-index" 844 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 845 | 846 | [[package]] 847 | name = "idna" 848 | version = "0.1.5" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 851 | dependencies = [ 852 | "matches", 853 | "unicode-bidi", 854 | "unicode-normalization", 855 | ] 856 | 857 | [[package]] 858 | name = "idna" 859 | version = "0.2.3" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" 862 | dependencies = [ 863 | "matches", 864 | "unicode-bidi", 865 | "unicode-normalization", 866 | ] 867 | 868 | [[package]] 869 | name = "idna" 870 | version = "0.5.0" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 873 | dependencies = [ 874 | "unicode-bidi", 875 | "unicode-normalization", 876 | ] 877 | 878 | [[package]] 879 | name = "indenter" 880 | version = "0.3.3" 881 | source = "registry+https://github.com/rust-lang/crates.io-index" 882 | checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" 883 | 884 | [[package]] 885 | name = "indexmap" 886 | version = "1.9.3" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 889 | dependencies = [ 890 | "autocfg 1.3.0", 891 | "hashbrown 0.12.3", 892 | ] 893 | 894 | [[package]] 895 | name = "iovec" 896 | version = "0.1.4" 897 | source = "registry+https://github.com/rust-lang/crates.io-index" 898 | checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 899 | dependencies = [ 900 | "libc", 901 | ] 902 | 903 | [[package]] 904 | name = "is_terminal_polyfill" 905 | version = "1.70.1" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 908 | 909 | [[package]] 910 | name = "itoa" 911 | version = "0.4.8" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" 914 | 915 | [[package]] 916 | name = "itoa" 917 | version = "1.0.11" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 920 | 921 | [[package]] 922 | name = "kernel32-sys" 923 | version = "0.2.2" 924 | source = "registry+https://github.com/rust-lang/crates.io-index" 925 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 926 | dependencies = [ 927 | "winapi 0.2.8", 928 | "winapi-build", 929 | ] 930 | 931 | [[package]] 932 | name = "lazy_static" 933 | version = "1.5.0" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 936 | 937 | [[package]] 938 | name = "libc" 939 | version = "0.2.158" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" 942 | 943 | [[package]] 944 | name = "libflate" 945 | version = "2.1.0" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "45d9dfdc14ea4ef0900c1cddbc8dcd553fbaacd8a4a282cf4018ae9dd04fb21e" 948 | dependencies = [ 949 | "adler32", 950 | "core2", 951 | "crc32fast", 952 | "dary_heap", 953 | "libflate_lz77", 954 | ] 955 | 956 | [[package]] 957 | name = "libflate_lz77" 958 | version = "2.1.0" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "e6e0d73b369f386f1c44abd9c570d5318f55ccde816ff4b562fa452e5182863d" 961 | dependencies = [ 962 | "core2", 963 | "hashbrown 0.14.5", 964 | "rle-decode-fast", 965 | ] 966 | 967 | [[package]] 968 | name = "libredox" 969 | version = "0.1.3" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 972 | dependencies = [ 973 | "bitflags 2.6.0", 974 | "libc", 975 | "redox_syscall 0.5.4", 976 | ] 977 | 978 | [[package]] 979 | name = "linux-raw-sys" 980 | version = "0.4.14" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 983 | 984 | [[package]] 985 | name = "lock_api" 986 | version = "0.3.4" 987 | source = "registry+https://github.com/rust-lang/crates.io-index" 988 | checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" 989 | dependencies = [ 990 | "scopeguard", 991 | ] 992 | 993 | [[package]] 994 | name = "log" 995 | version = "0.4.22" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 998 | 999 | [[package]] 1000 | name = "matchers" 1001 | version = "0.1.0" 1002 | source = "registry+https://github.com/rust-lang/crates.io-index" 1003 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 1004 | dependencies = [ 1005 | "regex-automata 0.1.10", 1006 | ] 1007 | 1008 | [[package]] 1009 | name = "matches" 1010 | version = "0.1.10" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" 1013 | 1014 | [[package]] 1015 | name = "maybe-uninit" 1016 | version = "2.0.0" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 1019 | 1020 | [[package]] 1021 | name = "memchr" 1022 | version = "2.7.4" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1025 | 1026 | [[package]] 1027 | name = "memoffset" 1028 | version = "0.5.6" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" 1031 | dependencies = [ 1032 | "autocfg 1.3.0", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "mime" 1037 | version = "0.3.17" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1040 | 1041 | [[package]] 1042 | name = "mime_guess" 1043 | version = "2.0.5" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" 1046 | dependencies = [ 1047 | "mime", 1048 | "unicase", 1049 | ] 1050 | 1051 | [[package]] 1052 | name = "miniz_oxide" 1053 | version = "0.7.4" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" 1056 | dependencies = [ 1057 | "adler", 1058 | ] 1059 | 1060 | [[package]] 1061 | name = "miniz_oxide" 1062 | version = "0.8.0" 1063 | source = "registry+https://github.com/rust-lang/crates.io-index" 1064 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 1065 | dependencies = [ 1066 | "adler2", 1067 | ] 1068 | 1069 | [[package]] 1070 | name = "mio" 1071 | version = "0.6.23" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" 1074 | dependencies = [ 1075 | "cfg-if 0.1.10", 1076 | "fuchsia-zircon", 1077 | "fuchsia-zircon-sys", 1078 | "iovec", 1079 | "kernel32-sys", 1080 | "libc", 1081 | "log", 1082 | "miow", 1083 | "net2", 1084 | "slab", 1085 | "winapi 0.2.8", 1086 | ] 1087 | 1088 | [[package]] 1089 | name = "miow" 1090 | version = "0.2.2" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" 1093 | dependencies = [ 1094 | "kernel32-sys", 1095 | "net2", 1096 | "winapi 0.2.8", 1097 | "ws2_32-sys", 1098 | ] 1099 | 1100 | [[package]] 1101 | name = "native-tls" 1102 | version = "0.2.12" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" 1105 | dependencies = [ 1106 | "libc", 1107 | "log", 1108 | "openssl", 1109 | "openssl-probe", 1110 | "openssl-sys", 1111 | "schannel", 1112 | "security-framework", 1113 | "security-framework-sys", 1114 | "tempfile", 1115 | ] 1116 | 1117 | [[package]] 1118 | name = "net2" 1119 | version = "0.2.39" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" 1122 | dependencies = [ 1123 | "cfg-if 0.1.10", 1124 | "libc", 1125 | "winapi 0.3.9", 1126 | ] 1127 | 1128 | [[package]] 1129 | name = "nu-ansi-term" 1130 | version = "0.46.0" 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" 1132 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1133 | dependencies = [ 1134 | "overload", 1135 | "winapi 0.3.9", 1136 | ] 1137 | 1138 | [[package]] 1139 | name = "num_cpus" 1140 | version = "1.16.0" 1141 | source = "registry+https://github.com/rust-lang/crates.io-index" 1142 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 1143 | dependencies = [ 1144 | "hermit-abi", 1145 | "libc", 1146 | ] 1147 | 1148 | [[package]] 1149 | name = "object" 1150 | version = "0.32.2" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 1153 | dependencies = [ 1154 | "memchr", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "once_cell" 1159 | version = "1.20.1" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" 1162 | dependencies = [ 1163 | "portable-atomic", 1164 | ] 1165 | 1166 | [[package]] 1167 | name = "openssl" 1168 | version = "0.10.66" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" 1171 | dependencies = [ 1172 | "bitflags 2.6.0", 1173 | "cfg-if 1.0.0", 1174 | "foreign-types", 1175 | "libc", 1176 | "once_cell", 1177 | "openssl-macros", 1178 | "openssl-sys", 1179 | ] 1180 | 1181 | [[package]] 1182 | name = "openssl-macros" 1183 | version = "0.1.1" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1186 | dependencies = [ 1187 | "proc-macro2", 1188 | "quote", 1189 | "syn 2.0.77", 1190 | ] 1191 | 1192 | [[package]] 1193 | name = "openssl-probe" 1194 | version = "0.1.5" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1197 | 1198 | [[package]] 1199 | name = "openssl-sys" 1200 | version = "0.9.103" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" 1203 | dependencies = [ 1204 | "cc", 1205 | "libc", 1206 | "pkg-config", 1207 | "vcpkg", 1208 | ] 1209 | 1210 | [[package]] 1211 | name = "os_pipe" 1212 | version = "1.2.1" 1213 | source = "registry+https://github.com/rust-lang/crates.io-index" 1214 | checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" 1215 | dependencies = [ 1216 | "libc", 1217 | "windows-sys 0.59.0", 1218 | ] 1219 | 1220 | [[package]] 1221 | name = "overload" 1222 | version = "0.1.1" 1223 | source = "registry+https://github.com/rust-lang/crates.io-index" 1224 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1225 | 1226 | [[package]] 1227 | name = "owo-colors" 1228 | version = "3.5.0" 1229 | source = "registry+https://github.com/rust-lang/crates.io-index" 1230 | checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" 1231 | 1232 | [[package]] 1233 | name = "parking_lot" 1234 | version = "0.9.0" 1235 | source = "registry+https://github.com/rust-lang/crates.io-index" 1236 | checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" 1237 | dependencies = [ 1238 | "lock_api", 1239 | "parking_lot_core", 1240 | "rustc_version", 1241 | ] 1242 | 1243 | [[package]] 1244 | name = "parking_lot_core" 1245 | version = "0.6.3" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" 1248 | dependencies = [ 1249 | "cfg-if 0.1.10", 1250 | "cloudabi", 1251 | "libc", 1252 | "redox_syscall 0.1.57", 1253 | "rustc_version", 1254 | "smallvec 0.6.14", 1255 | "winapi 0.3.9", 1256 | ] 1257 | 1258 | [[package]] 1259 | name = "percent-encoding" 1260 | version = "1.0.1" 1261 | source = "registry+https://github.com/rust-lang/crates.io-index" 1262 | checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1263 | 1264 | [[package]] 1265 | name = "percent-encoding" 1266 | version = "2.3.1" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1269 | 1270 | [[package]] 1271 | name = "pin-project-lite" 1272 | version = "0.2.14" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 1275 | 1276 | [[package]] 1277 | name = "pkg-config" 1278 | version = "0.3.30" 1279 | source = "registry+https://github.com/rust-lang/crates.io-index" 1280 | checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" 1281 | 1282 | [[package]] 1283 | name = "portable-atomic" 1284 | version = "1.9.0" 1285 | source = "registry+https://github.com/rust-lang/crates.io-index" 1286 | checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" 1287 | 1288 | [[package]] 1289 | name = "proc-macro2" 1290 | version = "1.0.86" 1291 | source = "registry+https://github.com/rust-lang/crates.io-index" 1292 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" 1293 | dependencies = [ 1294 | "unicode-ident", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "publicsuffix" 1299 | version = "1.5.6" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "95b4ce31ff0a27d93c8de1849cf58162283752f065a90d508f1105fa6c9a213f" 1302 | dependencies = [ 1303 | "idna 0.2.3", 1304 | "url 2.5.2", 1305 | ] 1306 | 1307 | [[package]] 1308 | name = "quote" 1309 | version = "1.0.37" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 1312 | dependencies = [ 1313 | "proc-macro2", 1314 | ] 1315 | 1316 | [[package]] 1317 | name = "rand" 1318 | version = "0.6.5" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1321 | dependencies = [ 1322 | "autocfg 0.1.8", 1323 | "libc", 1324 | "rand_chacha", 1325 | "rand_core 0.4.2", 1326 | "rand_hc", 1327 | "rand_isaac", 1328 | "rand_jitter", 1329 | "rand_os", 1330 | "rand_pcg", 1331 | "rand_xorshift", 1332 | "winapi 0.3.9", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "rand_chacha" 1337 | version = "0.1.1" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1340 | dependencies = [ 1341 | "autocfg 0.1.8", 1342 | "rand_core 0.3.1", 1343 | ] 1344 | 1345 | [[package]] 1346 | name = "rand_core" 1347 | version = "0.3.1" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 1350 | dependencies = [ 1351 | "rand_core 0.4.2", 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "rand_core" 1356 | version = "0.4.2" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 1359 | 1360 | [[package]] 1361 | name = "rand_hc" 1362 | version = "0.1.0" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 1365 | dependencies = [ 1366 | "rand_core 0.3.1", 1367 | ] 1368 | 1369 | [[package]] 1370 | name = "rand_isaac" 1371 | version = "0.1.1" 1372 | source = "registry+https://github.com/rust-lang/crates.io-index" 1373 | checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 1374 | dependencies = [ 1375 | "rand_core 0.3.1", 1376 | ] 1377 | 1378 | [[package]] 1379 | name = "rand_jitter" 1380 | version = "0.1.4" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 1383 | dependencies = [ 1384 | "libc", 1385 | "rand_core 0.4.2", 1386 | "winapi 0.3.9", 1387 | ] 1388 | 1389 | [[package]] 1390 | name = "rand_os" 1391 | version = "0.1.3" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 1394 | dependencies = [ 1395 | "cloudabi", 1396 | "fuchsia-cprng", 1397 | "libc", 1398 | "rand_core 0.4.2", 1399 | "rdrand", 1400 | "winapi 0.3.9", 1401 | ] 1402 | 1403 | [[package]] 1404 | name = "rand_pcg" 1405 | version = "0.1.2" 1406 | source = "registry+https://github.com/rust-lang/crates.io-index" 1407 | checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 1408 | dependencies = [ 1409 | "autocfg 0.1.8", 1410 | "rand_core 0.4.2", 1411 | ] 1412 | 1413 | [[package]] 1414 | name = "rand_xorshift" 1415 | version = "0.1.1" 1416 | source = "registry+https://github.com/rust-lang/crates.io-index" 1417 | checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1418 | dependencies = [ 1419 | "rand_core 0.3.1", 1420 | ] 1421 | 1422 | [[package]] 1423 | name = "rdrand" 1424 | version = "0.4.0" 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" 1426 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1427 | dependencies = [ 1428 | "rand_core 0.3.1", 1429 | ] 1430 | 1431 | [[package]] 1432 | name = "redox_syscall" 1433 | version = "0.1.57" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" 1436 | 1437 | [[package]] 1438 | name = "redox_syscall" 1439 | version = "0.5.4" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" 1442 | dependencies = [ 1443 | "bitflags 2.6.0", 1444 | ] 1445 | 1446 | [[package]] 1447 | name = "regex" 1448 | version = "1.10.6" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" 1451 | dependencies = [ 1452 | "aho-corasick", 1453 | "memchr", 1454 | "regex-automata 0.4.7", 1455 | "regex-syntax 0.8.4", 1456 | ] 1457 | 1458 | [[package]] 1459 | name = "regex-automata" 1460 | version = "0.1.10" 1461 | source = "registry+https://github.com/rust-lang/crates.io-index" 1462 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1463 | dependencies = [ 1464 | "regex-syntax 0.6.29", 1465 | ] 1466 | 1467 | [[package]] 1468 | name = "regex-automata" 1469 | version = "0.4.7" 1470 | source = "registry+https://github.com/rust-lang/crates.io-index" 1471 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 1472 | dependencies = [ 1473 | "aho-corasick", 1474 | "memchr", 1475 | "regex-syntax 0.8.4", 1476 | ] 1477 | 1478 | [[package]] 1479 | name = "regex-syntax" 1480 | version = "0.6.29" 1481 | source = "registry+https://github.com/rust-lang/crates.io-index" 1482 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1483 | 1484 | [[package]] 1485 | name = "regex-syntax" 1486 | version = "0.8.4" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 1489 | 1490 | [[package]] 1491 | name = "reqwest" 1492 | version = "0.9.24" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" 1495 | dependencies = [ 1496 | "base64", 1497 | "bytes 0.4.12", 1498 | "cookie", 1499 | "cookie_store", 1500 | "encoding_rs", 1501 | "flate2", 1502 | "futures", 1503 | "http 0.1.21", 1504 | "hyper 0.12.36", 1505 | "hyper-tls", 1506 | "log", 1507 | "mime", 1508 | "mime_guess", 1509 | "native-tls", 1510 | "serde", 1511 | "serde_json", 1512 | "serde_urlencoded", 1513 | "time", 1514 | "tokio 0.1.22", 1515 | "tokio-executor", 1516 | "tokio-io", 1517 | "tokio-threadpool", 1518 | "tokio-timer", 1519 | "url 1.7.2", 1520 | "uuid", 1521 | "winreg", 1522 | ] 1523 | 1524 | [[package]] 1525 | name = "rle-decode-fast" 1526 | version = "1.0.3" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" 1529 | 1530 | [[package]] 1531 | name = "rustc-demangle" 1532 | version = "0.1.24" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1535 | 1536 | [[package]] 1537 | name = "rustc_version" 1538 | version = "0.2.3" 1539 | source = "registry+https://github.com/rust-lang/crates.io-index" 1540 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1541 | dependencies = [ 1542 | "semver 0.9.0", 1543 | ] 1544 | 1545 | [[package]] 1546 | name = "rustix" 1547 | version = "0.38.37" 1548 | source = "registry+https://github.com/rust-lang/crates.io-index" 1549 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 1550 | dependencies = [ 1551 | "bitflags 2.6.0", 1552 | "errno", 1553 | "libc", 1554 | "linux-raw-sys", 1555 | "windows-sys 0.52.0", 1556 | ] 1557 | 1558 | [[package]] 1559 | name = "ryu" 1560 | version = "1.0.18" 1561 | source = "registry+https://github.com/rust-lang/crates.io-index" 1562 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1563 | 1564 | [[package]] 1565 | name = "same-file" 1566 | version = "1.0.6" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1569 | dependencies = [ 1570 | "winapi-util", 1571 | ] 1572 | 1573 | [[package]] 1574 | name = "schannel" 1575 | version = "0.1.24" 1576 | source = "registry+https://github.com/rust-lang/crates.io-index" 1577 | checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" 1578 | dependencies = [ 1579 | "windows-sys 0.59.0", 1580 | ] 1581 | 1582 | [[package]] 1583 | name = "scopeguard" 1584 | version = "1.2.0" 1585 | source = "registry+https://github.com/rust-lang/crates.io-index" 1586 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1587 | 1588 | [[package]] 1589 | name = "secrecy" 1590 | version = "0.8.0" 1591 | source = "registry+https://github.com/rust-lang/crates.io-index" 1592 | checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" 1593 | dependencies = [ 1594 | "serde", 1595 | "zeroize", 1596 | ] 1597 | 1598 | [[package]] 1599 | name = "security-framework" 1600 | version = "2.11.1" 1601 | source = "registry+https://github.com/rust-lang/crates.io-index" 1602 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1603 | dependencies = [ 1604 | "bitflags 2.6.0", 1605 | "core-foundation", 1606 | "core-foundation-sys", 1607 | "libc", 1608 | "security-framework-sys", 1609 | ] 1610 | 1611 | [[package]] 1612 | name = "security-framework-sys" 1613 | version = "2.11.1" 1614 | source = "registry+https://github.com/rust-lang/crates.io-index" 1615 | checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" 1616 | dependencies = [ 1617 | "core-foundation-sys", 1618 | "libc", 1619 | ] 1620 | 1621 | [[package]] 1622 | name = "semver" 1623 | version = "0.9.0" 1624 | source = "registry+https://github.com/rust-lang/crates.io-index" 1625 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1626 | dependencies = [ 1627 | "semver-parser", 1628 | ] 1629 | 1630 | [[package]] 1631 | name = "semver" 1632 | version = "1.0.23" 1633 | source = "registry+https://github.com/rust-lang/crates.io-index" 1634 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 1635 | dependencies = [ 1636 | "serde", 1637 | ] 1638 | 1639 | [[package]] 1640 | name = "semver-parser" 1641 | version = "0.7.0" 1642 | source = "registry+https://github.com/rust-lang/crates.io-index" 1643 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1644 | 1645 | [[package]] 1646 | name = "serde" 1647 | version = "1.0.210" 1648 | source = "registry+https://github.com/rust-lang/crates.io-index" 1649 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 1650 | dependencies = [ 1651 | "serde_derive", 1652 | ] 1653 | 1654 | [[package]] 1655 | name = "serde_derive" 1656 | version = "1.0.210" 1657 | source = "registry+https://github.com/rust-lang/crates.io-index" 1658 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 1659 | dependencies = [ 1660 | "proc-macro2", 1661 | "quote", 1662 | "syn 2.0.77", 1663 | ] 1664 | 1665 | [[package]] 1666 | name = "serde_json" 1667 | version = "1.0.128" 1668 | source = "registry+https://github.com/rust-lang/crates.io-index" 1669 | checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" 1670 | dependencies = [ 1671 | "itoa 1.0.11", 1672 | "memchr", 1673 | "ryu", 1674 | "serde", 1675 | ] 1676 | 1677 | [[package]] 1678 | name = "serde_urlencoded" 1679 | version = "0.5.5" 1680 | source = "registry+https://github.com/rust-lang/crates.io-index" 1681 | checksum = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" 1682 | dependencies = [ 1683 | "dtoa", 1684 | "itoa 0.4.8", 1685 | "serde", 1686 | "url 1.7.2", 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "sha2" 1691 | version = "0.10.8" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1694 | dependencies = [ 1695 | "cfg-if 1.0.0", 1696 | "cpufeatures", 1697 | "digest", 1698 | ] 1699 | 1700 | [[package]] 1701 | name = "sharded-slab" 1702 | version = "0.1.7" 1703 | source = "registry+https://github.com/rust-lang/crates.io-index" 1704 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1705 | dependencies = [ 1706 | "lazy_static", 1707 | ] 1708 | 1709 | [[package]] 1710 | name = "shlex" 1711 | version = "1.3.0" 1712 | source = "registry+https://github.com/rust-lang/crates.io-index" 1713 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1714 | 1715 | [[package]] 1716 | name = "slab" 1717 | version = "0.4.9" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1720 | dependencies = [ 1721 | "autocfg 1.3.0", 1722 | ] 1723 | 1724 | [[package]] 1725 | name = "smallvec" 1726 | version = "0.6.14" 1727 | source = "registry+https://github.com/rust-lang/crates.io-index" 1728 | checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" 1729 | dependencies = [ 1730 | "maybe-uninit", 1731 | ] 1732 | 1733 | [[package]] 1734 | name = "smallvec" 1735 | version = "1.13.2" 1736 | source = "registry+https://github.com/rust-lang/crates.io-index" 1737 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1738 | 1739 | [[package]] 1740 | name = "string" 1741 | version = "0.2.1" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" 1744 | dependencies = [ 1745 | "bytes 0.4.12", 1746 | ] 1747 | 1748 | [[package]] 1749 | name = "strsim" 1750 | version = "0.11.1" 1751 | source = "registry+https://github.com/rust-lang/crates.io-index" 1752 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1753 | 1754 | [[package]] 1755 | name = "subtle-encoding" 1756 | version = "0.5.1" 1757 | source = "registry+https://github.com/rust-lang/crates.io-index" 1758 | checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" 1759 | dependencies = [ 1760 | "zeroize", 1761 | ] 1762 | 1763 | [[package]] 1764 | name = "syn" 1765 | version = "1.0.109" 1766 | source = "registry+https://github.com/rust-lang/crates.io-index" 1767 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1768 | dependencies = [ 1769 | "proc-macro2", 1770 | "quote", 1771 | "unicode-ident", 1772 | ] 1773 | 1774 | [[package]] 1775 | name = "syn" 1776 | version = "2.0.77" 1777 | source = "registry+https://github.com/rust-lang/crates.io-index" 1778 | checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" 1779 | dependencies = [ 1780 | "proc-macro2", 1781 | "quote", 1782 | "unicode-ident", 1783 | ] 1784 | 1785 | [[package]] 1786 | name = "synstructure" 1787 | version = "0.12.6" 1788 | source = "registry+https://github.com/rust-lang/crates.io-index" 1789 | checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" 1790 | dependencies = [ 1791 | "proc-macro2", 1792 | "quote", 1793 | "syn 1.0.109", 1794 | "unicode-xid", 1795 | ] 1796 | 1797 | [[package]] 1798 | name = "tar" 1799 | version = "0.4.42" 1800 | source = "registry+https://github.com/rust-lang/crates.io-index" 1801 | checksum = "4ff6c40d3aedb5e06b57c6f669ad17ab063dd1e63d977c6a88e7f4dfa4f04020" 1802 | dependencies = [ 1803 | "filetime", 1804 | "libc", 1805 | "xattr", 1806 | ] 1807 | 1808 | [[package]] 1809 | name = "tempfile" 1810 | version = "3.12.0" 1811 | source = "registry+https://github.com/rust-lang/crates.io-index" 1812 | checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" 1813 | dependencies = [ 1814 | "cfg-if 1.0.0", 1815 | "fastrand", 1816 | "once_cell", 1817 | "rustix", 1818 | "windows-sys 0.59.0", 1819 | ] 1820 | 1821 | [[package]] 1822 | name = "termcolor" 1823 | version = "1.4.1" 1824 | source = "registry+https://github.com/rust-lang/crates.io-index" 1825 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 1826 | dependencies = [ 1827 | "winapi-util", 1828 | ] 1829 | 1830 | [[package]] 1831 | name = "thiserror" 1832 | version = "1.0.64" 1833 | source = "registry+https://github.com/rust-lang/crates.io-index" 1834 | checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" 1835 | dependencies = [ 1836 | "thiserror-impl", 1837 | ] 1838 | 1839 | [[package]] 1840 | name = "thiserror-impl" 1841 | version = "1.0.64" 1842 | source = "registry+https://github.com/rust-lang/crates.io-index" 1843 | checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" 1844 | dependencies = [ 1845 | "proc-macro2", 1846 | "quote", 1847 | "syn 2.0.77", 1848 | ] 1849 | 1850 | [[package]] 1851 | name = "thread_local" 1852 | version = "1.1.8" 1853 | source = "registry+https://github.com/rust-lang/crates.io-index" 1854 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1855 | dependencies = [ 1856 | "cfg-if 1.0.0", 1857 | "once_cell", 1858 | ] 1859 | 1860 | [[package]] 1861 | name = "time" 1862 | version = "0.1.45" 1863 | source = "registry+https://github.com/rust-lang/crates.io-index" 1864 | checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" 1865 | dependencies = [ 1866 | "libc", 1867 | "wasi", 1868 | "winapi 0.3.9", 1869 | ] 1870 | 1871 | [[package]] 1872 | name = "tinyvec" 1873 | version = "1.8.0" 1874 | source = "registry+https://github.com/rust-lang/crates.io-index" 1875 | checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" 1876 | dependencies = [ 1877 | "tinyvec_macros", 1878 | ] 1879 | 1880 | [[package]] 1881 | name = "tinyvec_macros" 1882 | version = "0.1.1" 1883 | source = "registry+https://github.com/rust-lang/crates.io-index" 1884 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 1885 | 1886 | [[package]] 1887 | name = "tokio" 1888 | version = "0.1.22" 1889 | source = "registry+https://github.com/rust-lang/crates.io-index" 1890 | checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" 1891 | dependencies = [ 1892 | "bytes 0.4.12", 1893 | "futures", 1894 | "mio", 1895 | "num_cpus", 1896 | "tokio-current-thread", 1897 | "tokio-executor", 1898 | "tokio-io", 1899 | "tokio-reactor", 1900 | "tokio-tcp", 1901 | "tokio-threadpool", 1902 | "tokio-timer", 1903 | ] 1904 | 1905 | [[package]] 1906 | name = "tokio" 1907 | version = "1.40.0" 1908 | source = "registry+https://github.com/rust-lang/crates.io-index" 1909 | checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" 1910 | dependencies = [ 1911 | "backtrace", 1912 | "pin-project-lite", 1913 | ] 1914 | 1915 | [[package]] 1916 | name = "tokio-buf" 1917 | version = "0.1.1" 1918 | source = "registry+https://github.com/rust-lang/crates.io-index" 1919 | checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" 1920 | dependencies = [ 1921 | "bytes 0.4.12", 1922 | "either", 1923 | "futures", 1924 | ] 1925 | 1926 | [[package]] 1927 | name = "tokio-current-thread" 1928 | version = "0.1.7" 1929 | source = "registry+https://github.com/rust-lang/crates.io-index" 1930 | checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" 1931 | dependencies = [ 1932 | "futures", 1933 | "tokio-executor", 1934 | ] 1935 | 1936 | [[package]] 1937 | name = "tokio-executor" 1938 | version = "0.1.10" 1939 | source = "registry+https://github.com/rust-lang/crates.io-index" 1940 | checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" 1941 | dependencies = [ 1942 | "crossbeam-utils", 1943 | "futures", 1944 | ] 1945 | 1946 | [[package]] 1947 | name = "tokio-io" 1948 | version = "0.1.13" 1949 | source = "registry+https://github.com/rust-lang/crates.io-index" 1950 | checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" 1951 | dependencies = [ 1952 | "bytes 0.4.12", 1953 | "futures", 1954 | "log", 1955 | ] 1956 | 1957 | [[package]] 1958 | name = "tokio-reactor" 1959 | version = "0.1.12" 1960 | source = "registry+https://github.com/rust-lang/crates.io-index" 1961 | checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" 1962 | dependencies = [ 1963 | "crossbeam-utils", 1964 | "futures", 1965 | "lazy_static", 1966 | "log", 1967 | "mio", 1968 | "num_cpus", 1969 | "parking_lot", 1970 | "slab", 1971 | "tokio-executor", 1972 | "tokio-io", 1973 | "tokio-sync", 1974 | ] 1975 | 1976 | [[package]] 1977 | name = "tokio-sync" 1978 | version = "0.1.8" 1979 | source = "registry+https://github.com/rust-lang/crates.io-index" 1980 | checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" 1981 | dependencies = [ 1982 | "fnv", 1983 | "futures", 1984 | ] 1985 | 1986 | [[package]] 1987 | name = "tokio-tcp" 1988 | version = "0.1.4" 1989 | source = "registry+https://github.com/rust-lang/crates.io-index" 1990 | checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" 1991 | dependencies = [ 1992 | "bytes 0.4.12", 1993 | "futures", 1994 | "iovec", 1995 | "mio", 1996 | "tokio-io", 1997 | "tokio-reactor", 1998 | ] 1999 | 2000 | [[package]] 2001 | name = "tokio-threadpool" 2002 | version = "0.1.18" 2003 | source = "registry+https://github.com/rust-lang/crates.io-index" 2004 | checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" 2005 | dependencies = [ 2006 | "crossbeam-deque", 2007 | "crossbeam-queue", 2008 | "crossbeam-utils", 2009 | "futures", 2010 | "lazy_static", 2011 | "log", 2012 | "num_cpus", 2013 | "slab", 2014 | "tokio-executor", 2015 | ] 2016 | 2017 | [[package]] 2018 | name = "tokio-timer" 2019 | version = "0.2.13" 2020 | source = "registry+https://github.com/rust-lang/crates.io-index" 2021 | checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" 2022 | dependencies = [ 2023 | "crossbeam-utils", 2024 | "futures", 2025 | "slab", 2026 | "tokio-executor", 2027 | ] 2028 | 2029 | [[package]] 2030 | name = "toml" 2031 | version = "0.5.11" 2032 | source = "registry+https://github.com/rust-lang/crates.io-index" 2033 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 2034 | dependencies = [ 2035 | "serde", 2036 | ] 2037 | 2038 | [[package]] 2039 | name = "tracing" 2040 | version = "0.1.40" 2041 | source = "registry+https://github.com/rust-lang/crates.io-index" 2042 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 2043 | dependencies = [ 2044 | "pin-project-lite", 2045 | "tracing-attributes", 2046 | "tracing-core", 2047 | ] 2048 | 2049 | [[package]] 2050 | name = "tracing-attributes" 2051 | version = "0.1.27" 2052 | source = "registry+https://github.com/rust-lang/crates.io-index" 2053 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 2054 | dependencies = [ 2055 | "proc-macro2", 2056 | "quote", 2057 | "syn 2.0.77", 2058 | ] 2059 | 2060 | [[package]] 2061 | name = "tracing-core" 2062 | version = "0.1.32" 2063 | source = "registry+https://github.com/rust-lang/crates.io-index" 2064 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 2065 | dependencies = [ 2066 | "once_cell", 2067 | "valuable", 2068 | ] 2069 | 2070 | [[package]] 2071 | name = "tracing-log" 2072 | version = "0.1.4" 2073 | source = "registry+https://github.com/rust-lang/crates.io-index" 2074 | checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" 2075 | dependencies = [ 2076 | "log", 2077 | "once_cell", 2078 | "tracing-core", 2079 | ] 2080 | 2081 | [[package]] 2082 | name = "tracing-log" 2083 | version = "0.2.0" 2084 | source = "registry+https://github.com/rust-lang/crates.io-index" 2085 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 2086 | dependencies = [ 2087 | "log", 2088 | "once_cell", 2089 | "tracing-core", 2090 | ] 2091 | 2092 | [[package]] 2093 | name = "tracing-subscriber" 2094 | version = "0.3.18" 2095 | source = "registry+https://github.com/rust-lang/crates.io-index" 2096 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" 2097 | dependencies = [ 2098 | "matchers", 2099 | "nu-ansi-term", 2100 | "once_cell", 2101 | "regex", 2102 | "sharded-slab", 2103 | "smallvec 1.13.2", 2104 | "thread_local", 2105 | "tracing", 2106 | "tracing-core", 2107 | "tracing-log 0.2.0", 2108 | ] 2109 | 2110 | [[package]] 2111 | name = "try-lock" 2112 | version = "0.2.5" 2113 | source = "registry+https://github.com/rust-lang/crates.io-index" 2114 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2115 | 2116 | [[package]] 2117 | name = "try_from" 2118 | version = "0.3.2" 2119 | source = "registry+https://github.com/rust-lang/crates.io-index" 2120 | checksum = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" 2121 | dependencies = [ 2122 | "cfg-if 0.1.10", 2123 | ] 2124 | 2125 | [[package]] 2126 | name = "typenum" 2127 | version = "1.17.0" 2128 | source = "registry+https://github.com/rust-lang/crates.io-index" 2129 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2130 | 2131 | [[package]] 2132 | name = "unicase" 2133 | version = "2.7.0" 2134 | source = "registry+https://github.com/rust-lang/crates.io-index" 2135 | checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" 2136 | dependencies = [ 2137 | "version_check", 2138 | ] 2139 | 2140 | [[package]] 2141 | name = "unicode-bidi" 2142 | version = "0.3.15" 2143 | source = "registry+https://github.com/rust-lang/crates.io-index" 2144 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 2145 | 2146 | [[package]] 2147 | name = "unicode-ident" 2148 | version = "1.0.13" 2149 | source = "registry+https://github.com/rust-lang/crates.io-index" 2150 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 2151 | 2152 | [[package]] 2153 | name = "unicode-normalization" 2154 | version = "0.1.23" 2155 | source = "registry+https://github.com/rust-lang/crates.io-index" 2156 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 2157 | dependencies = [ 2158 | "tinyvec", 2159 | ] 2160 | 2161 | [[package]] 2162 | name = "unicode-xid" 2163 | version = "0.2.5" 2164 | source = "registry+https://github.com/rust-lang/crates.io-index" 2165 | checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" 2166 | 2167 | [[package]] 2168 | name = "url" 2169 | version = "1.7.2" 2170 | source = "registry+https://github.com/rust-lang/crates.io-index" 2171 | checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" 2172 | dependencies = [ 2173 | "idna 0.1.5", 2174 | "matches", 2175 | "percent-encoding 1.0.1", 2176 | ] 2177 | 2178 | [[package]] 2179 | name = "url" 2180 | version = "2.5.2" 2181 | source = "registry+https://github.com/rust-lang/crates.io-index" 2182 | checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" 2183 | dependencies = [ 2184 | "form_urlencoded", 2185 | "idna 0.5.0", 2186 | "percent-encoding 2.3.1", 2187 | ] 2188 | 2189 | [[package]] 2190 | name = "utf8parse" 2191 | version = "0.2.2" 2192 | source = "registry+https://github.com/rust-lang/crates.io-index" 2193 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2194 | 2195 | [[package]] 2196 | name = "uuid" 2197 | version = "0.7.4" 2198 | source = "registry+https://github.com/rust-lang/crates.io-index" 2199 | checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" 2200 | dependencies = [ 2201 | "rand", 2202 | ] 2203 | 2204 | [[package]] 2205 | name = "valuable" 2206 | version = "0.1.0" 2207 | source = "registry+https://github.com/rust-lang/crates.io-index" 2208 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 2209 | 2210 | [[package]] 2211 | name = "vcpkg" 2212 | version = "0.2.15" 2213 | source = "registry+https://github.com/rust-lang/crates.io-index" 2214 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 2215 | 2216 | [[package]] 2217 | name = "version_check" 2218 | version = "0.9.5" 2219 | source = "registry+https://github.com/rust-lang/crates.io-index" 2220 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2221 | 2222 | [[package]] 2223 | name = "wait-timeout" 2224 | version = "0.2.0" 2225 | source = "registry+https://github.com/rust-lang/crates.io-index" 2226 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" 2227 | dependencies = [ 2228 | "libc", 2229 | ] 2230 | 2231 | [[package]] 2232 | name = "walkdir" 2233 | version = "2.5.0" 2234 | source = "registry+https://github.com/rust-lang/crates.io-index" 2235 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 2236 | dependencies = [ 2237 | "same-file", 2238 | "winapi-util", 2239 | ] 2240 | 2241 | [[package]] 2242 | name = "want" 2243 | version = "0.2.0" 2244 | source = "registry+https://github.com/rust-lang/crates.io-index" 2245 | checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" 2246 | dependencies = [ 2247 | "futures", 2248 | "log", 2249 | "try-lock", 2250 | ] 2251 | 2252 | [[package]] 2253 | name = "wasi" 2254 | version = "0.10.0+wasi-snapshot-preview1" 2255 | source = "registry+https://github.com/rust-lang/crates.io-index" 2256 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 2257 | 2258 | [[package]] 2259 | name = "winapi" 2260 | version = "0.2.8" 2261 | source = "registry+https://github.com/rust-lang/crates.io-index" 2262 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 2263 | 2264 | [[package]] 2265 | name = "winapi" 2266 | version = "0.3.9" 2267 | source = "registry+https://github.com/rust-lang/crates.io-index" 2268 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2269 | dependencies = [ 2270 | "winapi-i686-pc-windows-gnu", 2271 | "winapi-x86_64-pc-windows-gnu", 2272 | ] 2273 | 2274 | [[package]] 2275 | name = "winapi-build" 2276 | version = "0.1.1" 2277 | source = "registry+https://github.com/rust-lang/crates.io-index" 2278 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 2279 | 2280 | [[package]] 2281 | name = "winapi-i686-pc-windows-gnu" 2282 | version = "0.4.0" 2283 | source = "registry+https://github.com/rust-lang/crates.io-index" 2284 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2285 | 2286 | [[package]] 2287 | name = "winapi-util" 2288 | version = "0.1.9" 2289 | source = "registry+https://github.com/rust-lang/crates.io-index" 2290 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 2291 | dependencies = [ 2292 | "windows-sys 0.59.0", 2293 | ] 2294 | 2295 | [[package]] 2296 | name = "winapi-x86_64-pc-windows-gnu" 2297 | version = "0.4.0" 2298 | source = "registry+https://github.com/rust-lang/crates.io-index" 2299 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2300 | 2301 | [[package]] 2302 | name = "windows-sys" 2303 | version = "0.52.0" 2304 | source = "registry+https://github.com/rust-lang/crates.io-index" 2305 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2306 | dependencies = [ 2307 | "windows-targets", 2308 | ] 2309 | 2310 | [[package]] 2311 | name = "windows-sys" 2312 | version = "0.59.0" 2313 | source = "registry+https://github.com/rust-lang/crates.io-index" 2314 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2315 | dependencies = [ 2316 | "windows-targets", 2317 | ] 2318 | 2319 | [[package]] 2320 | name = "windows-targets" 2321 | version = "0.52.6" 2322 | source = "registry+https://github.com/rust-lang/crates.io-index" 2323 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2324 | dependencies = [ 2325 | "windows_aarch64_gnullvm", 2326 | "windows_aarch64_msvc", 2327 | "windows_i686_gnu", 2328 | "windows_i686_gnullvm", 2329 | "windows_i686_msvc", 2330 | "windows_x86_64_gnu", 2331 | "windows_x86_64_gnullvm", 2332 | "windows_x86_64_msvc", 2333 | ] 2334 | 2335 | [[package]] 2336 | name = "windows_aarch64_gnullvm" 2337 | version = "0.52.6" 2338 | source = "registry+https://github.com/rust-lang/crates.io-index" 2339 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2340 | 2341 | [[package]] 2342 | name = "windows_aarch64_msvc" 2343 | version = "0.52.6" 2344 | source = "registry+https://github.com/rust-lang/crates.io-index" 2345 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2346 | 2347 | [[package]] 2348 | name = "windows_i686_gnu" 2349 | version = "0.52.6" 2350 | source = "registry+https://github.com/rust-lang/crates.io-index" 2351 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2352 | 2353 | [[package]] 2354 | name = "windows_i686_gnullvm" 2355 | version = "0.52.6" 2356 | source = "registry+https://github.com/rust-lang/crates.io-index" 2357 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2358 | 2359 | [[package]] 2360 | name = "windows_i686_msvc" 2361 | version = "0.52.6" 2362 | source = "registry+https://github.com/rust-lang/crates.io-index" 2363 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2364 | 2365 | [[package]] 2366 | name = "windows_x86_64_gnu" 2367 | version = "0.52.6" 2368 | source = "registry+https://github.com/rust-lang/crates.io-index" 2369 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2370 | 2371 | [[package]] 2372 | name = "windows_x86_64_gnullvm" 2373 | version = "0.52.6" 2374 | source = "registry+https://github.com/rust-lang/crates.io-index" 2375 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2376 | 2377 | [[package]] 2378 | name = "windows_x86_64_msvc" 2379 | version = "0.52.6" 2380 | source = "registry+https://github.com/rust-lang/crates.io-index" 2381 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2382 | 2383 | [[package]] 2384 | name = "winreg" 2385 | version = "0.6.2" 2386 | source = "registry+https://github.com/rust-lang/crates.io-index" 2387 | checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" 2388 | dependencies = [ 2389 | "winapi 0.3.9", 2390 | ] 2391 | 2392 | [[package]] 2393 | name = "ws2_32-sys" 2394 | version = "0.2.1" 2395 | source = "registry+https://github.com/rust-lang/crates.io-index" 2396 | checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 2397 | dependencies = [ 2398 | "winapi 0.2.8", 2399 | "winapi-build", 2400 | ] 2401 | 2402 | [[package]] 2403 | name = "xattr" 2404 | version = "1.3.1" 2405 | source = "registry+https://github.com/rust-lang/crates.io-index" 2406 | checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" 2407 | dependencies = [ 2408 | "libc", 2409 | "linux-raw-sys", 2410 | "rustix", 2411 | ] 2412 | 2413 | [[package]] 2414 | name = "zerocopy" 2415 | version = "0.7.35" 2416 | source = "registry+https://github.com/rust-lang/crates.io-index" 2417 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2418 | dependencies = [ 2419 | "zerocopy-derive", 2420 | ] 2421 | 2422 | [[package]] 2423 | name = "zerocopy-derive" 2424 | version = "0.7.35" 2425 | source = "registry+https://github.com/rust-lang/crates.io-index" 2426 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2427 | dependencies = [ 2428 | "proc-macro2", 2429 | "quote", 2430 | "syn 2.0.77", 2431 | ] 2432 | 2433 | [[package]] 2434 | name = "zeroize" 2435 | version = "1.8.1" 2436 | source = "registry+https://github.com/rust-lang/crates.io-index" 2437 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 2438 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "canister" 3 | edition = "2021" 4 | rust-version = "1.69" 5 | description = "Deploy binaries from Google Container Registry (gcr.io)" 6 | version = "0.3.0" 7 | authors = ["Tony Arcieri ", "Shella Stephens "] 8 | license = "Apache-2.0" 9 | homepage = "https://github.com/iqlusioninc/canister" 10 | readme = "README.md" 11 | categories = ["command-line-utilities"] 12 | keywords = ["container", "devops", "docker", "deployment", "systemd"] 13 | 14 | [dependencies] 15 | clap = "4" 16 | hex = "0.4" 17 | hyper = "1.4" 18 | percent-encoding = "2" 19 | libflate = "2.1" 20 | log = "0.4" 21 | os_pipe = "1.2" 22 | reqwest = "0.9" 23 | thiserror = "1" 24 | serde = { version = "1", features = ["serde_derive"] } 25 | serde_json = "1" 26 | subtle-encoding = "0.5" 27 | sha2 = "0.10" 28 | tar = "0.4" 29 | walkdir = "2" 30 | 31 | [package.metadata.rpm.cargo] 32 | buildflags = ["--release"] 33 | 34 | [package.metadata.rpm.targets] 35 | canister = { path = "/usr/bin/canister" } 36 | 37 | [dev-dependencies] 38 | once_cell = "1" 39 | 40 | [dependencies.abscissa_core] 41 | version = "0.7" 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # canister 🛢️ iqlusion 2 | 3 | Deploy self-contained binaries from [GCP Container Registry] (gcr.io) as systemd service units. 4 | 5 | Supported release artifact formats are tarballs and [Docker `scratch`]-based images (i.e. single-layer only) containing the compiled binaries, as fetched from a Docker registry (in the form of a tarball). Our (as in [@iqlusioninc]'s) internal use of this tool is primarily with a Docker scratch-based workflow using a Docker-based build system (namely [GCP Cloud Build]). 6 | 7 | [GCP Container Registry]: https://cloud.google.com/container-registry/ 8 | [Docker `scratch`]: https://hub.docker.com/_/scratch/ 9 | [@iqlusioninc]: https://github.com/iqlusioninc 10 | [GCP Cloud Build]: https://cloud.google.com/cloud-build/ 11 | 12 | ## Status 13 | 14 | Under active development. Currently **alpha** quality. 15 | 16 | ## License 17 | 18 | Copyright © 2018 iqlusion 19 | 20 | Licensed under the Apache License, Version 2.0 (the "License"); 21 | you may not use this file except in compliance with the License. 22 | You may obtain a copy of the License at 23 | 24 | https://www.apache.org/licenses/LICENSE-2.0 25 | 26 | Unless required by applicable law or agreed to in writing, software 27 | distributed under the License is distributed on an "AS IS" BASIS, 28 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 | See the License for the specific language governing permissions and 30 | limitations under the License. 31 | -------------------------------------------------------------------------------- /canister.toml.example: -------------------------------------------------------------------------------- 1 | project = "awesome-project" 2 | bucket = "production.appspot.com" 3 | image = "bin" 4 | tag = "latest" 5 | object = "containers/images" 6 | path = "/home/app" 7 | proxy = "https://example.com:8080" 8 | 9 | [run_command] 10 | path = "/home/app/awesome-project/current/awesome-bin" 11 | args = ["start"] 12 | 13 | [snapshot] 14 | bucket = "awesome-project-snapshots" 15 | path = "/home/app/awesome-project/data" 16 | tar_file = "/home/app/awesome-project-2019-06-25.tgz" 17 | -------------------------------------------------------------------------------- /src/application.rs: -------------------------------------------------------------------------------- 1 | //! Canister Abscissa Application 2 | 3 | use crate::{commands::CanisterCommand, config::CanisterConfig}; 4 | use abscissa_core::{ 5 | application, 6 | application::AppCell, 7 | config::{self, CfgCell}, 8 | trace, Application, FrameworkError, StandardPaths, 9 | }; 10 | 11 | /// Application state 12 | pub static APPLICATION: AppCell = AppCell::new(); 13 | 14 | /// Canister Application 15 | #[derive(Debug, Default)] 16 | pub struct CanisterApplication { 17 | /// Application configuration. 18 | config: CfgCell, 19 | 20 | /// Application state. 21 | state: application::State, 22 | } 23 | 24 | impl Application for CanisterApplication { 25 | /// Entrypoint command for this application. 26 | type Cmd = CanisterCommand; 27 | 28 | /// Application configuration. 29 | type Cfg = CanisterConfig; 30 | 31 | /// Paths to resources within the application. 32 | type Paths = StandardPaths; 33 | 34 | /// Accessor for application configuration. 35 | fn config(&self) -> config::Reader { 36 | self.config.read() 37 | } 38 | 39 | /// Borrow the application state immutably. 40 | fn state(&self) -> &application::State { 41 | &self.state 42 | } 43 | 44 | /// Register all components used by this application. 45 | /// 46 | /// If you would like to add additional components to your application 47 | /// beyond the default ones provided by the framework, this is the place 48 | /// to do so. 49 | fn register_components(&mut self, command: &Self::Cmd) -> Result<(), FrameworkError> { 50 | let components = self.framework_components(command)?; 51 | 52 | let mut component_registry = self.state.components_mut(); 53 | component_registry.register(components) 54 | } 55 | 56 | /// Post-configuration lifecycle callback. 57 | /// 58 | /// Called regardless of whether config is loaded to indicate this is the 59 | /// time in app lifecycle when configuration would be loaded if 60 | /// possible. 61 | fn after_config(&mut self, config: Self::Cfg) -> Result<(), FrameworkError> { 62 | let mut component_registry = self.state.components_mut(); 63 | component_registry.after_config(&config)?; 64 | self.config.set_once(config); 65 | Ok(()) 66 | } 67 | 68 | /// Get tracing configuration from command-line options 69 | fn tracing_config(&self, command: &CanisterCommand) -> trace::Config { 70 | if command.verbose() { 71 | trace::Config::verbose() 72 | } else { 73 | trace::Config::default() 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/commands/deploy.rs: -------------------------------------------------------------------------------- 1 | use crate::gcp::{Manifest, Storage, Token}; 2 | use crate::prelude::*; 3 | use crate::unpacker::{HexDigest, Unpacker}; 4 | use abscissa_core::{Command, Runnable}; 5 | use clap::Parser; 6 | use std::process; 7 | 8 | use std::fs; 9 | use std::io; 10 | use std::os::unix; 11 | 12 | #[derive(Command, Debug, Default, Parser)] 13 | pub struct DeployCommand { 14 | #[clap(short = 'c', long = "config")] 15 | pub config: Option, 16 | 17 | #[clap(short = 'v', long = "verbose")] 18 | pub verbose: bool, 19 | } 20 | 21 | impl Runnable for DeployCommand { 22 | #[allow(clippy::complexity)] 23 | fn run(&self) { 24 | let config = APPLICATION.config(); 25 | let project = &config.project; 26 | let bucket = &config.bucket; 27 | let image = &config.image; 28 | let tag = &config.tag; 29 | let object_path = &config.object; 30 | let path = &config.path; 31 | let proxy = config.proxy.as_deref(); 32 | let token = Token::from_gcloud_tool().unwrap_or_else(|e| { 33 | status_err!("Error, gcloud auth print-access-token cmd failed: {}", e); 34 | process::exit(1); 35 | }); 36 | 37 | let (image_id, m) = Manifest::get(&token, project, image, tag, proxy).unwrap_or_else(|e| { 38 | status_err!("Error, unable to fetch manifest: {}", e); 39 | process::exit(1); 40 | }); 41 | debug!("{}", image_id); 42 | let layers_len = m.layers.len(); 43 | debug!("{:?}", layers_len); 44 | if layers_len != 1 { 45 | panic!("layers length more than 1"); 46 | } 47 | let layer = &m.layers[0]; 48 | debug!("{:?}", layer); 49 | let layer_digest = HexDigest::new(&layer.digest[7..]); 50 | debug!("{:?}", &layer_digest); 51 | 52 | let object = format!("{}/sha256:{}", object_path, layer_digest.as_str()); 53 | let response = Storage::get(&token, bucket, &object, proxy).unwrap_or_else(|e| { 54 | status_err!("Error, unable to download object from bucket: {}", e); 55 | process::exit(1); 56 | }); 57 | let mut unpacker = Unpacker::new(response, config.path.join(image_id.to_string())); 58 | unpacker.unpack().unwrap_or_else(|e| { 59 | status_err!("Error, unable to unpack archive: {}", e); 60 | process::exit(1); 61 | }); 62 | let digest = unpacker.hex_digest(); 63 | debug!("digest: "); 64 | status_ok!("Downloaded", "{} object from {}", object, bucket); 65 | debug!("hasher result: {}", digest.as_str()); 66 | debug!("layer digest: {}", layer_digest.as_str()); 67 | assert_eq!(digest, layer_digest); 68 | let full_path = path.join(image_id.to_string()); 69 | let full_tag = path.join("current"); 70 | if let Err(e) = unix::fs::symlink(&full_path, &full_tag) { 71 | if e.kind() == io::ErrorKind::AlreadyExists { 72 | fs::remove_file(&full_tag).unwrap(); 73 | unix::fs::symlink(full_path, full_tag).unwrap(); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/commands/mod.rs: -------------------------------------------------------------------------------- 1 | use abscissa_core::{Command, Configurable, Runnable}; 2 | use clap::Parser; 3 | use std::path::PathBuf; 4 | 5 | mod deploy; 6 | mod run; 7 | mod version; 8 | 9 | pub use self::{deploy::DeployCommand, run::RunCommand, version::VersionCommand}; 10 | use crate::config::{CanisterConfig, CONFIG_FILE_NAME}; 11 | 12 | #[derive(Command, Debug, Parser, Runnable)] 13 | pub enum CanisterCommand { 14 | /// subcommands for Deploy 15 | Deploy(DeployCommand), 16 | 17 | /// subcommands for Run 18 | Run(RunCommand), 19 | } 20 | 21 | impl CanisterCommand { 22 | pub fn verbose(&self) -> bool { 23 | match self { 24 | CanisterCommand::Deploy(deploy) => deploy.verbose, 25 | CanisterCommand::Run(run) => run.verbose, 26 | } 27 | } 28 | } 29 | 30 | impl Configurable for CanisterCommand { 31 | fn config_path(&self) -> Option { 32 | match self { 33 | CanisterCommand::Deploy(deploy) => Some(PathBuf::from( 34 | deploy 35 | .config 36 | .as_ref() 37 | .map(|s| s.as_ref()) 38 | .unwrap_or(CONFIG_FILE_NAME), 39 | )), 40 | CanisterCommand::Run(run) => Some(PathBuf::from( 41 | run.config 42 | .as_ref() 43 | .map(|s| s.as_ref()) 44 | .unwrap_or(CONFIG_FILE_NAME), 45 | )), 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/commands/run.rs: -------------------------------------------------------------------------------- 1 | use crate::prelude::*; 2 | use abscissa_core::{Command, Runnable}; 3 | use clap::Parser; 4 | 5 | use super::DeployCommand; 6 | 7 | #[derive(Command, Debug, Default, Parser)] 8 | pub struct RunCommand { 9 | #[clap(short = 'c', long = "config")] 10 | pub config: Option, 11 | 12 | #[clap(short = 'v', long = "verbose")] 13 | pub verbose: bool, 14 | } 15 | 16 | impl Runnable for RunCommand { 17 | fn run(&self) { 18 | let config = APPLICATION.config(); 19 | let path = &config.run_command.path; 20 | let args = &config.run_command.args; 21 | 22 | DeployCommand { 23 | config: self.config.clone(), 24 | verbose: self.verbose, 25 | } 26 | .run(); 27 | 28 | let mut run_command = std::process::Command::new(path.clone()) 29 | .args(args) 30 | .spawn() 31 | .unwrap(); 32 | match run_command.wait() { 33 | Ok(exit_status) => match exit_status.code() { 34 | Some(0) => info!("successful exit status! cmd: {:?}", path), 35 | Some(code) => error!("error exit status! cmd: {:?}, code: {}", path, code), 36 | None => error!("Process terminated by unknown signal! cmd: {:?}", path), 37 | }, 38 | Err(e) => error!("error: {}, cmd: {:?}", e, path), 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/commands/version.rs: -------------------------------------------------------------------------------- 1 | //! The `version` subcommand 2 | //! 3 | #![allow(clippy::never_loop)] 4 | 5 | use abscissa_core::{Command, Runnable}; 6 | use clap::Parser; 7 | use std::{option_env, process}; 8 | 9 | /// The `version` subcommand 10 | #[derive(Command, Debug, Default, Parser)] 11 | pub struct VersionCommand {} 12 | 13 | impl Runnable for VersionCommand { 14 | /// Print version message 15 | fn run(&self) { 16 | println!("{}", option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")); 17 | process::exit(0); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/config/mod.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | use std::path::PathBuf; 3 | 4 | pub const CONFIG_FILE_NAME: &str = "canister.toml"; 5 | 6 | #[derive(Default, Deserialize, Debug)] 7 | pub struct CanisterConfig { 8 | pub project: String, 9 | pub bucket: String, 10 | pub image: String, 11 | pub tag: String, 12 | pub object: String, 13 | pub path: PathBuf, 14 | pub proxy: Option, 15 | pub run_command: RunCommandConfig, 16 | } 17 | 18 | #[derive(Default, Deserialize, Debug)] 19 | pub struct RunCommandConfig { 20 | pub path: PathBuf, 21 | pub args: Vec, 22 | } 23 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use abscissa_core::error::{BoxError, Context}; 2 | use std::fmt::{self, Display}; 3 | use std::ops::Deref; 4 | use std::{io, string::FromUtf8Error}; 5 | use thiserror::Error; 6 | 7 | /// Abscissa error type for canister 8 | pub struct Error(Box>); 9 | 10 | /// Types of errors which occur internally within canister 11 | #[derive(Copy, Clone, Debug, Eq, Error, PartialEq)] 12 | pub enum ErrorKind { 13 | /// I/O operation failed 14 | #[error("I/O operation failed")] 15 | IoError, 16 | 17 | /// Parse Error 18 | #[error("Parse error")] 19 | ParseError, 20 | 21 | /// Reqwest Error 22 | #[error("Reqwest error")] 23 | ReqwestError, 24 | 25 | /// Content Digest missing 26 | #[error("no content digest in response (access control issue?)")] 27 | ContentDigestMissing, 28 | } 29 | 30 | impl ErrorKind { 31 | /// Create an error context from this error 32 | pub fn context(self, source: impl Into) -> Context { 33 | Context::new(self, Some(source.into())) 34 | } 35 | } 36 | 37 | impl Deref for Error { 38 | type Target = Context; 39 | 40 | fn deref(&self) -> &Context { 41 | &self.0 42 | } 43 | } 44 | 45 | impl Display for Error { 46 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 47 | self.0.fmt(f) 48 | } 49 | } 50 | 51 | impl From> for Error { 52 | fn from(ctx: Context) -> Self { 53 | Error(Box::new(ctx)) 54 | } 55 | } 56 | 57 | impl From for Error { 58 | fn from(err: hyper::header::ToStrError) -> Self { 59 | ErrorKind::ParseError.context(err).into() 60 | } 61 | } 62 | 63 | impl From for Error { 64 | fn from(err: io::Error) -> Self { 65 | ErrorKind::IoError.context(err).into() 66 | } 67 | } 68 | 69 | impl From for Error { 70 | fn from(err: reqwest::Error) -> Self { 71 | ErrorKind::ReqwestError.context(err).into() 72 | } 73 | } 74 | 75 | impl From for Error { 76 | fn from(err: serde_json::Error) -> Self { 77 | ErrorKind::ParseError.context(err).into() 78 | } 79 | } 80 | 81 | impl From for Error { 82 | fn from(err: FromUtf8Error) -> Self { 83 | Error(ErrorKind::ParseError.context(err).into()) 84 | } 85 | } 86 | 87 | impl From for Error { 88 | fn from(err: reqwest::UrlError) -> Self { 89 | Error(ErrorKind::ParseError.context(err).into()) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/gcp/gcr.rs: -------------------------------------------------------------------------------- 1 | use super::oauth::{self, AuthHeader}; 2 | use crate::{ 3 | error::{Error, ErrorKind::*}, 4 | prelude::*, 5 | }; 6 | use reqwest::header::ACCEPT; 7 | use serde::{Deserialize, Serialize}; 8 | use sha2::{Digest, Sha256}; 9 | use std::fmt; 10 | 11 | #[derive(Serialize, Deserialize, Debug)] 12 | pub struct Manifest { 13 | #[serde(rename = "schemaVersion")] 14 | pub schema_version: usize, 15 | #[serde(rename = "mediaType")] 16 | pub media_type: String, 17 | pub config: Layer, 18 | pub layers: Vec, 19 | } 20 | 21 | #[derive(Serialize, Deserialize, Debug)] 22 | pub struct Layer { 23 | #[serde(rename = "mediaType")] 24 | pub media_type: String, 25 | pub size: usize, 26 | pub digest: String, 27 | } 28 | 29 | pub const SHA256_PREFIX: &str = "sha256:"; 30 | 31 | pub struct ImageId(String); 32 | 33 | impl fmt::Display for ImageId { 34 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 35 | self.0.fmt(f) 36 | } 37 | } 38 | 39 | impl Manifest { 40 | pub fn get( 41 | token: &oauth::Token, 42 | project: &str, 43 | image: &str, 44 | tag: &str, 45 | proxy: Option<&str>, 46 | ) -> Result<(ImageId, Self), Error> { 47 | let mut headers = token.headers(AuthHeader::Basic); 48 | headers.insert( 49 | ACCEPT, 50 | "application/vnd.docker.distribution.manifest.v2+json" 51 | .parse() 52 | .unwrap(), 53 | ); 54 | 55 | let client = match proxy { 56 | Some(p) => reqwest::Client::builder() 57 | .default_headers(headers) 58 | .proxy(reqwest::Proxy::all(p)?) 59 | .build(), 60 | None => reqwest::Client::builder().default_headers(headers).build(), 61 | }?; 62 | 63 | let url = format!("https://gcr.io/v2/{}/{}/manifests/{}", project, image, tag); 64 | 65 | let mut response = client.get(url.as_str()).send()?; 66 | 67 | let docker_digest_header = response 68 | .headers() 69 | .get("Docker-Content-Digest") 70 | .ok_or_else(|| Error::from(format_err!(ContentDigestMissing, "{}", url)))? 71 | .to_str() 72 | .unwrap() 73 | .to_owned(); 74 | 75 | if !docker_digest_header.starts_with(SHA256_PREFIX) { 76 | panic!("bad digest prefix: {:?}", docker_digest_header); 77 | } 78 | 79 | let docker_digest = &docker_digest_header[SHA256_PREFIX.len()..]; 80 | debug!("{:?}", docker_digest); 81 | debug!("response = {:?}", response); 82 | 83 | let body = response.text()?; 84 | debug!("body = {:?}", body); 85 | let image_id = ImageId(hex::encode(Sha256::digest(body.as_bytes()))); 86 | assert_eq!(image_id.0, *docker_digest); 87 | debug!("{}", image_id); 88 | 89 | let manifest = serde_json::from_str(&body)?; 90 | 91 | Ok((image_id, manifest)) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/gcp/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod gcr; 2 | mod oauth; 3 | mod storage; 4 | 5 | pub use self::gcr::Manifest; 6 | pub use self::oauth::Token; 7 | pub use self::storage::Storage; 8 | -------------------------------------------------------------------------------- /src/gcp/oauth.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Error; 2 | use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION}; 3 | use std::process::Command; 4 | use subtle_encoding::base64; 5 | 6 | pub struct Token { 7 | pub(super) token: String, 8 | } 9 | 10 | #[derive(Copy, Clone)] 11 | pub enum AuthHeader { 12 | Basic, 13 | Bearer, 14 | } 15 | 16 | impl AuthHeader { 17 | pub fn set(self, headers: &mut HeaderMap, token: &Token) { 18 | match self { 19 | AuthHeader::Bearer => { 20 | headers.insert( 21 | AUTHORIZATION, 22 | HeaderValue::from_str(&format!("Bearer {}", token.as_str())).unwrap(), 23 | ); 24 | } 25 | AuthHeader::Basic => { 26 | let password = token.as_str(); 27 | let auth = format!("oauth2accesstoken:{}", password); 28 | headers.insert( 29 | AUTHORIZATION, 30 | HeaderValue::from_str(&format!( 31 | "Basic {}", 32 | String::from_utf8(base64::encode(auth)).unwrap() 33 | )) 34 | .unwrap(), 35 | ); 36 | } 37 | } 38 | } 39 | } 40 | 41 | impl Token { 42 | pub fn from_gcloud_tool() -> Result { 43 | let cmd = Command::new("gcloud") 44 | .args(["auth", "print-access-token"]) 45 | .output() 46 | .expect("gcloud auth print-access-token cmd failed"); 47 | let mut token = String::from_utf8(cmd.stdout)?; 48 | let len = token.len(); 49 | token.truncate(len - 1); 50 | Ok(Self { token }) 51 | } 52 | 53 | pub fn as_str(&self) -> &str { 54 | &self.token 55 | } 56 | 57 | pub fn headers(&self, header_type: AuthHeader) -> HeaderMap { 58 | let mut headers = HeaderMap::new(); 59 | header_type.set(&mut headers, self); 60 | headers 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/gcp/storage.rs: -------------------------------------------------------------------------------- 1 | use super::oauth::{self, AuthHeader}; 2 | use crate::error::Error; 3 | use percent_encoding::{percent_encode, NON_ALPHANUMERIC}; 4 | use reqwest::header::{HeaderValue, CONTENT_TYPE}; 5 | use reqwest::Url; 6 | use std::fs::File; 7 | 8 | pub struct Storage { 9 | pub bucket: String, 10 | pub object: String, 11 | } 12 | 13 | impl Storage { 14 | // https://cloud.google.com/storage/docs/json_api/v1/objects/get 15 | pub fn get( 16 | token: &oauth::Token, 17 | bucket: &str, 18 | object: &str, 19 | proxy: Option<&str>, 20 | ) -> Result { 21 | let base = Url::parse("https://www.googleapis.com/storage/v1/b/")?; 22 | let mut url = base 23 | .join(&format!("{}/", bucket))? 24 | .join("o/")? 25 | .join(&percent_encode(object.as_bytes(), NON_ALPHANUMERIC).to_string())?; 26 | url.set_query(Some("alt=media")); 27 | let headers = token.headers(AuthHeader::Bearer); 28 | let storage_client = match proxy { 29 | Some(p) => reqwest::Client::builder() 30 | .default_headers(headers) 31 | .proxy(reqwest::Proxy::all(p)?) 32 | .build(), 33 | None => reqwest::Client::builder().default_headers(headers).build(), 34 | }?; 35 | let response = storage_client.get(url.as_str()).send()?; 36 | if !response.status().is_success() { 37 | panic!("{}", response.status()) 38 | } 39 | Ok(response) 40 | } 41 | 42 | // https://cloud.google.com/storage/docs/json_api/v1/objects/list 43 | pub fn list( 44 | token: &oauth::Token, 45 | bucket: &str, 46 | proxy: Option<&str>, 47 | ) -> Result { 48 | let base = Url::parse("https://www.googleapis.com/storage/v1/b/")?; 49 | let url = base.join(&format!("{}/", bucket))?.join("o/")?; 50 | let headers = token.headers(AuthHeader::Bearer); 51 | let storage_client = match proxy { 52 | Some(p) => reqwest::Client::builder() 53 | .default_headers(headers) 54 | .proxy(reqwest::Proxy::all(p)?) 55 | .build(), 56 | None => reqwest::Client::builder().default_headers(headers).build(), 57 | }?; 58 | let response = storage_client.get(url.as_str()).send()?; 59 | if !response.status().is_success() { 60 | panic!("{}", response.status()) 61 | } 62 | Ok(response) 63 | } 64 | 65 | // https://cloud.google.com/storage/docs/json_api/v1/objects/insert 66 | pub fn insert( 67 | token: &oauth::Token, 68 | bucket: &str, 69 | object: File, 70 | name: &str, 71 | proxy: Option<&str>, 72 | ) -> Result { 73 | let base = Url::parse("https://www.googleapis.com/upload/storage/v1/b/")?; 74 | let mut url = base.join(&format!("{}/", bucket))?.join("o")?; 75 | url.set_query(Some(&format!("uploadType=media&name={}", name))); 76 | 77 | let mut headers = token.headers(AuthHeader::Bearer); 78 | headers.insert( 79 | CONTENT_TYPE, 80 | HeaderValue::from_static("application/octet-stream"), 81 | ); 82 | 83 | let storage_client = match proxy { 84 | Some(p) => reqwest::Client::builder() 85 | .default_headers(headers) 86 | .proxy(reqwest::Proxy::all(p)?) 87 | .build(), 88 | None => reqwest::Client::builder().default_headers(headers).build(), 89 | }?; 90 | 91 | let response = storage_client.post(url.as_str()).body(object).send()?; 92 | if !response.status().is_success() { 93 | panic!("{}", response.status()) 94 | } 95 | Ok(response) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | //! Canister 2 | 3 | pub mod application; 4 | pub mod commands; 5 | pub mod config; 6 | pub mod error; 7 | pub mod gcp; 8 | pub mod packer; 9 | pub mod prelude; 10 | pub mod unpacker; 11 | 12 | use crate::application::APPLICATION; 13 | 14 | fn main() { 15 | abscissa_core::boot(&APPLICATION); 16 | } 17 | -------------------------------------------------------------------------------- /src/packer.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Error; 2 | use crate::prelude::*; 3 | use libflate::gzip::Encoder; 4 | use std::io::Write; 5 | use std::path::PathBuf; 6 | use walkdir::WalkDir; 7 | 8 | pub struct Packer { 9 | writer: W, 10 | path: PathBuf, 11 | } 12 | 13 | impl Packer { 14 | pub fn new(writer: W) -> Self { 15 | let config = APPLICATION.config(); 16 | let path = config.path.to_path_buf(); 17 | Self { writer, path } 18 | } 19 | 20 | pub fn pack(&mut self) -> Result<(), Error> { 21 | let mut encoder = Encoder::new(&mut self.writer).unwrap(); 22 | { 23 | let mut archive = tar::Builder::new(&mut encoder); 24 | for f in WalkDir::new(&self.path) { 25 | let f = f.unwrap(); 26 | if f.path().is_dir() { 27 | continue; 28 | } 29 | archive 30 | .append_path_with_name(f.path(), f.path().strip_prefix(&self.path).unwrap()) 31 | .unwrap(); 32 | } 33 | archive.finish().unwrap(); 34 | } 35 | encoder.finish().unwrap(); 36 | Ok(()) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/prelude.rs: -------------------------------------------------------------------------------- 1 | //! Application-local prelude: conveniently import types/functions/macros 2 | //! which are generally useful and should be available everywhere. 3 | 4 | /// Abscissa core prelude 5 | pub use abscissa_core::prelude::*; 6 | 7 | /// Application state 8 | pub use crate::application::APPLICATION; 9 | -------------------------------------------------------------------------------- /src/unpacker.rs: -------------------------------------------------------------------------------- 1 | use crate::error::Error; 2 | use libflate::gzip::Decoder; 3 | use sha2::{Digest, Sha256}; 4 | use std::io::{self, Read}; 5 | use std::path::PathBuf; 6 | 7 | pub struct Unpacker { 8 | hasher: Hasher, 9 | path: PathBuf, 10 | } 11 | 12 | impl Unpacker { 13 | pub fn new(reader: R, path: impl Into) -> Self { 14 | let hasher = Hasher::new(reader); 15 | Self { 16 | hasher, 17 | path: path.into(), 18 | } 19 | } 20 | 21 | pub fn unpack(&mut self) -> Result<(), Error> { 22 | let decoder = Decoder::new(&mut self.hasher).unwrap(); 23 | let mut archive = tar::Archive::new(decoder); 24 | archive.unpack(&self.path).unwrap(); 25 | Ok(()) 26 | } 27 | 28 | pub fn hex_digest(mut self) -> HexDigest { 29 | // drain remaining data in the tarball 30 | io::copy(&mut self.hasher, &mut io::sink()).unwrap(); 31 | self.hasher.hex_digest() 32 | } 33 | } 34 | 35 | struct Hasher { 36 | reader: R, 37 | digest: Sha256, 38 | } 39 | 40 | impl Hasher { 41 | pub fn new(reader: R) -> Self { 42 | Self { 43 | reader, 44 | digest: Sha256::default(), 45 | } 46 | } 47 | 48 | pub fn hex_digest(self) -> HexDigest { 49 | HexDigest(hex::encode(self.digest.finalize())) 50 | } 51 | } 52 | 53 | impl Read for Hasher { 54 | fn read(&mut self, buffer: &mut [u8]) -> io::Result { 55 | let nbytes = self.reader.read(buffer)?; 56 | self.digest.update(&buffer[..nbytes]); 57 | Ok(nbytes) 58 | } 59 | } 60 | 61 | #[derive(Clone, Debug, Eq, PartialEq)] 62 | pub struct HexDigest(pub String); 63 | 64 | impl HexDigest { 65 | pub fn new(digest: &str) -> HexDigest { 66 | HexDigest(digest.to_string()) 67 | } 68 | 69 | pub fn as_str(&self) -> &str { 70 | self.0.as_ref() 71 | } 72 | } 73 | --------------------------------------------------------------------------------