diff --git a/Cargo.lock b/Cargo.lock index 55e1ed370..a08a2de10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,11 +79,45 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "aws-lc-rs" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "boil" @@ -97,7 +131,9 @@ dependencies = [ "glob", "oci-spec", "regex", + "reqwest", "rstest", + "secrecy", "serde", "serde_json", "snafu", @@ -162,17 +198,29 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "clap" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -211,9 +259,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.6.0" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -227,12 +275,31 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "console" version = "0.16.3" @@ -247,11 +314,12 @@ dependencies = [ [[package]] name = "const_format" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" dependencies = [ "const_format_proc_macros", + "konst", ] [[package]] @@ -265,6 +333,32 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "darling" version = "0.20.11" @@ -351,12 +445,27 @@ dependencies = [ "syn", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "encode_unicode" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -417,6 +526,21 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" version = "0.3.32" @@ -434,6 +558,12 @@ dependencies = [ "syn", ] +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + [[package]] name = "futures-task" version = "0.3.32" @@ -459,6 +589,19 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + [[package]] name = "getrandom" version = "0.3.4" @@ -466,9 +609,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] @@ -506,7 +651,7 @@ dependencies = [ "libc", "libgit2-sys", "log", - "openssl-probe", + "openssl-probe 0.1.6", "openssl-sys", "url", ] @@ -517,6 +662,25 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.15.5" @@ -538,6 +702,106 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + [[package]] name = "icu_collections" version = "2.2.0" @@ -707,6 +971,16 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +[[package]] +name = "iri-string" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -719,6 +993,50 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -735,10 +1053,27 @@ version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "lazy_static" version = "1.5.0" @@ -815,6 +1150,12 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "matchers" version = "0.2.0" @@ -836,6 +1177,12 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "mio" version = "1.2.0" @@ -876,7 +1223,7 @@ dependencies = [ "serde_json", "strum 0.27.2", "strum_macros 0.27.2", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -897,6 +1244,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "openssl-sys" version = "0.9.113" @@ -964,6 +1317,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -1014,6 +1376,62 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "aws-lc-rs", + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" version = "1.0.45" @@ -1035,6 +1453,35 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "rand" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "regex" version = "1.12.3" @@ -1070,6 +1517,60 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" +[[package]] +name = "reqwest" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rstest" version = "0.26.1" @@ -1100,42 +1601,173 @@ dependencies = [ ] [[package]] -name = "rustc_version" -version = "0.4.1" +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustix-linux-procfs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc84bf7e9aa16c4f2c758f27412dc9841341e16aa682d9c7ac308fe3ee12056" +dependencies = [ + "once_cell", + "rustix", +] + +[[package]] +name = "rustls" +version = "0.23.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" +dependencies = [ + "aws-lc-rs", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe 0.2.1", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.103.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "same-file" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ - "semver", + "winapi-util", ] [[package]] -name = "rustix" -version = "1.1.4" +name = "schannel" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", "windows-sys 0.61.2", ] [[package]] -name = "rustix-linux-procfs" -version = "0.1.1" +name = "secrecy" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fc84bf7e9aa16c4f2c758f27412dc9841341e16aa682d9c7ac308fe3ee12056" +checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" dependencies = [ - "once_cell", - "rustix", + "zeroize", ] [[package]] -name = "rustversion" -version = "1.0.22" +name = "security-framework" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] [[package]] name = "semver" @@ -1253,6 +1885,16 @@ dependencies = [ "syn", ] +[[package]] +name = "socket2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -1304,6 +1946,12 @@ dependencies = [ "syn", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.117" @@ -1315,6 +1963,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -1326,6 +1983,27 @@ dependencies = [ "syn", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" version = "3.27.0" @@ -1339,13 +2017,33 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1409,17 +2107,33 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +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.51.1" +version = "1.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" +checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" dependencies = [ "bytes", "libc", "mio", "pin-project-lite", "signal-hook-registry", + "socket2", "tokio-macros", "windows-sys 0.61.2", ] @@ -1435,6 +2149,29 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml" version = "1.1.2+spec-1.1.0" @@ -1486,6 +2223,51 @@ version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.44" @@ -1559,6 +2341,12 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "unicode-ident" version = "1.0.24" @@ -1583,6 +2371,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.8" @@ -1641,6 +2435,25 @@ dependencies = [ "memchr", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[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.1+wasi-snapshot-preview1" @@ -1678,6 +2491,16 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.118" @@ -1744,6 +2567,16 @@ dependencies = [ "semver", ] +[[package]] +name = "web-sys" +version = "0.3.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "web-time" version = "1.1.0" @@ -1754,12 +2587,77 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -1787,6 +2685,21 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.52.6" @@ -1820,6 +2733,12 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -1832,6 +2751,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -1844,6 +2769,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1868,6 +2799,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -1880,6 +2817,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -1892,6 +2835,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -1904,6 +2853,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -2052,6 +3007,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zerocopy" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerofrom" version = "0.1.7" @@ -2073,6 +3048,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerotrie" version = "0.2.4" diff --git a/Cargo.toml b/Cargo.toml index 16cccf679..a74124a43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,9 @@ clap_complete_nushell = "4.5.8" git2 = "0.20.1" glob = "0.3.2" oci-spec = "0.9.0" +reqwest = { version = "0.13.2", features = ["json"] } rstest = "0.26.1" +secrecy = "0.10.3" regex = "1.12.3" serde = { version = "1.0.217", features = ["derive"] } serde_json = "1.0.140" diff --git a/airflow/boil-config.toml b/airflow/boil-config.toml index b768fd851..eaba370c6 100644 --- a/airflow/boil-config.toml +++ b/airflow/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + # Deprecated since SDP 25.11 [versions."2.9.3".local-images] "shared/statsd-exporter" = "0.28.0" diff --git a/boil.toml b/boil.toml index e83a38236..be505b12a 100644 --- a/boil.toml +++ b/boil.toml @@ -11,5 +11,3 @@ authors = "Stackable GmbH " vendor-tag-prefix = "stackable" vendor = "Stackable GmbH" licenses = "Apache-2.0" - -[docker-config] diff --git a/druid/boil-config.toml b/druid/boil-config.toml index 2e1babe3e..8910b6818 100644 --- a/druid/boil-config.toml +++ b/druid/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + # LTS since 24.11 [versions."30.0.1".local-images] # https://druid.apache.org/docs/30.0.1/operations/java/ diff --git a/hadoop/boil-config.toml b/hadoop/boil-config.toml index 80190dd27..4c6ef2a64 100644 --- a/hadoop/boil-config.toml +++ b/hadoop/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + # Not part of SDP 25.7.0, but still required for hbase, hive, spark-k8s [versions."3.3.6".local-images] "hadoop/hadoop" = "3.3.6" diff --git a/hbase/boil-config.toml b/hbase/boil-config.toml index c00fddd1f..66d1af206 100644 --- a/hbase/boil-config.toml +++ b/hbase/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."2.6.3".local-images] "hbase/hbase" = "2.6.3" "hbase/hbase-operator-tools" = "1.3.0-hbase2.6.3" diff --git a/hive/boil-config.toml b/hive/boil-config.toml index aab12f907..6731797dc 100644 --- a/hive/boil-config.toml +++ b/hive/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."3.1.3".local-images] # Hive 3 must be built with Java 8 but will run on Java 11 java-base = "11" diff --git a/java-devel/boil-config.toml b/java-devel/boil-config.toml index d42101fe4..778baedd9 100644 --- a/java-devel/boil-config.toml +++ b/java-devel/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."8".local-images] stackable-devel = "1.0.0" diff --git a/jdk-base/boil-config.toml b/jdk-base/boil-config.toml index 58a93e0b5..832ecb67a 100644 --- a/jdk-base/boil-config.toml +++ b/jdk-base/boil-config.toml @@ -1,6 +1,5 @@ [versions."21".local-images] vector = "0.52.0" - [versions."24".local-images] vector = "0.52.0" diff --git a/kafka-testing-tools/boil-config.toml b/kafka-testing-tools/boil-config.toml index ca78f8116..070c5f882 100644 --- a/kafka-testing-tools/boil-config.toml +++ b/kafka-testing-tools/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."1.0.0".local-images] stackable-base = "1.0.0" "kafka/kcat" = "1.7.0" diff --git a/kafka/boil-config.toml b/kafka/boil-config.toml index 84848f5d1..0d5d0a387 100644 --- a/kafka/boil-config.toml +++ b/kafka/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."3.9.1".local-images] java-base = "21" java-devel = "21" diff --git a/krb5/boil-config.toml b/krb5/boil-config.toml index dc853fd32..b706861e6 100644 --- a/krb5/boil-config.toml +++ b/krb5/boil-config.toml @@ -1 +1,4 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."1.21.1"] diff --git a/nifi/boil-config.toml b/nifi/boil-config.toml index 486b88d10..b81d7e8cc 100644 --- a/nifi/boil-config.toml +++ b/nifi/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."1.28.1".local-images] java-base = "11" java-devel = "11" diff --git a/omid/boil-config.toml b/omid/boil-config.toml index c6df6e0db..6989cfe86 100644 --- a/omid/boil-config.toml +++ b/omid/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."1.1.2".local-images] java-base = "11" java-devel = "11" diff --git a/opa/boil-config.toml b/opa/boil-config.toml index 2bb749e3c..9c1e9c98e 100644 --- a/opa/boil-config.toml +++ b/opa/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + # Version 1.8.0 [versions."1.8.0".local-images] stackable-devel = "1.0.0" diff --git a/opensearch-dashboards/boil-config.toml b/opensearch-dashboards/boil-config.toml index bf5ad93cd..8be6cd823 100644 --- a/opensearch-dashboards/boil-config.toml +++ b/opensearch-dashboards/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."3.1.0".local-images] stackable-devel = "1.0.0" vector = "0.52.0" @@ -25,22 +28,22 @@ cdxgen-version = "12.0.0" [versions."3.4.0".local-images] stackable-devel = "1.0.0" -"opensearch-dashboards/alerting-dashboards-plugin"= "3.4.0.0" -"opensearch-dashboards/anomaly-detection-dashboards-plugin"= "3.4.0.0" -"opensearch-dashboards/dashboards-assistant"= "3.4.0.0" -"opensearch-dashboards/dashboards-flow-framework"= "3.4.0.0" -"opensearch-dashboards/dashboards-maps"= "3.4.0.0" -"opensearch-dashboards/dashboards-notifications"= "3.4.0.0" -"opensearch-dashboards/dashboards-observability"= "3.4.0.0" -"opensearch-dashboards/dashboards-query-workbench"= "3.4.0.0" -"opensearch-dashboards/dashboards-reporting"= "3.4.0.0" -"opensearch-dashboards/dashboards-search-relevance"= "3.4.0.0" -"opensearch-dashboards/index-management-dashboards-plugin"= "3.4.0.0" -"opensearch-dashboards/ml-commons-dashboards"= "3.4.0.0" -"opensearch-dashboards/query-insights-dashboards"= "3.4.0.0" -"opensearch-dashboards/security-analytics-dashboards-plugin"= "3.4.0.0" -"opensearch-dashboards/security-dashboards-plugin"= "3.4.0.0" -"opensearch-dashboards/opensearch-build"= "3.4.0" +"opensearch-dashboards/alerting-dashboards-plugin" = "3.4.0.0" +"opensearch-dashboards/anomaly-detection-dashboards-plugin" = "3.4.0.0" +"opensearch-dashboards/dashboards-assistant" = "3.4.0.0" +"opensearch-dashboards/dashboards-flow-framework" = "3.4.0.0" +"opensearch-dashboards/dashboards-maps" = "3.4.0.0" +"opensearch-dashboards/dashboards-notifications" = "3.4.0.0" +"opensearch-dashboards/dashboards-observability" = "3.4.0.0" +"opensearch-dashboards/dashboards-query-workbench" = "3.4.0.0" +"opensearch-dashboards/dashboards-reporting" = "3.4.0.0" +"opensearch-dashboards/dashboards-search-relevance" = "3.4.0.0" +"opensearch-dashboards/index-management-dashboards-plugin" = "3.4.0.0" +"opensearch-dashboards/ml-commons-dashboards" = "3.4.0.0" +"opensearch-dashboards/query-insights-dashboards" = "3.4.0.0" +"opensearch-dashboards/security-analytics-dashboards-plugin" = "3.4.0.0" +"opensearch-dashboards/security-dashboards-plugin" = "3.4.0.0" +"opensearch-dashboards/opensearch-build" = "3.4.0" "vector" = "0.52.0" [versions."3.4.0".build-arguments] diff --git a/opensearch/boil-config.toml b/opensearch/boil-config.toml index b71e52186..4aab8ceac 100644 --- a/opensearch/boil-config.toml +++ b/opensearch/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."3.1.0".local-images] java-devel = "21" jdk-base = "21" diff --git a/rust/boil/Cargo.toml b/rust/boil/Cargo.toml index c33bcc479..8bc17128e 100644 --- a/rust/boil/Cargo.toml +++ b/rust/boil/Cargo.toml @@ -15,7 +15,9 @@ clap_complete_nushell.workspace = true git2.workspace = true glob.workspace = true oci-spec.workspace = true +reqwest.workspace = true regex.workspace = true +secrecy.workspace = true serde.workspace = true serde_json.workspace = true snafu.workspace = true diff --git a/rust/boil/src/cli/build.rs b/rust/boil/src/cli/build.rs index 2c7854485..3409c92a0 100644 --- a/rust/boil/src/cli/build.rs +++ b/rust/boil/src/cli/build.rs @@ -2,19 +2,20 @@ use std::{ fmt::{Debug, Display}, path::PathBuf, str::FromStr, - sync::LazyLock, }; use clap::{Args, ValueHint, value_parser}; -use regex::Regex; use snafu::{ResultExt, Snafu, ensure}; use strum::EnumDiscriminants; use url::Host; -use crate::core::{ - docker::BuildArgument, - image::ImageSelector, - platform::{Architecture, TargetPlatform}, +use crate::{ + cli::Cli, + core::{ + docker::BuildArgument, + image::ImageSelector, + platform::{Architecture, TargetPlatform}, + }, }; #[derive(Debug, Args)] @@ -27,8 +28,8 @@ pub struct BuildArguments { /// The image version being built. #[arg( short, long, - value_parser = BuildArguments::parse_image_version, - default_value_t = Self::default_image_version(), + value_parser = Cli::parse_image_version, + default_value_t = Cli::default_image_version(), help_heading = "Image Options" )] pub image_version: String, @@ -46,7 +47,7 @@ pub struct BuildArguments { /// The format is host[:port]. #[arg( short, long, - default_value_t = Self::default_registry(), + default_value_t = Cli::default_registry(), value_hint = ValueHint::Hostname, help_heading = "Registry Options" )] @@ -130,33 +131,7 @@ pub struct BuildArguments { pub rest: Vec, } -// This is derived from the general rule where the length of the tag can be up to 128 chars -// See: https://github.com/opencontainers/distribution-spec/blob/main/spec.md -// But that checking needs to be at a higher layer. -static VALID_IMAGE_TAG: LazyLock = - LazyLock::new(|| Regex::new(r"^[a-zA-Z0-9_][a-zA-Z0-9_.-]+$").expect("regex is valid")); - impl BuildArguments { - /// Ensure that the given version will be valid for use in the image tag - fn parse_image_version(version: &str) -> Result { - if !VALID_IMAGE_TAG.is_match(version) { - return ParseVersionSnafu { version }.fail(); - } - - Ok(version.to_owned()) - } - - fn default_image_version() -> String { - "0.0.0-dev".to_owned() - } - - fn default_registry() -> HostPort { - HostPort { - host: Host::Domain(String::from("oci.stackable.tech")), - port: None, - } - } - // TODO: Auto-detect this fn default_architecture() -> TargetPlatform { TargetPlatform::Linux(Architecture::Amd64) @@ -167,12 +142,6 @@ impl BuildArguments { } } -#[derive(Debug, Snafu)] -pub enum ParseImageVersionError { - #[snafu(display("invalid image tag characters for {version:?}"))] - ParseVersion { version: String }, -} - #[derive(Debug, PartialEq, Snafu, EnumDiscriminants)] pub enum ParseHostPortError { #[snafu(display("unexpected empty input"))] diff --git a/rust/boil/src/cli/image.rs b/rust/boil/src/cli/image.rs index 9e0fc707b..db208917c 100644 --- a/rust/boil/src/cli/image.rs +++ b/rust/boil/src/cli/image.rs @@ -1,6 +1,6 @@ use clap::{Args, Subcommand, ValueEnum}; -use crate::core::image::ImageSelector; +use crate::{cli::Cli, core::image::ImageSelector}; #[derive(Debug, Args)] pub struct ImageArguments { @@ -10,7 +10,13 @@ pub struct ImageArguments { #[derive(Debug, Subcommand)] pub enum ImageCommand { + /// Lists images known by boil with all available versions. List(ImageListArguments), + + /// Checks if all images known by boil are available in the specified registries. + /// + /// Access tokens must be provided with the following name: `BOIL_REGISTRY_TOKEN_`. + Check(ImageCheckArguments), } #[derive(Debug, Args)] @@ -23,6 +29,22 @@ pub struct ImageListArguments { pub pretty: Pretty, } +#[derive(Debug, Args)] +pub struct ImageCheckArguments { + /// Optionally specify one or more images to check. Checks all images by default. + pub image: Vec, + + // NOTE (@Techassi): Should this maybe be renamed to vendor_version? + /// The image version being built. + #[arg( + short, long, + value_parser = Cli::parse_image_version, + default_value_t = Cli::default_image_version(), + help_heading = "Image Options" + )] + pub image_version: String, +} + // #[derive(Clone, Debug, Default, strum::Display, strum::EnumString)] #[derive(Clone, Debug, Default, ValueEnum)] pub enum Pretty { diff --git a/rust/boil/src/cli/mod.rs b/rust/boil/src/cli/mod.rs index 5c22b0432..13f3e44dc 100644 --- a/rust/boil/src/cli/mod.rs +++ b/rust/boil/src/cli/mod.rs @@ -1,6 +1,8 @@ -use std::path::PathBuf; +use std::{path::PathBuf, sync::LazyLock}; use clap::{Parser, Subcommand}; +use regex::Regex; +use snafu::Snafu; mod build; mod completions; @@ -9,6 +11,19 @@ mod image; pub use build::*; pub use completions::*; pub use image::*; +use url::Host; + +// This is derived from the general rule where the length of the tag can be up to 128 chars +// See: https://github.com/opencontainers/distribution-spec/blob/main/spec.md +// But that checking needs to be at a higher layer. +static VALID_IMAGE_TAG: LazyLock = + LazyLock::new(|| Regex::new(r"^[a-zA-Z0-9_][a-zA-Z0-9_.-]+$").expect("regex is valid")); + +#[derive(Debug, Snafu)] +pub enum ParseImageVersionError { + #[snafu(display("invalid image tag characters for {version:?}"))] + ParseVersion { version: String }, +} #[derive(Debug, Parser)] #[command(author, version, about)] @@ -25,6 +40,26 @@ impl Cli { fn default_config_path() -> PathBuf { PathBuf::from("./boil.toml") } + + pub(super) fn default_image_version() -> String { + "0.0.0-dev".to_owned() + } + + pub(super) fn default_registry() -> HostPort { + HostPort { + host: Host::Domain(String::from("oci.stackable.tech")), + port: None, + } + } + + /// Ensure that the given version will be valid for use in the image tag + pub(super) fn parse_image_version(version: &str) -> Result { + if !VALID_IMAGE_TAG.is_match(version) { + return ParseVersionSnafu { version }.fail(); + } + + Ok(version.to_owned()) + } } #[derive(Debug, Subcommand)] diff --git a/rust/boil/src/cmd/image.rs b/rust/boil/src/cmd/image.rs index 9c53f105f..6a2b2cc66 100644 --- a/rust/boil/src/cmd/image.rs +++ b/rust/boil/src/cmd/image.rs @@ -1,10 +1,14 @@ use std::{collections::BTreeMap, io::IsTerminal}; +use secrecy::{ExposeSecret, SecretString}; use snafu::{ResultExt, Snafu}; use crate::{ - cli::{ImageListArguments, Pretty}, + cli::{ImageCheckArguments, ImageListArguments, Pretty}, + config::Config, core::bakefile::{self, Targets, TargetsOptions}, + models::TagList, + utils::{format_image_index_manifest_tag, format_registry_token_env_var_name}, }; #[derive(Debug, Snafu)] @@ -14,31 +18,136 @@ pub enum Error { #[snafu(display("failed to build list of targets"))] BuildTargets { source: bakefile::TargetsError }, + + #[snafu(display("failed to build request client"))] + BuildClient { source: reqwest::Error }, + + #[snafu(display("failed to send request"))] + SendRequest { source: reqwest::Error }, + + #[snafu(display("failed to deserialize response"))] + DeserializeResponse { source: reqwest::Error }, + + #[snafu(display("missing images found: \n {missing_images}", missing_images = missing_images.join("\n")))] + MissingVersion { missing_images: Vec }, } /// This is the `boil show images` command handler function. pub fn list_images(arguments: ImageListArguments) -> Result<(), Error> { - let list: BTreeMap<_, _> = if arguments.image.is_empty() { - Targets::all(TargetsOptions { only_entry: true }) - .context(BuildTargetsSnafu)? - .into_iter() + let targets = if arguments.image.is_empty() { + Targets::all(TargetsOptions { + only_entry: true, + non_recursive: false, + }) + .context(BuildTargetsSnafu)? } else { - Targets::set(&arguments.image, TargetsOptions { only_entry: true }) - .context(BuildTargetsSnafu)? - .into_iter() - } - .map(|(image_name, image_versions)| { - let versions: Vec<_> = image_versions - .into_iter() - .map(|(image_version, (_, _))| image_version) - .collect(); - (image_name, versions) - }) - .collect(); + Targets::set( + &arguments.image, + TargetsOptions { + only_entry: true, + non_recursive: false, + }, + ) + .context(BuildTargetsSnafu)? + }; + + let list = targets + .into_iter() + .map(|(image_name, (image_config, _))| { + let versions: Vec<_> = image_config + .versions + .into_iter() + .map(|(image_version, _)| image_version) + .collect(); + (image_name, versions) + }) + .collect(); print_to_stdout(list, arguments.pretty) } +pub async fn check_images(arguments: ImageCheckArguments, config: Config) -> Result<(), Error> { + let targets = if arguments.image.is_empty() { + Targets::all(TargetsOptions { + only_entry: true, + non_recursive: true, + }) + .context(BuildTargetsSnafu)? + } else { + Targets::set( + &arguments.image, + TargetsOptions { + only_entry: true, + non_recursive: true, + }, + ) + .context(BuildTargetsSnafu)? + }; + + let mut registry_tokens = BTreeMap::new(); + let client = reqwest::ClientBuilder::new() + .build() + .context(BuildClientSnafu)?; + + let mut missing_images = Vec::new(); + + for (image_name, (image_config, _)) in targets { + for (registry, registry_options) in image_config.metadata.registries { + // Add tokens to a map so that we don't need construct the key and retrieve the value + // over and over again. + let registry_token = registry_tokens.entry(registry.clone()).or_insert_with(|| { + let name = format_registry_token_env_var_name(®istry); + std::env::var(name).ok().map(SecretString::from) + }); + + println!( + "Checking {registry}/{registry_namespace}/{image_name}", + registry_namespace = registry_options.namespace, + ); + + let url = format!( + "https://{registry}/v2/{registry_namespace}/{image_name}/tags/list", + registry_namespace = registry_options.namespace, + ); + let request = client.get(url); + + let request = match ®istry_token { + Some(registry_token) => request.bearer_auth(registry_token.expose_secret()), + None => request, + }; + + let tag_list: TagList = request + .send() + .await + .context(SendRequestSnafu)? + .json() + .await + .context(DeserializeResponseSnafu)?; + + for (image_version, _) in image_config.versions.iter() { + let index_manifest_tag = format_image_index_manifest_tag( + image_version, + &config.metadata.vendor_tag_prefix, + &arguments.image_version, + ); + + let image_identifier = format!("{image_name}:{index_manifest_tag}"); + + println!("- {image_identifier}"); + if !tag_list.tags.contains(&index_manifest_tag) { + missing_images.push(image_identifier); + } + } + } + } + + if !missing_images.is_empty() { + return MissingVersionSnafu { missing_images }.fail(); + } + + Ok(()) +} + fn print_to_stdout(list: BTreeMap>, pretty: Pretty) -> Result<(), Error> { let stdout = std::io::stdout(); diff --git a/rust/boil/src/config.rs b/rust/boil/src/config.rs index 34351c1e0..b84f8c58b 100644 --- a/rust/boil/src/config.rs +++ b/rust/boil/src/config.rs @@ -17,7 +17,7 @@ pub enum ConfigError { #[serde(rename_all = "kebab-case")] pub struct Config { pub build_arguments: docker::BuildArguments, - pub metadata: Metadata, + pub metadata: MetadataOptions, } impl Config { @@ -31,7 +31,7 @@ impl Config { // are optional, the appropriate annotations are only emitted if set. #[derive(Debug, Deserialize)] #[serde(rename_all = "kebab-case")] -pub struct Metadata { +pub struct MetadataOptions { /// The URL to the documentation page. pub documentation: Option, diff --git a/rust/boil/src/core/bakefile.rs b/rust/boil/src/core/bakefile.rs index 417fcef0c..649af56b9 100644 --- a/rust/boil/src/core/bakefile.rs +++ b/rust/boil/src/core/bakefile.rs @@ -1,5 +1,5 @@ use std::{ - collections::BTreeMap, + collections::{BTreeMap, btree_map::Entry}, fmt::Debug, ops::{Deref, DerefMut}, path::PathBuf, @@ -17,11 +17,11 @@ use time::format_description::well_known::Rfc3339; use crate::{ cli::{self, HostPort}, - config::{self, Config, Metadata}, + config::{self, Config, MetadataOptions}, constants::DOCKER_LABEL_BUILD_DATE, core::{ docker, - image::{ImageConfig, ImageConfigError, ImageOptions, ImageSelector, VersionOptionsPair}, + image::{ImageConfig, ImageConfigError, ImageSelector}, platform::TargetPlatform, }, utils, @@ -82,19 +82,25 @@ pub enum TargetsError { #[derive(Debug, Default)] pub struct TargetsOptions { + /// Only select the entry images (selected by the image selector). This is particular useful for + /// the image list command. pub only_entry: bool, + + /// If a non recursive glob pattern should be used meaning only the top-level directories will + /// be searched for config files. + pub non_recursive: bool, } /// Contains targets selected by the user. /// -/// This is a map which uses the image/target name as the key. Each key points to another map, -/// which contains one entry per version of the target. Each value contains the image options and -/// a boolean flag to indicate if this target is an entry target. +/// This is a map which uses the image/target name as the key. Each key points to image config +/// containing filtered versions. Additionally, each value contains a boolean flag to indicate if +/// this target is an entry target. #[derive(Debug, Default)] -pub struct Targets(BTreeMap>); +pub struct Targets(BTreeMap); impl Deref for Targets { - type Target = BTreeMap>; + type Target = BTreeMap; fn deref(&self) -> &Self::Target { &self.0 @@ -108,9 +114,8 @@ impl DerefMut for Targets { } impl IntoIterator for Targets { - type IntoIter = - std::collections::btree_map::IntoIter>; - type Item = (String, BTreeMap); + type IntoIter = std::collections::btree_map::IntoIter; + type Item = (String, (ImageConfig, bool)); fn into_iter(self) -> Self::IntoIter { self.0.into_iter() @@ -134,9 +139,13 @@ impl Targets { // See https://github.com/rust-lang/rust-clippy/pull/15445 #[allow(clippy::unwrap_in_result)] pub fn all(options: TargetsOptions) -> Result { - let image_config_paths = glob(ImageConfig::ALL_CONFIGS_GLOB_PATTERN) - .expect("constant glob pattern must be valid") - .filter_map(Result::ok); + let image_config_paths = if options.non_recursive { + glob(ImageConfig::FLAT_CONFIG_GLOB_PATTERN) + } else { + glob(ImageConfig::ALL_CONFIGS_GLOB_PATTERN) + } + .expect("constant glob pattern must be valid") + .filter_map(Result::ok); let mut targets = Self::default(); @@ -152,9 +161,7 @@ impl Targets { .to_string_lossy() .into_owned(); - let pairs = image_config.all(); - - targets.insert_targets(image_name.to_owned(), pairs, &options, true)?; + targets.insert_targets(image_name.to_owned(), image_config, &options, true)?; } Ok(targets) @@ -176,15 +183,15 @@ impl Targets { // Read the image config which defines supported image versions and their dependencies as // well as other values. - let image_config = + let mut image_config = ImageConfig::from_file(image_config_path).context(ReadImageConfigSnafu)?; // Create a list of image versions we need to generate targets for in the bakefile. - let pairs = image_config + image_config .filter_by_version(&image.versions) .context(InvalidImageVersionSnafu)?; - targets.insert_targets(image.name.clone(), pairs, &options, true)?; + targets.insert_targets(image.name.clone(), image_config, &options, true)?; } Ok(targets) @@ -193,21 +200,17 @@ impl Targets { fn insert_targets( &mut self, image_name: String, - pairs: Vec, + config: ImageConfig, options: &TargetsOptions, is_entry: bool, ) -> Result<(), TargetsError> { - for VersionOptionsPair { - version: image_version, - options: image_options, - } in pairs - { + for image_options in (*config.versions).values() { if !options.only_entry { // TODO (@Techassi): Add cycle detection for (image_name, image_version) in &image_options.local_images { if self .get(image_name) - .is_some_and(|image_versions| image_versions.contains_key(image_version)) + .is_some_and(|(config, _)| config.versions.contains_key(image_version)) { continue; } @@ -216,21 +219,29 @@ impl Targets { .join(image_name) .join(ImageConfig::DEFAULT_FILE_NAME); - let image_config = + let mut image_config = ImageConfig::from_file(image_config_path).context(ReadImageConfigSnafu)?; - let pairs = image_config + image_config .filter_by_version(&[image_version]) .context(InvalidImageVersionSnafu)?; // Wowzers, recursion! - self.insert_targets(image_name.clone(), pairs, options, false)?; + self.insert_targets(image_name.clone(), image_config, options, false)?; } } + } - self.entry(image_name.clone()) - .or_default() - .insert(image_version, (image_options, is_entry)); + // We explicitly use the entry API without using the combinator functions because of issues + // regarding partial moves and borrowing. + match self.entry(image_name) { + Entry::Vacant(entry) => { + entry.insert((config, is_entry)); + } + Entry::Occupied(mut entry) => { + let (exiting_config, _) = entry.get_mut(); + exiting_config.versions.extend(config.versions); + } } Ok(()) @@ -276,7 +287,7 @@ impl Bakefile { fn common_target( cli_args: &cli::BuildArguments, container_build_args: docker::BuildArguments, - metadata: &Metadata, + metadata: &MetadataOptions, ) -> Result { let revision = Self::git_head_revision().context(GetRevisionSnafu)?; let date_time = Self::now()?; @@ -313,6 +324,7 @@ impl Bakefile { let Config { build_arguments, metadata, + .. } = config; // Create a common target, which contains shared data, like annotations, arguments, labels, etc... @@ -326,8 +338,8 @@ impl Bakefile { &cli_args.registry }; - for (image_name, image_versions) in targets.into_iter() { - for (image_version, (image_options, is_entry)) in image_versions { + for (image_name, (image_config, is_entry)) in targets.into_iter() { + for (image_version, image_options) in image_config.versions { let image_repository_uri = utils::format_image_repository_uri( image_registry, &cli_args.registry_namespace, @@ -574,9 +586,9 @@ impl BakefileTarget { release_version: String, container_build_args: docker::BuildArguments, user_container_build_args: Vec, - metadata: &Metadata, + metadata: &MetadataOptions, ) -> Self { - let config::Metadata { + let config::MetadataOptions { documentation: docs, licenses, authors, diff --git a/rust/boil/src/core/image.rs b/rust/boil/src/core/image.rs index 70c43bb93..418ca6a8d 100644 --- a/rust/boil/src/core/image.rs +++ b/rust/boil/src/core/image.rs @@ -1,7 +1,7 @@ use std::{ collections::BTreeMap, fmt::Display, - ops::Deref, + ops::{Deref, DerefMut}, path::{Path, PathBuf}, str::FromStr, }; @@ -9,7 +9,7 @@ use std::{ use serde::Deserialize; use snafu::{ResultExt as _, Snafu, ensure}; -use crate::{IfContext, core::docker}; +use crate::core::docker; #[derive(Debug, PartialEq, Snafu)] pub enum ParseImageSelectorError { @@ -115,9 +115,9 @@ pub enum ImageConfigError { #[derive(Debug, Deserialize)] pub struct ImageConfig { - // TODO (@Techassi): Eventually support this - // #[serde(default)] - // pub metadata: ImageMetadata, + #[serde(default)] + pub metadata: ImageMetadata, + pub versions: ImageVersions, } @@ -126,31 +126,20 @@ impl ImageConfig { pub const ALL_CONFIGS_GLOB_PATTERN: &str = "**/boil-config.toml"; /// The default image config file name. pub const DEFAULT_FILE_NAME: &str = "boil-config.toml"; + /// This glob pattern matches all (top-level) image configs. + pub const FLAT_CONFIG_GLOB_PATTERN: &str = "*/boil-config.toml"; - pub fn filter_by_version( - self, - versions: &[V], - ) -> Result, ImageConfigError> + /// This function removes versions in the config filtered out by `versions`. + pub fn filter_by_version(&mut self, versions: &[V]) -> Result<(), ImageConfigError> where V: AsRef + PartialEq, { - let versions: Vec<_> = self - .pairs() - .filter(|(image_version, _)| { - versions.is_empty() || versions.iter().any(|v| v.as_ref() == image_version) - }) - .map(Into::into) - .collect(); - - versions.if_context(|v| !v.is_empty(), EmptyFilterSnafu) - } - - pub fn all(self) -> Vec { - self.pairs().map(Into::into).collect() - } + self.versions.retain(|image_version, _| { + versions.is_empty() || versions.iter().any(|v| v.as_ref() == image_version) + }); - fn pairs(self) -> impl Iterator { - self.versions.0.into_iter() + ensure!(!self.versions.is_empty(), EmptyFilterSnafu); + Ok(()) } } @@ -163,19 +152,34 @@ impl ImageConfig { } #[derive(Debug, Deserialize)] -pub struct ImageVersions(BTreeMap); +pub struct ImageVersions(BTreeMap); impl Deref for ImageVersions { - type Target = BTreeMap; + type Target = BTreeMap; fn deref(&self) -> &Self::Target { &self.0 } } +impl DerefMut for ImageVersions { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl IntoIterator for ImageVersions { + type IntoIter = std::collections::btree_map::IntoIter; + type Item = (String, ImageVersionOptions); + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + #[derive(Debug, Deserialize)] #[serde(rename_all = "kebab-case")] -pub struct ImageOptions { +pub struct ImageVersionOptions { #[serde(default)] pub local_images: BTreeMap, @@ -192,19 +196,16 @@ pub struct ImageOptions { pub dockerfile: Option, } -#[derive(Debug)] -pub struct VersionOptionsPair { - pub version: String, - pub options: ImageOptions, +#[derive(Debug, Default, Deserialize)] +pub struct ImageMetadata { + /// A map of registries an image is published to and various options configurable for each one. + #[serde(default)] + pub registries: BTreeMap, } -impl From<(String, ImageOptions)> for VersionOptionsPair { - fn from(value: (String, ImageOptions)) -> Self { - VersionOptionsPair { - version: value.0, - options: value.1, - } - } +#[derive(Debug, Deserialize)] +pub struct RegistryOptions { + pub namespace: String, } #[cfg(test)] diff --git a/rust/boil/src/main.rs b/rust/boil/src/main.rs index fa767fd93..0f76196f4 100644 --- a/rust/boil/src/main.rs +++ b/rust/boil/src/main.rs @@ -2,16 +2,16 @@ use clap::Parser; use snafu::{ResultExt, Snafu}; use crate::{ - cli::{Cli, Command, ImageArguments, ImageCommand}, + cli::{Cli, Command, ImageCommand}, config::Config, }; -// Common modules mod cli; mod cmd; mod config; mod constants; mod core; +mod models; mod utils; /// This trait extends functionailty provided by [`snafu`]. @@ -67,10 +67,16 @@ async fn main() -> Result<(), Error> { let config = Config::from_file(&cli.config_path).context(ReadConfigSnafu)?; cmd::build::run_command(arguments, config).context(BuildSnafu) } - Command::Images(arguments) - | Command::Image(ImageArguments { - command: ImageCommand::List(arguments), - }) => cmd::image::list_images(arguments).context(ImageSnafu), + Command::Image(arguments) => match arguments.command { + ImageCommand::List(arguments) => cmd::image::list_images(arguments).context(ImageSnafu), + ImageCommand::Check(arguments) => { + let config = Config::from_file(&cli.config_path).context(ReadConfigSnafu)?; + cmd::image::check_images(arguments, config) + .await + .context(ImageSnafu) + } + }, + Command::Images(arguments) => cmd::image::list_images(arguments).context(ImageSnafu), Command::Completions(arguments) => { cmd::completions::run_command(arguments); Ok(()) diff --git a/rust/boil/src/models/mod.rs b/rust/boil/src/models/mod.rs new file mode 100644 index 000000000..54df693bb --- /dev/null +++ b/rust/boil/src/models/mod.rs @@ -0,0 +1,8 @@ +use serde::Deserialize; + +#[derive(Debug, Deserialize)] +pub struct TagList { + // #[serde(rename = "name")] + // pub _name: String, + pub tags: Vec, +} diff --git a/rust/boil/src/utils.rs b/rust/boil/src/utils.rs index 6f214a9ca..895eec6a8 100644 --- a/rust/boil/src/utils.rs +++ b/rust/boil/src/utils.rs @@ -41,6 +41,14 @@ pub fn format_image_manifest_tag( } } +/// Formats and returns the registry-specific env var name, eg. `BOIL_REGISTRY_TOKEN_OCI_STACKABLE_TECH`. +pub fn format_registry_token_env_var_name(registry_uri: &str) -> String { + format!( + "BOIL_REGISTRY_TOKEN_{registry_uri}", + registry_uri = registry_uri.replace(['.', '-'], "_").to_uppercase() + ) +} + pub trait CommandExt { /// Adds an argument to the command if the `predicate` is `true`. fn arg_if(&mut self, predicate: bool, arg: S) -> &mut Self diff --git a/shared/statsd-exporter/boil-config.toml b/shared/statsd-exporter/boil-config.toml index c2f9afcb2..408235597 100644 --- a/shared/statsd-exporter/boil-config.toml +++ b/shared/statsd-exporter/boil-config.toml @@ -1,2 +1,5 @@ +[metadata] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."0.28.0".local-images] stackable-base = "1.0.0" diff --git a/spark-connect-client/boil-config.toml b/spark-connect-client/boil-config.toml index f1ac8fbc9..3beb191ed 100644 --- a/spark-connect-client/boil-config.toml +++ b/spark-connect-client/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "stackable" } + [versions."3.5.7".local-images] spark-k8s = "3.5.7" java-base = "17" diff --git a/spark-k8s/boil-config.toml b/spark-k8s/boil-config.toml index 8ea324386..1ebde375c 100644 --- a/spark-k8s/boil-config.toml +++ b/spark-k8s/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."3.5.7"] containerfile = "Dockerfile.3" diff --git a/stackable-base/boil-config.toml b/stackable-base/boil-config.toml index fa7f2b5ce..bb794a933 100644 --- a/stackable-base/boil-config.toml +++ b/stackable-base/boil-config.toml @@ -1,2 +1,4 @@ +[metadata] + [versions."1.0.0".local-images] stackable-devel = "1.0.0" diff --git a/superset/boil-config.toml b/superset/boil-config.toml index 7531b4f09..9e91d32c1 100644 --- a/superset/boil-config.toml +++ b/superset/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."4.1.4".local-images] "shared/statsd-exporter" = "0.28.0" stackable-devel = "1.0.0" diff --git a/testing-tools/boil-config.toml b/testing-tools/boil-config.toml index 35487b91b..f8ba25776 100644 --- a/testing-tools/boil-config.toml +++ b/testing-tools/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."0.3.0".build-arguments] kubectl-version = "1.35.0" python-version = "3.12" diff --git a/tools/boil-config.toml b/tools/boil-config.toml index 1269e7716..55fcf6498 100644 --- a/tools/boil-config.toml +++ b/tools/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."1.0.0".local-images] stackable-base = "1.0.0" diff --git a/trino-cli/boil-config.toml b/trino-cli/boil-config.toml index 440f7156d..d559ef3fc 100644 --- a/trino-cli/boil-config.toml +++ b/trino-cli/boil-config.toml @@ -1,2 +1,5 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."479".local-images] java-base = "25" diff --git a/trino/boil-config.toml b/trino/boil-config.toml index 00147c5f3..0ac6ddb8c 100644 --- a/trino/boil-config.toml +++ b/trino/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."477".local-images] java-base = "24" "trino/trino" = "477" diff --git a/vector/boil-config.toml b/vector/boil-config.toml index 0d00443c4..5b28896d6 100644 --- a/vector/boil-config.toml +++ b/vector/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."0.52.0".local-images] # We need to point to a special version of stackable-devel which will have the # correct toolchain to build vector. diff --git a/zookeeper/boil-config.toml b/zookeeper/boil-config.toml index cab00dcde..f22cf51cd 100644 --- a/zookeeper/boil-config.toml +++ b/zookeeper/boil-config.toml @@ -1,3 +1,6 @@ +[metadata.registries] +"oci.stackable.tech" = { namespace = "sdp" } + [versions."3.9.4".local-images] java-base = "17" java-devel = "11"