diff --git a/src/injector/Cargo.lock b/src/injector/Cargo.lock index 4915654980..8388c6278a 100644 --- a/src/injector/Cargo.lock +++ b/src/injector/Cargo.lock @@ -17,6 +17,36 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + [[package]] name = "async-trait" version = "0.1.80" @@ -28,6 +58,12 @@ dependencies = [ "syn", ] +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + [[package]] name = "axum" version = "0.7.5" @@ -98,6 +134,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "1.3.2" @@ -119,6 +161,56 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bollard" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41711ad46fda47cd701f6908e59d1bd6b9a2b7464c0d0aeab95c6d37096ff8a" +dependencies = [ + "base64", + "bollard-stubs", + "bytes", + "futures-core", + "futures-util", + "hex", + "http", + "http-body-util", + "hyper", + "hyper-named-pipe", + "hyper-util", + "hyperlocal", + "log", + "pin-project-lite", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "serde_urlencoded", + "thiserror", + "tokio", + "tokio-util", + "tower-service", + "url", + "winapi", +] + +[[package]] +name = "bollard-stubs" +version = "1.45.0-rc.26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7c5415e3a6bc6d3e99eff6268e488fd4ee25e7b28c10f08fa6760bd9de16e4" +dependencies = [ + "serde", + "serde_repr", + "serde_with", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "bytes" version = "1.6.0" @@ -137,6 +229,25 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.12" @@ -165,6 +276,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "digest" version = "0.10.7" @@ -175,6 +296,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.8" @@ -182,7 +309,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -194,7 +321,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -237,6 +364,17 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.30" @@ -256,9 +394,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -283,6 +423,24 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hex" version = "0.4.3" @@ -337,9 +495,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", @@ -352,15 +510,32 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", +] + +[[package]] +name = "hyper-named-pipe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +dependencies = [ + "hex", + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", + "winapi", ] [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" dependencies = [ "bytes", + "futures-channel", "futures-util", "http", "http-body", @@ -368,6 +543,79 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "hyperlocal" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" +dependencies = [ + "hex", + "http-body-util", + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", + "serde", ] [[package]] @@ -376,6 +624,15 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "libc" version = "0.2.153" @@ -423,13 +680,29 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", ] [[package]] @@ -485,6 +758,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro2" version = "1.0.81" @@ -512,12 +791,41 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + [[package]] name = "regex-lite" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -534,7 +842,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -590,6 +898,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -602,6 +921,23 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.5.0", + "serde", + "serde_derive", + "serde_json", + "time", +] + [[package]] name = "sha2" version = "0.10.8" @@ -613,6 +949,15 @@ dependencies = [ "digest", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -626,7 +971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -663,26 +1008,99 @@ dependencies = [ "xattr", ] +[[package]] +name = "temp-dir" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f227968ec00f0e5322f9b8173c7a0cbcff6181a0a5b28e9892491c286277231" + +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" -version = "1.37.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", + "bytes", "libc", "mio", "pin-project-lite", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", @@ -700,6 +1118,7 @@ dependencies = [ "futures-sink", "pin-project-lite", "tokio", + "tracing", ] [[package]] @@ -750,24 +1169,65 @@ dependencies = [ "once_cell", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -775,36 +1235,98 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "windows-sys" -version = "0.48.0" +name = "wasm-bindgen" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ - "windows-targets 0.48.5", + "cfg-if", + "once_cell", + "wasm-bindgen-macro", ] [[package]] -name = "windows-sys" +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -813,46 +1335,28 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.5" @@ -865,48 +1369,24 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.5" @@ -928,14 +1408,19 @@ dependencies = [ name = "zarf-injector" version = "0.5.0" dependencies = [ + "anyhow", "axum", + "bollard", "flate2", + "futures-util", "glob", "hex", + "regex", "regex-lite", "serde_json", "sha2", "tar", + "temp-dir", "tokio", "tokio-util", ] diff --git a/src/injector/Cargo.toml b/src/injector/Cargo.toml index 050f6e314a..70957b1abb 100644 --- a/src/injector/Cargo.toml +++ b/src/injector/Cargo.toml @@ -10,7 +10,6 @@ panic = "abort" strip = true - [package] name = "zarf-injector" version = "0.5.0" @@ -23,9 +22,18 @@ glob = "0.3.1" flate2 = "1.0.28" tar = "0.4.40" sha2 = "0.10.8" -hex = {version = "0.4.3", default-features = false} -serde_json = { version = "1.0.113", default-features = false, features = ["alloc"] } -axum = {version = "0.7.5", features = ["tokio"]} +hex = { version = "0.4.3", default-features = false } +serde_json = { version = "1.0.113", default-features = false, features = [ + "alloc", +] } +axum = { version = "0.7.5", features = ["tokio"] } tokio = { version = "1.35.0", features = ["fs", "rt"] } -tokio-util = { version = "0.7.10", features = ["io"]} +tokio-util = { version = "0.7.10", features = ["io"] } regex-lite = "0.1.5" + +[dev-dependencies] +anyhow = "1.0.86" +bollard = "0.17.1" +futures-util = "0.3.30" +regex = "1.10.6" +temp-dir = "0.1.13" diff --git a/src/injector/src/main.rs b/src/injector/src/main.rs index e1b9cc3dc5..623884dc96 100644 --- a/src/injector/src/main.rs +++ b/src/injector/src/main.rs @@ -62,8 +62,14 @@ fn collect_binary_data(paths: &Vec) -> io::Result> { /// /// Inspired by https://medium.com/@nlauchande/rust-coding-up-a-simple-concatenate-files-tool-and-first-impressions-a8cbe680e887 fn unpack(sha_sum: &String) { + let init_root = + std::env::var("ZARF_INJECTOR_INIT_ROOT").unwrap_or_else(|_| String::from("/zarf-init")); + let seed_root = + std::env::var("ZARF_INJECTOR_SEED_ROOT").unwrap_or_else(|_| String::from("/zarf-seed")); + // get the list of file matches to merge - let file_partials: Result, _> = glob("zarf-payload-*") + let glob_path = format!("{}/zarf-payload-*", init_root); + let file_partials: Result, _> = glob(&glob_path) .expect("Failed to read glob pattern") .collect(); @@ -90,7 +96,7 @@ fn unpack(sha_sum: &String) { let tar = GzDecoder::new(&contents[..]); let mut archive = Archive::new(tar); archive - .unpack("/zarf-seed") + .unpack(seed_root) .expect("Unable to unarchive the resulting tarball"); } @@ -158,8 +164,11 @@ async fn handler(Path(path): Path) -> Response { /// Handles the GET request for the manifest (only returns a OCI manifest regardless of Accept header) async fn handle_get_manifest(name: String, reference: String) -> Response { - let index = fs::read_to_string(PathBuf::from("/zarf-seed").join("index.json")) - .expect("index.json is read"); + let root = PathBuf::from( + std::env::var("ZARF_INJECTOR_SEED_ROOT").unwrap_or_else(|_| String::from("/zarf-seed")), + ); + + let index = fs::read_to_string(root.join("index.json")).expect("index.json is read"); let json: Value = serde_json::from_str(&index).expect("unable to parse index.json"); let mut sha_manifest: String = "".to_owned(); @@ -189,11 +198,7 @@ async fn handle_get_manifest(name: String, reference: String) -> Response { .unwrap() .into_response() } else { - let file_path = PathBuf::from("/zarf-seed") - .to_owned() - .join("blobs") - .join("sha256") - .join(&sha_manifest); + let file_path = root.join("blobs").join("sha256").join(&sha_manifest); match tokio::fs::File::open(&file_path).await { Ok(file) => { let metadata = match file.metadata().await { @@ -230,7 +235,10 @@ async fn handle_get_manifest(name: String, reference: String) -> Response { /// Handles the GET request for a blob async fn handle_get_digest(tag: String) -> Response { - let blob_root = PathBuf::from("/zarf-seed").join("blobs").join("sha256"); + let root = PathBuf::from( + std::env::var("ZARF_INJECTOR_SEED_ROOT").unwrap_or_else(|_| String::from("/zarf-seed")), + ); + let blob_root = root.join("blobs").join("sha256"); let path = blob_root.join(tag.strip_prefix("sha256:").unwrap()); match tokio::fs::File::open(&path).await { @@ -268,3 +276,299 @@ async fn main() { axum::serve(listener, start_seed_registry()).await.unwrap(); println!("Usage: {} ", args[1]); } + +#[cfg(test)] +mod test { + use anyhow::{bail, Context as _, Ok, Result}; + use bollard::{image::CreateImageOptions, Docker}; + use flate2::{write::GzEncoder, Compression}; + use futures_util::{future::ready, TryStreamExt}; + use sha2::{Digest, Sha256}; + use std::{ + fs::File, + io::{BufRead, BufReader, Cursor, Seek, Write}, + path::{Path, PathBuf}, + }; + use temp_dir::TempDir; + + use crate::{start_seed_registry, unpack}; + + // TODO: Make this configurable? + const TEST_IMAGE: &str = "ghcr.io/zarf-dev/doom-game:0.0.1"; + // Split gzip into 1024 * 768 kb chunks + const CHUNK_SIZE: usize = 1024 * 768; + const ZARF_PAYLOAD_PREFIX: &str = "zarf-payload"; + // Based on upstream rust-oci-client regex: + // https://github.com/oras-project/rust-oci-client/blob/657c1caf9e99ce2184a96aa319fde4f4a8c09439/src/regexp.rs#L3-L5 + const REFERENCE_REGEXP: &str = r"^((?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])(?:(?:\.(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]))+)?(?::[0-9]+)?/)?[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?(?:(?:/[a-z0-9]+(?:(?:(?:[._]|__|[-]*)[a-z0-9]+)+)?)+)?)(?::([\w][\w.-]{0,127}))?(?:@([A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}))?$"; + + #[tokio::test] + async fn test_integration() { + let docker = Docker::connect_with_socket_defaults() + .expect("should have been able to create a Docker client"); + let tmpdir = TempDir::new().expect("should have created a temporary directory"); + + let env = TestEnv::new(docker.clone(), TEST_IMAGE, tmpdir.path().to_owned()) + .await + .expect("should have setup the test environment"); + + let output_root = env.output_dir(); + std::env::set_var("ZARF_INJECTOR_INIT_ROOT", env.input_dir()); + std::env::set_var("ZARF_INJECTOR_SEED_ROOT", &output_root); + unpack(&env.shasum()); + + // Assert the files and directory we expect to exist do exist + assert!(Path::new(&output_root.join("index.json")).exists()); + assert!(Path::new(&output_root.join("manifest.json")).exists()); + assert!(Path::new(&output_root.join("oci-layout")).exists()); + assert!(Path::new(&output_root.join("repositories")).exists()); + // TODO: Assert all of the blobs referenced in index.json and manifest.json exist under blobs/sha256/... + + localize_test_image(TEST_IMAGE, &output_root) + .expect("should have localized the test image's index.json"); + + // Use :0 to let the operating system decide the random port to listen on + let listener = tokio::net::TcpListener::bind("127.0.0.1:0") + .await + .expect("should have been able to bind listener to a random port on localhost"); + let random_port = listener + .local_addr() + .expect("should have been able to resolve the address") + .port(); + + // Start registry in the background + tokio::spawn(async { + let app = start_seed_registry(); + axum::serve(listener, app) + .await + .expect("should have been able to start serving the registry"); + }); + + let test_image = TEST_IMAGE.replace("ghcr.io", &format!("127.0.0.1:{random_port}")); + let options = Some(CreateImageOptions { + from_image: test_image.clone(), + ..Default::default() + }); + + let test_image_pull = docker + .create_image(options, None, None) + .try_collect::>() + .await; + assert!(test_image_pull.is_ok()); + docker + .remove_image(&test_image, None, None) + .await + .expect("should have cleaned up the pulled test image"); + } + + // This localizes the test image's index.json such that the registry server + // will be able to match the test image from it + fn localize_test_image(image_reference: &str, image_root: &Path) -> Result<()> { + let reference = normalize_manifest_reference(image_reference) + .context("should have localized the test image reference")?; + + let mut index_file = File::options() + .read(true) + .write(true) + .open(image_root.join("index.json")) + .context("should have opened index.json")?; + + let mut index_json: serde_json::Value = + serde_json::from_reader(index_file.try_clone().unwrap()) + .context("should have read index.json")?; + + // Overwrite or add an annotation for "org.opencontainers.image.base.name" + // that is normalized to be without registry address so that it can be + // pulled locally + index_json + .get_mut("manifests") + .and_then(|manifests| manifests.get_mut(0)) + .and_then(|array| array.get_mut("annotations")) + .and_then(|annotations| annotations.as_object_mut()) + .and_then(|annotations| { + annotations.insert( + "org.opencontainers.image.base.name".into(), + reference.into(), + ) + }); + + // Rewind index.json so serde overwrites from beginning of the file instead of appending to the end + index_file.rewind().unwrap(); + serde_json::to_writer(index_file.try_clone().unwrap(), &index_json) + .context("should have overwrote index.json")?; + Ok(()) + } + + // "Normalizes" the image reference by removing the registry component from it, + // so that it can be used for referring to local images. + fn normalize_manifest_reference(identifier: &str) -> Result { + let re = regex::Regex::new(REFERENCE_REGEXP)?; + let caps = re + .captures(identifier) + .context("should have matched captures for extracting reference components")?; + let repository = &caps[1]; + let tag = caps.get(2).map(|m| m.as_str().to_owned()); + let digest = caps.get(3).map(|m| m.as_str().to_owned()); + let reference = match (tag, digest) { + (None, None) => "latest".into(), + (None, Some(dgst)) => dgst, + (Some(tg), None) => tg, + // This should never happen, but for the sake of satisfying the borrow checker we need it here. + _ => { + bail!("both tag and digest were matched by the regex, that should not be possible") + } + }; + let name = extract_name(repository); + Ok(format!("{name}:{reference}")) + } + + // Based on rust-oci-client's split_domain: + // https://github.com/oras-project/rust-oci-client/blob/657c1caf9e99ce2184a96aa319fde4f4a8c09439/src/reference.rs#L297-L330 + fn extract_name(name: &str) -> String { + let mut domain: String; + let mut remainder: String; + + match name.split_once('/') { + None => { + domain = "docker.io".into(); + remainder = name.into(); + } + Some((left, right)) => { + if !(left.contains('.') || left.contains(':')) && left != "localhost" { + domain = "docker.io".into(); + remainder = name.into(); + } else { + domain = left.into(); + remainder = right.into(); + } + } + } + if domain == "index.docker.io" { + domain = "docker.io".into(); + } + if domain == "docker.io" && !remainder.contains('/') { + remainder = format!("{}/{}", "library", remainder); + } + + remainder + } + + struct TestEnv { + digest: String, + input_dir: PathBuf, + output_dir: PathBuf, + } + + impl TestEnv { + async fn new(client: Docker, image: &str, root: PathBuf) -> Result { + // Ensure we have test directories set up + let input_dir = root.join("zarf-init"); + let output_dir = root.join("zarf-seed"); + std::fs::create_dir(&input_dir).context("should have created test input directory")?; + std::fs::create_dir(&output_dir) + .context("should have created test output directory")?; + + // Download test image + Self::ensure_image_exists_locally(&client, image) + .await + .context("should have pulled down the test image")?; + + // Export test image from docker into a stream to iterate over + let image_stream = client.export_image(image).map_err(anyhow::Error::msg); + + // Create an in-memory seekable buffer reading in the image and + // for iteration later when creating the zarf-payload-* chunks + let buffer = Cursor::new(Vec::new()); + + // Encode test image as gzip into the buffer + let mut gz = GzEncoder::new(buffer, Compression::default()); + image_stream + .try_for_each(|data| { + // We map the error to make sure we're propagating the + // same type of error across the board + let res = gz.write_all(&data).map_err(anyhow::Error::msg); + // Ready needs to be called for the stream to do its thing + ready(res) + }) + .await?; + + let mut buffer = gz + .finish() + .context("should have finished reading from stream")?; + + // Rewind to the beginning of the now gzip encoded contents image, + // so that it can be iterated over to create zarf-payload-* chunks + buffer + .rewind() + .context("should have rewound buffer for reading")?; + let mut reader = BufReader::with_capacity(CHUNK_SIZE, buffer); + + let mut hasher = Sha256::new(); + let mut chunk_id = 0; + while let std::result::Result::Ok(chunk) = reader.fill_buf() { + let read_bytes = chunk.len(); + if read_bytes == 0 { + break; + } + + hasher.update(chunk); + + // Write chunks to disk as zarf-payload-00X in temp dir + let mut chunk_file = File::create( + input_dir.join(format!("{}-{:0>3}", ZARF_PAYLOAD_PREFIX, chunk_id)), + ) + .context("should have created chunk file")?; + chunk_file + .write_all(chunk) + .context("should have written chunk to file")?; + chunk_file + .flush() + .context("should have flushed chunk file")?; + chunk_id += 1; + + reader.consume(read_bytes); + } + let hash = hasher.finalize(); + let digest = format!("{hash:x}"); + + Ok(Self { + digest, + input_dir, + output_dir, + }) + } + + fn shasum(&self) -> String { + self.digest.to_owned() + } + + fn input_dir(&self) -> PathBuf { + self.input_dir.to_owned() + } + + fn output_dir(&self) -> PathBuf { + self.output_dir.to_owned() + } + + async fn ensure_image_exists_locally(client: &Docker, image: &str) -> Result<()> { + // Check if the test image already exists. + if (client.inspect_image(image).await).is_ok() { + Ok(()) + } else { + let options = Some(CreateImageOptions { + from_image: image, + ..Default::default() + }); + // Attempt to pull image from the upstream registry + let _ = client + .create_image(options, None, None) + .try_collect::>() + .await + .map_err(anyhow::Error::msg) + .context("should have been able to pull test image")?; + // Inspect the image to make sure it exists locally and then discard the output + Ok(client.inspect_image(image).await.map(|_| ())?) + } + } + } +}