diff --git a/Cargo.lock b/Cargo.lock index a4be608f..b434637b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,11 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + [[package]] name = "aho-corasick" version = "0.7.13" @@ -15,13 +21,36 @@ version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b602bfe940d21c130f3895acd65221e8a61270debe89d628b9cb4e3ccb8569b" +[[package]] +name = "async-compression" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9021768bcce77296b64648cc7a7460e3df99979b97ed5c925c38d1cc83778d98" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + [[package]] name = "async-stream" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" dependencies = [ - "async-stream-impl", + "async-stream-impl 0.2.1", + "futures-core", +] + +[[package]] +name = "async-stream" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3670df70cbc01729f901f94c887814b3c68db038aad1329a418bae178bc5295c" +dependencies = [ + "async-stream-impl 0.3.0", "futures-core", ] @@ -36,6 +65,17 @@ dependencies = [ "syn", ] +[[package]] +name = "async-stream-impl" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3548b8efc9f8e8a5a0a2808c5bd8451a9031b9e5b879a79590304ae928b0a70" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-trait" version = "0.1.40" @@ -76,12 +116,57 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding", + "byte-tools", + "byteorder", + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "bumpalo" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + [[package]] name = "bytes" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" +[[package]] +name = "cc" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381" + [[package]] name = "cfg-if" version = "0.1.10" @@ -119,29 +204,121 @@ dependencies = [ "syn", ] +[[package]] +name = "cloudabi" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" +dependencies = [ + "bitflags", +] + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +dependencies = [ + "cfg-if", +] + [[package]] name = "cri" version = "0.1.0" dependencies = [ "anyhow", + "async-compression", + "async-stream 0.3.0", + "bytes", "clap", "env_logger", "futures-util", "getset", "log", + "oci-registry-client", "prost", "serde", + "sled", + "tempfile", + "thiserror", "tokio", + "tokio-tar", "tonic", "tonic-build", ] +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "dtoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" + [[package]] name = "either" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f" +[[package]] +name = "encoding_rs" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a51b8cf747471cb9499b6d59e59b0444f4c90eba8968c4e44874e92b5b64ace2" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_logger" version = "0.7.1" @@ -155,18 +332,73 @@ dependencies = [ "termcolor", ] +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "filetime" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "winapi 0.3.9", +] + [[package]] name = "fixedbitset" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" +[[package]] +name = "flate2" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "766d0e77a2c1502169d4a93ff3b8c15a71fd946cd0126309752104e5f3c46d94" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -241,6 +473,24 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +dependencies = [ + "typenum", +] + [[package]] name = "getrandom" version = "0.1.14" @@ -367,6 +617,30 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-tls" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-tls", +] + +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "1.6.0" @@ -377,6 +651,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "instant" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485" + [[package]] name = "iovec" version = "0.1.4" @@ -386,6 +666,12 @@ dependencies = [ "libc", ] +[[package]] +name = "ipnet" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" + [[package]] name = "itertools" version = "0.8.2" @@ -401,6 +687,15 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +[[package]] +name = "js-sys" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -423,6 +718,15 @@ version = "0.2.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" +[[package]] +name = "lock_api" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.11" @@ -433,12 +737,58 @@ dependencies = [ "serde", ] +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "memchr" version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "memoffset" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "mime_guess" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d7559a8a40d0f97e1edea3220f698f78b1c5ab67532e49f68fde3910323b722" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.6.22" @@ -487,6 +837,24 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1255076139a83bb467426e7f8d0134968a8118844faa755985e077cf31850333" +[[package]] +name = "native-tls" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "net2" version = "0.2.35" @@ -498,18 +866,97 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "oci-registry-client" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1d7c5ec6ecc1bb879e11ba01d824c9feb2bfcb0d4d678594a7e5b8e145390c" +dependencies = [ + "bytes", + "reqwest", + "serde", + "serde_json", + "sha2", + "tokio", +] + [[package]] name = "once_cell" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "openssl" +version = "0.10.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "lazy_static", + "libc", + "openssl-sys", +] + +[[package]] +name = "openssl-probe" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" + +[[package]] +name = "openssl-sys" +version = "0.9.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "os_str_bytes" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ac6fe3538f701e339953a3ebbe4f39941aababa8a3f6964635b24ab526daeac" +[[package]] +name = "parking_lot" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b" +dependencies = [ + "cfg-if", + "cloudabi", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -558,6 +1005,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" + [[package]] name = "ppv-lite86" version = "0.2.9" @@ -759,6 +1212,87 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "reqwest" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9eaa17ac5d7b838b7503d118fa16ad88f440498bf9ffe5424e621f93190d61e" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "mime_guess", + "native-tls", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-tls", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi 0.3.9", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "security-framework" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.115" @@ -779,12 +1313,69 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +dependencies = [ + "dtoa", + "itoa", + "serde", + "url", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + [[package]] name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +[[package]] +name = "sled" +version = "0.34.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbf56c35b0c3f9bc208fab35e45c3bc03137d3c1a4a85bdf0b8db69aecffb45" +dependencies = [ + "crc32fast", + "crossbeam-epoch", + "crossbeam-utils", + "fs2", + "fxhash", + "libc", + "log", + "parking_lot", +] + +[[package]] +name = "smallvec" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" + [[package]] name = "socket2" version = "0.3.12" @@ -857,6 +1448,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.0.1" @@ -877,6 +1488,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "tinyvec" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117" + [[package]] name = "tokio" version = "0.2.22" @@ -908,6 +1525,30 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-tar" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a9e415c93375be93253134543229563114a2be8d46440d6d8f25b2ec62a7fb" +dependencies = [ + "filetime", + "futures-core", + "libc", + "redox_syscall", + "tokio", + "xattr", +] + +[[package]] +name = "tokio-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.3.1" @@ -928,7 +1569,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74a5d6e7439ecf910463667080de772a9c7ddf26bc9fb4f3252ac3862e43337d" dependencies = [ - "async-stream", + "async-stream 0.2.1", "async-trait", "base64", "bytes", @@ -1190,6 +1831,39 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "typenum" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.6.0" @@ -1208,6 +1882,23 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "url" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" +dependencies = [ + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "vcpkg" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" + [[package]] name = "vec_map" version = "0.8.2" @@ -1242,6 +1933,84 @@ version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +[[package]] +name = "wasm-bindgen" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c" +dependencies = [ + "cfg-if", + "serde", + "serde_json", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092" + +[[package]] +name = "web-sys" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda38f4e5ca63eda02c059d243aa25b5f35ab98451e518c51612cd0f1bd19a47" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "which" version = "3.1.1" @@ -1294,6 +2063,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winreg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -1303,3 +2081,12 @@ dependencies = [ "winapi 0.2.8", "winapi-build", ] + +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] diff --git a/Cargo.toml b/Cargo.toml index 0eea0fa0..b8b90e3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ path = "src/main.rs" [dependencies] anyhow = "1.0.32" +thiserror = "1.0.20" clap = { git = "https://github.com/clap-rs/clap", features = ["wrap_help"] } env_logger = "0.7.1" futures-util = "0.3.5" @@ -28,8 +29,19 @@ getset = "0.1.1" log = { version = "0.4.11", features = ["serde", "std"] } prost = "0.6.1" serde = { version = "1.0.115", features = ["derive"] } -tokio = { version = "0.2.22", features = ["fs", "macros", "stream", "uds"] } +tokio = { version = "0.2.22", features = ["macros", "fs", "stream", "uds", "io-util", "rt-core", "rt-util"] } tonic = "0.3.1" +sled = "0.34.3" + +oci-registry-client = "0.1.3" + +tempfile = "3.1.0" + +bytes = "0.5.6" +async-compression = { version = "0.3.5", features = ["tokio-02", "gzip"] } +tokio-tar = "0.2.0" + +async-stream = "0.3.0" [build-dependencies] anyhow = "1.0.32" diff --git a/src/config.rs b/src/config.rs index c245d797..87856064 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,6 +3,7 @@ use clap::{AppSettings, Clap}; use getset::{CopyGetters, Getters}; use log::LevelFilter; use serde::{Deserialize, Serialize}; +use std::path::PathBuf; #[derive(Clap, CopyGetters, Getters, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] @@ -24,6 +25,10 @@ pub struct Config { /// The logging level of the application log_level: LevelFilter, + #[get = "pub"] + #[clap(default_value("/var/lib/cri"), env("CRI_DATA_DIR"), long("data-dir"))] + /// Directory to store CRI data + data_dir: PathBuf, #[get = "pub"] #[clap( default_value("/var/run/cri/cri.sock"), diff --git a/src/image_service.rs b/src/image_service.rs index 72cb6c26..e38dbd20 100644 --- a/src/image_service.rs +++ b/src/image_service.rs @@ -1,24 +1,195 @@ use crate::criapi::{self, image_service_server::ImageService}; -use std::collections::HashMap; +use crate::{criapi::ImageSpec, lock_map::LockMap}; +use anyhow::Result; +use async_compression::tokio_02::bufread::GzipDecoder; +use bytes::Bytes; +use oci_registry_client::{ + blob::Blob, manifest::Digest, manifest::Manifest, DockerRegistryClientV2, +}; +use prost::Message; +use std::path::{Path, PathBuf}; +use std::{collections::HashMap, sync::Arc}; +use tokio::{fs, io::stream_reader, stream::Stream, sync::Mutex}; +use tokio_tar::Archive; use tonic::{Request, Response, Status}; -#[derive(Default)] -pub struct MyImage {} +#[derive(thiserror::Error, Debug)] +pub enum ImageError { + #[error("image database error: {0}")] + DatabaseError(#[from] sled::Error), + #[error("decode error, database likely corrupted: {0}")] + DecodeError(#[from] prost::DecodeError), +} + +impl From for Status { + fn from(_: ImageError) -> Self { + todo!() + } +} + +pub struct MyImage { + database: sled::Db, + layers: PathBuf, + + layer_lock: LockMap, + + registries: Vec, + // TODO: prevent pulling same image simultaneously + // pull_progress: RwLock>>, +} + +/// Workaround for bad original API +/// Blob should implement AsyncRead itself +fn blob_to_stream( + mut blob: Blob, + out_digest: Arc>>, +) -> impl Stream> { + async_stream::try_stream! { + while let Some(bytes) = blob.chunk().await.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))? { + yield bytes; + } + out_digest.lock().await.replace(blob.digest()); + } +} + +impl MyImage { + /// Open directory as image storage + pub async fn open(image_storage: &Path) -> Result { + let mut db_path = image_storage.to_owned(); + db_path.push("images.db"); + let mut layers = image_storage.to_owned(); + layers.push("layers"); + fs::create_dir_all(&layers).await?; + Ok(MyImage { + database: sled::open(db_path)?, + layers, + registries: vec![DockerRegistryClientV2::new( + "registry.docker.io", + "https://registry-1.docker.io", + "https://auth.docker.io/token", + )], + + layer_lock: Default::default(), + }) + } + + /// List already pulled images + /// TODO: use passed spec + pub fn list_images(&self, _spec: Option<&ImageSpec>) -> Result, ImageError> { + use std::io::Cursor; + + let mut k = sled::IVec::default(); + let mut out = vec![]; + while let Some((ik, v)) = self.database.get_gt(&k)? { + k = ik.clone(); + out.push(criapi::Image::decode(&mut Cursor::new(&v))?); + } + Ok(out) + } + + pub async fn download_layer( + &self, + registry: &DockerRegistryClientV2, + image: &str, + digest: &Digest, + ) -> Result<()> { + let _lock = self.layer_lock.lock(digest.to_string()).await; + + let mut layer_dir = self.layers.clone(); + layer_dir.push(&digest.to_string()); + + let meta = fs::metadata(&layer_dir).await; + if meta.is_ok() && meta?.is_dir() { + return Ok(()); + } + + let tmp_layer_dir = tempfile::tempdir_in(&self.layers)?; + + let out_digest = Arc::new(Mutex::new(None)); + + let blob = registry.blob(image, digest).await?; + let blob_stream = blob_to_stream(blob, out_digest.clone()); + let blob_reader = stream_reader(blob_stream); + let deflate = Box::pin(GzipDecoder::new(blob_reader)); + let mut tar = Archive::new(deflate); + + tar.unpack(&tmp_layer_dir).await?; + + // TODO: return error instead of panic on digest mismatch + // assert_eq!(out_digest.as_ref().unwrap(), digest); + + fs::rename(tmp_layer_dir.into_path(), layer_dir).await?; + + Ok(()) + } + + pub async fn pull_image(&self, spec: &ImageSpec) -> Result> { + // TODO: handle registry name in image name (I.e docker.io/redis:latest) + let parts = spec.image.split(':').collect::>(); + assert_eq!(parts.len(), 2, "bad name format"); + let image_name = parts[0]; + let reference = parts[1]; + for registry in &self.registries { + let response = registry.auth("repository", image_name, "pull").await; + let mut registry = registry.clone(); + if let Ok(token) = response { + registry.set_auth_token(Some(token)); + } + + let manifests = match registry.list_manifests(image_name, reference).await { + Ok(m) => m, + // TODO: abort on error + Err(e) => { + println!("Error: {:?}", e); + continue; + } + }; + let mut found_manifest = None; + for manifest in manifests.manifests { + // TODO: check platform with passed annotations + let manifest = registry + .manifest(image_name, &manifest.digest.to_string()) + .await?; + found_manifest.replace(manifest); + } + let manifest = if let Some(m) = found_manifest { + m + } else { + return Ok(None); + }; + + // TODO: report progress in ImageStatusResponse info field + // TODO: download in parallel + for layer in manifest.layers { + self.download_layer(®istry, image_name, &layer.digest) + .await?; + } + } + Ok(None) + } +} #[tonic::async_trait] impl ImageService for MyImage { async fn list_images( &self, - _request: Request, + request: Request, ) -> Result, Status> { - let resp = criapi::ListImagesResponse { images: Vec::new() }; + let request = request.into_inner(); + let images = self.list_images(request.filter.as_ref().and_then(|f| f.image.as_ref()))?; + let resp = criapi::ListImagesResponse { images }; Ok(Response::new(resp)) } async fn pull_image( &self, - _request: Request, + request: Request, ) -> Result, Status> { + let request = request.into_inner(); + if let Some(spec) = request.image { + self.pull_image(&spec).await.expect("pull"); + } + let resp = criapi::PullImageResponse { image_ref: "some_image".into(), }; @@ -54,3 +225,41 @@ impl ImageService for MyImage { Ok(Response::new(resp)) } } + +#[cfg(test)] +pub mod tests { + use super::MyImage; + use crate::criapi::ImageSpec; + use anyhow::{Context, Result}; + + async fn create_tmp_image_service() -> Result<(tempfile::TempDir, MyImage)> { + let tempdir = tempfile::tempdir().context("tempdir")?; + let image_service = MyImage::open(tempdir.path()) + .await + .context("image service open")?; + Ok((tempdir, image_service)) + } + + #[tokio::test] + pub async fn list_images() -> Result<()> { + let (_tempdir, image_service) = create_tmp_image_service().await?; + + assert!(image_service.list_images(None)?.is_empty()); + + Ok(()) + } + + #[tokio::test] + pub async fn find_manifest() -> Result<()> { + let (_tempdir, image_service) = create_tmp_image_service().await?; + + image_service + .pull_image(&ImageSpec { + image: "library/redis:latest".into(), + ..Default::default() + }) + .await?; + + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index fa043638..2ca524fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ mod config; mod criapi; mod image_service; +mod lock_map; mod runtime_service; mod server; mod unix_stream; diff --git a/src/lock_map.rs b/src/lock_map.rs new file mode 100644 index 00000000..4f1c1f13 --- /dev/null +++ b/src/lock_map.rs @@ -0,0 +1,50 @@ +use std::{collections::HashMap, hash::Hash, sync::Arc}; + +use tokio::sync::{Mutex, OwnedMutexGuard, TryLockError}; + +#[derive(Default)] +pub struct LockMap { + inner: std::sync::Mutex>>>, +} + +pub struct LockMapGuard<'m, K: Hash + Eq> { + map: &'m LockMap, + key: K, + _guard: OwnedMutexGuard<()>, +} +impl Drop for LockMapGuard<'_, K> { + fn drop(&mut self) { + self.map + .inner + .lock() + .expect("lock map guard") + .remove(&self.key); + } +} + +impl LockMap { + fn mutex_by_key(&self, key: K) -> Arc> { + let mut map = self.inner.lock().expect("lock map guard"); + let mutex = map + .entry(key) + .or_insert_with(|| Arc::new(Mutex::new(()))) + .clone(); + mutex + } + pub async fn lock(&self, key: K) -> LockMapGuard<'_, K> { + let guard = self.mutex_by_key(key.clone()).lock_owned().await; + LockMapGuard { + map: self, + key, + _guard: guard, + } + } + pub fn try_lock(&self, key: K) -> Result, TryLockError> { + let guard = self.mutex_by_key(key.clone()).try_lock_owned()?; + Ok(LockMapGuard { + map: self, + key, + _guard: guard, + }) + } +} diff --git a/src/server.rs b/src/server.rs index a8942944..eab61e64 100644 --- a/src/server.rs +++ b/src/server.rs @@ -32,7 +32,7 @@ impl Server { .context("set logging verbosity")?; let rt = MyRuntime::default(); - let img = MyImage::default(); + let img = MyImage::open(&self.config.data_dir()).await?; let sock_path = Path::new(self.config.sock_path()); if !sock_path.is_absolute() {