From a551755078f63faed10f1ca6819cce8af31e1a3d Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 15:24:56 +0200 Subject: [PATCH 01/18] chore: Point stackable-operator at smooth-operator branch Co-Authored-By: Claude Opus 4.8 (1M context) --- Cargo.lock | 281 +++++++++++++++++++++++++++-------------------------- Cargo.toml | 6 +- 2 files changed, 144 insertions(+), 143 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 575558a9..4443e37c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,9 +163,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "axum" @@ -265,9 +265,9 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" [[package]] name = "block-buffer" @@ -280,9 +280,9 @@ dependencies = [ [[package]] name = "built" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" +checksum = "5c0e531d93d39c34eef561e929e8a7f86d77a5af08aac4f6d6e39976c51858e9" dependencies = [ "chrono", "git2", @@ -290,9 +290,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytes" @@ -302,9 +302,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.60" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "jobserver", @@ -613,9 +613,9 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -676,9 +676,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elliptic-curve" @@ -924,9 +924,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" @@ -983,15 +983,14 @@ dependencies = [ [[package]] name = "git2" -version = "0.20.4" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +checksum = "ddddbf932745a6be37109b6112d3ee09696106f848449069d3a57bba937ab82e" dependencies = [ "bitflags", "libc", "libgit2-sys", "log", - "url", ] [[package]] @@ -1025,9 +1024,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -1055,9 +1054,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -1087,9 +1086,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" dependencies = [ "bytes", "itoa", @@ -1138,9 +1137,9 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -1336,9 +1335,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1351,7 +1350,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", ] [[package]] @@ -1369,16 +1368,6 @@ 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" @@ -1413,9 +1402,9 @@ dependencies = [ [[package]] name = "jiff" -version = "0.2.23" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -1423,14 +1412,14 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.61.2", + "windows-link", ] [[package]] name = "jiff-static" -version = "0.2.23" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" dependencies = [ "proc-macro2", "quote", @@ -1464,9 +1453,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -1476,14 +1465,15 @@ dependencies = [ [[package]] name = "json-patch" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f300e415e2134745ef75f04562dd0145405c2f7fd92065db029ac4b16b57fe90" +checksum = "7421438de105a0827e44fadd05377727847d717c80ce29a229f85fd04c427b72" dependencies = [ "jsonptr", + "schemars", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] @@ -1525,11 +1515,11 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "darling", "regex", - "snafu 0.9.0", + "snafu 0.9.1", ] [[package]] @@ -1666,15 +1656,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.185" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libgit2-sys" -version = "0.18.3+1.9.2" +version = "0.18.5+1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" +checksum = "005d6ae6eac1912906073e069f7db60b1fa98e052a68227824afe3e3a1c59ca2" dependencies = [ "cc", "libc", @@ -1690,9 +1680,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libz-sys" -version = "1.1.28" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ "cc", "libc", @@ -1717,9 +1707,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "113b30b4cd05f7c06868fdb2854f66a7b9fece9a48425351cd532e810d74024f" [[package]] name = "matchers" @@ -1738,9 +1728,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "mime" @@ -1760,9 +1750,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -1796,9 +1786,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -2062,18 +2052,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -2474,9 +2464,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.38" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "log", "once_cell", @@ -2489,9 +2479,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -2501,9 +2491,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "zeroize", ] @@ -2677,9 +2667,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -2757,9 +2747,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signal-hook-registry" @@ -2820,11 +2810,11 @@ dependencies = [ [[package]] name = "snafu" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1d4bced6a69f90b2056c03dcff2c4737f98d6fb9e0853493996e1d253ca29c6" +checksum = "d1a012328be2e3f5d5f6f3218147ca02588cea4cb865e876849ab6debcf36522" dependencies = [ - "snafu-derive 0.9.0", + "snafu-derive 0.9.1", ] [[package]] @@ -2852,9 +2842,9 @@ dependencies = [ [[package]] name = "snafu-derive" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54254b8531cafa275c5e096f62d48c81435d1015405a91198ddb11e967301d40" +checksum = "5f103c50866b8743da9429b8a581d81a27c2d3a9c4ac7df8f8571c1dd7896eda" dependencies = [ "heck", "proc-macro2", @@ -2864,9 +2854,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -2897,7 +2887,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stackable-certs" version = "0.4.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "const-oid", "ecdsa", @@ -2909,7 +2899,7 @@ dependencies = [ "rsa", "sha2", "signature", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-shared", "tokio", "tokio-rustls", @@ -2936,7 +2926,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-operator", "strum", "tokio", @@ -2945,8 +2935,8 @@ dependencies = [ [[package]] name = "stackable-operator" -version = "0.111.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +version = "0.111.1" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "base64", "clap", @@ -2970,7 +2960,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-operator-derive", "stackable-shared", "stackable-telemetry", @@ -2982,12 +2972,13 @@ dependencies = [ "tracing-appender", "tracing-subscriber", "url", + "uuid", ] [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "darling", "proc-macro2", @@ -2998,7 +2989,7 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.1.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "jiff", "k8s-openapi", @@ -3007,7 +2998,7 @@ dependencies = [ "semver", "serde", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "strum", "time", ] @@ -3015,7 +3006,7 @@ dependencies = [ [[package]] name = "stackable-telemetry" version = "0.6.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "axum", "clap", @@ -3026,7 +3017,7 @@ dependencies = [ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "pin-project", - "snafu 0.9.0", + "snafu 0.9.1", "strum", "tokio", "tower", @@ -3039,21 +3030,21 @@ dependencies = [ [[package]] name = "stackable-versioned" version = "0.10.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "kube", "schemars", "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-versioned-macros", ] [[package]] name = "stackable-versioned-macros" version = "0.10.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "convert_case", "convert_case_extras", @@ -3071,7 +3062,7 @@ dependencies = [ [[package]] name = "stackable-webhook" version = "0.9.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "arc-swap", "async-trait", @@ -3087,7 +3078,7 @@ dependencies = [ "rand 0.9.4", "serde", "serde_json", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-certs", "stackable-shared", "stackable-telemetry", @@ -3294,9 +3285,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -3366,9 +3357,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", "toml_datetime", @@ -3387,9 +3378,9 @@ dependencies = [ [[package]] name = "tonic" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", "base64", @@ -3414,9 +3405,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", "prost", @@ -3444,9 +3435,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "base64", "bitflags", @@ -3454,13 +3445,13 @@ dependencies = [ "futures-util", "http", "http-body", - "iri-string", "mime", "pin-project-lite", "tower", "tower-layer", "tower-service", "tracing", + "url", ] [[package]] @@ -3587,9 +3578,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "ucd-trie" @@ -3605,9 +3596,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-xid" @@ -3652,6 +3643,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" @@ -3696,9 +3697,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -3709,9 +3710,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -3719,9 +3720,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3729,9 +3730,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -3742,18 +3743,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -3912,9 +3913,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -3947,9 +3948,9 @@ dependencies = [ [[package]] name = "xml" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8aa498d22c9bbaf482329839bc5620c46be275a19a812e9a22a2b07529a642a" +checksum = "636f85e5ca6488e96401b61eb7de54f4e44755c988af0f52cf90230c312a1a89" [[package]] name = "yoke" @@ -3976,18 +3977,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" dependencies = [ "proc-macro2", "quote", @@ -3996,9 +3997,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] diff --git a/Cargo.toml b/Cargo.toml index ec6d3e67..2a306cf7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", anyhow = "1.0" built = { version = "0.8", features = ["chrono", "git2"] } -clap = "4.5" +clap = "4.6" const_format = "0.2" fnv = "1.0" futures = { version = "0.3", features = ["compat"] } @@ -28,9 +28,9 @@ serde_json = "1.0" serde_yaml = "0.9" snafu = "0.9" strum = { version = "0.28", features = ["derive"] } -tokio = { version = "1.40", features = ["full"] } +tokio = { version = "1.52", features = ["full"] } tracing = "0.1" [patch."https://github.com/stackabletech/operator-rs.git"] +stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "smooth-operator" } # stackable-operator = { path = "../operator-rs/crates/stackable-operator" } -# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } From 262333b73ca66e6189e80fb3b2829b0416c37abd Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 15:27:47 +0200 Subject: [PATCH 02/18] feat: Vendor framework::role_utils (mirrors trino) Co-Authored-By: Claude Opus 4.8 (1M context) --- rust/operator-binary/src/framework.rs | 13 ++ .../src/framework/role_utils.rs | 140 ++++++++++++++++++ rust/operator-binary/src/main.rs | 2 + 3 files changed, 155 insertions(+) create mode 100644 rust/operator-binary/src/framework.rs create mode 100644 rust/operator-binary/src/framework/role_utils.rs diff --git a/rust/operator-binary/src/framework.rs b/rust/operator-binary/src/framework.rs new file mode 100644 index 00000000..75d7a9cb --- /dev/null +++ b/rust/operator-binary/src/framework.rs @@ -0,0 +1,13 @@ +//! Local framework helpers that mirror the work-in-progress upstream +//! `stackable_operator::v2::*` modules. +//! +//! We vendor `role_utils` because the upstream `v2::role_utils` requires +//! `CommonConfig: Merge` and uses `EnvVarSet` for `env_overrides`. Hive (like +//! trino) uses `JavaCommonConfig`, whose JVM-argument merge is fallible and so +//! does not implement `Merge`; we also want `env_overrides` as a plain +//! `BTreeMap`. +//! +//! Follow-up: replace with `stackable_operator::v2::role_utils::*` once upstream +//! relaxes the `Merge` bound. + +pub mod role_utils; diff --git a/rust/operator-binary/src/framework/role_utils.rs b/rust/operator-binary/src/framework/role_utils.rs new file mode 100644 index 00000000..5c3a80c6 --- /dev/null +++ b/rust/operator-binary/src/framework/role_utils.rs @@ -0,0 +1,140 @@ +//! Vendored variant of `stackable_operator::v2::role_utils` from the +//! `smooth-operator` branch, with simplifications appropriate for hive-operator. +//! +//! Differences from upstream: +//! - `env_overrides` is `BTreeMap` instead of `EnvVarSet`. +//! - No `cli_overrides_to_vec` helper, `ResourceNames`, or service-account helpers. +//! - The `CommonConfig` (a.k.a. `product_specific_common_config`) does NOT need to +//! implement `Merge`. Hive uses `JavaCommonConfig`, which intentionally does not +//! implement `Merge` because its inner `JvmArgumentOverrides::try_merge` is +//! fallible (regex validation). The `RoleGroupConfig::product_specific_common_config` +//! field here simply carries the role-group level value through. +//! +//! Replace with `stackable_operator::v2::role_utils::*` once upstream relaxes the +//! `Merge` bound. + +use std::collections::BTreeMap; + +use serde::Serialize; +use stackable_operator::{ + config::{ + fragment::{self, FromFragment}, + merge::{Merge, merge}, + }, + k8s_openapi::{DeepMerge, api::core::v1::PodTemplateSpec}, + role_utils::{Role, RoleGroup}, + schemars::JsonSchema, +}; + +/// Hive-friendly view of a validated, merged `RoleGroup`. +#[derive(Clone, Debug, PartialEq)] +pub struct RoleGroupConfig { + pub replicas: u16, + pub config: Config, + pub config_overrides: ConfigOverrides, + pub env_overrides: BTreeMap, + pub cli_overrides: BTreeMap, + pub pod_overrides: PodTemplateSpec, + pub product_specific_common_config: CommonConfig, +} + +/// Merges and validates the `RoleGroup` with the given `role` and `default_config`. +pub fn with_validated_config( + role_group: &RoleGroup, + role: &Role, + default_config: &Config, +) -> Result< + RoleGroupConfig, + fragment::ValidationError, +> +where + ValidatedConfig: FromFragment, + CommonConfig: Clone + Default + JsonSchema + Serialize, + Config: Clone + Merge, + RoleConfig: Default + JsonSchema + Serialize, + ConfigOverrides: Clone + Default + JsonSchema + Merge + Serialize, +{ + let validated_config = validate_config(role_group, role, default_config)?; + Ok(RoleGroupConfig { + replicas: role_group.replicas.unwrap_or(1), + config: validated_config, + config_overrides: merged_config_overrides( + &role.config.config_overrides, + role_group.config.config_overrides.clone(), + ), + env_overrides: merged_env_overrides( + role.config + .env_overrides + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), + role_group + .config + .env_overrides + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), + ), + cli_overrides: merged_cli_overrides( + role.config.cli_overrides.clone(), + role_group.config.cli_overrides.clone(), + ), + pod_overrides: merged_pod_overrides( + role.config.pod_overrides.clone(), + role_group.config.pod_overrides.clone(), + ), + product_specific_common_config: role_group.config.product_specific_common_config.clone(), + }) +} + +fn validate_config( + role_group: &RoleGroup, + role: &Role, + default_config: &Config, +) -> Result +where + ValidatedConfig: FromFragment, + CommonConfig: Default + JsonSchema + Serialize, + Config: Clone + Merge, + RoleConfig: Default + JsonSchema + Serialize, + ConfigOverrides: Default + JsonSchema + Serialize, +{ + role_group.validate_config(role, default_config) +} + +fn merged_config_overrides( + role_config_overrides: &ConfigOverrides, + role_group_config_overrides: ConfigOverrides, +) -> ConfigOverrides +where + ConfigOverrides: Merge, +{ + merge(role_group_config_overrides, role_config_overrides) +} + +fn merged_env_overrides( + role_env_overrides: BTreeMap, + role_group_env_overrides: BTreeMap, +) -> BTreeMap { + let mut merged = role_env_overrides; + merged.extend(role_group_env_overrides); + merged +} + +fn merged_cli_overrides( + role_cli_overrides: BTreeMap, + role_group_cli_overrides: BTreeMap, +) -> BTreeMap { + let mut merged = role_cli_overrides; + merged.extend(role_group_cli_overrides); + merged +} + +fn merged_pod_overrides( + role_pod_overrides: PodTemplateSpec, + role_group_pod_overrides: PodTemplateSpec, +) -> PodTemplateSpec { + let mut merged = role_pod_overrides; + merged.merge_from(role_group_pod_overrides); + merged +} diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 80f00860..4a3b34c4 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -42,6 +42,8 @@ mod config; mod controller; mod crd; mod discovery; +#[allow(dead_code)] // wired up in the validate refactor (a later task) +mod framework; mod kerberos; mod listener; mod operations; From eeeb836a941e9ab8a34e3d47c8c98c6fe3ad842e Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 15:40:35 +0200 Subject: [PATCH 03/18] feat: Vendor Hadoop XML / Java properties writer in framework Replaces product-config's writer module. Lives in framework::writer and renders hive-site.xml (Hadoop XML) and security.properties (Java properties), matching product-config's output. Also scaffolds controller/build with placeholders for the per-file builders. Co-Authored-By: Claude Opus 4.8 (1M context) --- Cargo.lock | 2 + Cargo.toml | 2 + rust/operator-binary/Cargo.toml | 2 + rust/operator-binary/src/controller.rs | 2 + rust/operator-binary/src/controller/build.rs | 4 + .../src/controller/build/config_map.rs | 1 + .../src/controller/build/properties.rs | 5 + .../controller/build/properties/core_site.rs | 1 + .../controller/build/properties/hive_site.rs | 1 + .../build/properties/security_properties.rs | 1 + rust/operator-binary/src/framework.rs | 1 + rust/operator-binary/src/framework/writer.rs | 145 ++++++++++++++++++ 12 files changed, 167 insertions(+) create mode 100644 rust/operator-binary/src/controller/build.rs create mode 100644 rust/operator-binary/src/controller/build/config_map.rs create mode 100644 rust/operator-binary/src/controller/build/properties.rs create mode 100644 rust/operator-binary/src/controller/build/properties/core_site.rs create mode 100644 rust/operator-binary/src/controller/build/properties/hive_site.rs create mode 100644 rust/operator-binary/src/controller/build/properties/security_properties.rs create mode 100644 rust/operator-binary/src/framework/writer.rs diff --git a/Cargo.lock b/Cargo.lock index 4443e37c..ecf2dbd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2919,6 +2919,7 @@ dependencies = [ "fnv", "futures 0.3.32", "indoc", + "java-properties", "pin-project", "product-config", "rstest", @@ -2931,6 +2932,7 @@ dependencies = [ "strum", "tokio", "tracing", + "xml", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 2a306cf7..2a45bd1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ const_format = "0.2" fnv = "1.0" futures = { version = "0.3", features = ["compat"] } indoc = "2.0" +java-properties = "2.0" pin-project = "1.1" rstest = "0.26" semver = "1.0" @@ -30,6 +31,7 @@ snafu = "0.9" strum = { version = "0.28", features = ["derive"] } tokio = { version = "1.52", features = ["full"] } tracing = "0.1" +xml = "1.3" [patch."https://github.com/stackabletech/operator-rs.git"] stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "smooth-operator" } diff --git a/rust/operator-binary/Cargo.toml b/rust/operator-binary/Cargo.toml index a841e2b7..fafcd2ac 100644 --- a/rust/operator-binary/Cargo.toml +++ b/rust/operator-binary/Cargo.toml @@ -18,6 +18,7 @@ const_format.workspace = true fnv.workspace = true futures.workspace = true indoc.workspace = true +java-properties.workspace = true pin-project.workspace = true semver.workspace = true serde.workspace = true @@ -26,6 +27,7 @@ snafu.workspace = true strum.workspace = true tokio.workspace = true tracing.workspace = true +xml.workspace = true [dev-dependencies] rstest.workspace = true diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 6fc44f07..a33ee292 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -2,6 +2,8 @@ mod dereference; mod validate; +#[allow(dead_code)] // wired up in a later task +mod build; use std::{ collections::{BTreeMap, HashMap}, diff --git a/rust/operator-binary/src/controller/build.rs b/rust/operator-binary/src/controller/build.rs new file mode 100644 index 00000000..21024b3f --- /dev/null +++ b/rust/operator-binary/src/controller/build.rs @@ -0,0 +1,4 @@ +//! Builders that turn a `ValidatedCluster` into Kubernetes resources. + +pub mod config_map; +pub mod properties; diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs new file mode 100644 index 00000000..ea4bfda5 --- /dev/null +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -0,0 +1 @@ +//! placeholder — implemented in a later task diff --git a/rust/operator-binary/src/controller/build/properties.rs b/rust/operator-binary/src/controller/build/properties.rs new file mode 100644 index 00000000..2c337160 --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties.rs @@ -0,0 +1,5 @@ +//! Per-file builders for the Hive metastore config files. + +pub mod core_site; +pub mod hive_site; +pub mod security_properties; diff --git a/rust/operator-binary/src/controller/build/properties/core_site.rs b/rust/operator-binary/src/controller/build/properties/core_site.rs new file mode 100644 index 00000000..ea4bfda5 --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -0,0 +1 @@ +//! placeholder — implemented in a later task diff --git a/rust/operator-binary/src/controller/build/properties/hive_site.rs b/rust/operator-binary/src/controller/build/properties/hive_site.rs new file mode 100644 index 00000000..ea4bfda5 --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/hive_site.rs @@ -0,0 +1 @@ +//! placeholder — implemented in a later task diff --git a/rust/operator-binary/src/controller/build/properties/security_properties.rs b/rust/operator-binary/src/controller/build/properties/security_properties.rs new file mode 100644 index 00000000..ea4bfda5 --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/security_properties.rs @@ -0,0 +1 @@ +//! placeholder — implemented in a later task diff --git a/rust/operator-binary/src/framework.rs b/rust/operator-binary/src/framework.rs index 75d7a9cb..19b9d132 100644 --- a/rust/operator-binary/src/framework.rs +++ b/rust/operator-binary/src/framework.rs @@ -11,3 +11,4 @@ //! relaxes the `Merge` bound. pub mod role_utils; +pub mod writer; diff --git a/rust/operator-binary/src/framework/writer.rs b/rust/operator-binary/src/framework/writer.rs new file mode 100644 index 00000000..08250f9f --- /dev/null +++ b/rust/operator-binary/src/framework/writer.rs @@ -0,0 +1,145 @@ +//! Writers for Hadoop XML config files and Java `.properties` files. +//! +//! Vendored from the `product-config` crate's `writer` module so the operator no +//! longer depends on `product-config` for rendering. + +use std::io::Write; + +use java_properties::{PropertiesError, PropertiesWriter}; +use snafu::{ResultExt, Snafu}; +use xml::escape::escape_str_attribute; + +#[derive(Debug, Snafu)] +pub enum PropertiesWriterError { + #[snafu(display("failed to create properties file"))] + Properties { source: PropertiesError }, + + #[snafu(display("failed to convert properties file byte array to UTF-8"))] + FromUtf8 { source: std::string::FromUtf8Error }, +} + +/// Creates a common Java properties file string in the format: +/// `property_1=value_1\nproperty_2=value_2\n`. +pub fn to_java_properties_string<'a, T>(properties: T) -> Result +where + T: Iterator)>, +{ + let mut output = Vec::new(); + write_java_properties(&mut output, properties)?; + String::from_utf8(output).context(FromUtf8Snafu) +} + +/// Writes Java properties to the given writer. A `None` value is written as an +/// empty value (`key=`). +fn write_java_properties<'a, W, T>(writer: W, properties: T) -> Result<(), PropertiesWriterError> +where + W: Write, + T: Iterator)>, +{ + let mut writer = PropertiesWriter::new(writer); + for (k, v) in properties { + let property_value = v.as_deref().unwrap_or_default(); + writer.write(k, property_value).context(PropertiesSnafu)?; + } + writer.flush().context(PropertiesSnafu)?; + Ok(()) +} + +/// Converts properties into a Hadoop configuration XML, including the wrapping +/// `...` elements. Properties with a `None` value +/// are skipped. Keys and values are XML-escaped. +pub fn to_hadoop_xml<'a, T>(properties: T) -> String +where + T: Iterator)>, +{ + let mut snippet = String::new(); + for (k, v) in properties { + let escaped_value = match v { + Some(value) => escape_str_attribute(value), + None => continue, + }; + let escaped_key = escape_str_attribute(k); + snippet.push_str(&format!( + " \n {escaped_key}\n {escaped_value}\n \n" + )); + } + format!("\n\n{snippet}") +} + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + + use super::*; + + fn xml(pairs: &[(&str, Option<&str>)]) -> String { + let map: BTreeMap> = pairs + .iter() + .map(|(k, v)| (k.to_string(), v.map(str::to_string))) + .collect(); + to_hadoop_xml(map.iter()) + } + + fn props(pairs: &[(&str, Option<&str>)]) -> String { + let map: BTreeMap> = pairs + .iter() + .map(|(k, v)| (k.to_string(), v.map(str::to_string))) + .collect(); + to_java_properties_string(map.iter()).unwrap() + } + + #[test] + fn hadoop_xml_wraps_empty_configuration() { + assert_eq!( + xml(&[]), + "\n\n" + ); + } + + #[test] + fn hadoop_xml_renders_single_property() { + assert_eq!( + xml(&[("fs.defaultFS", Some("hdfs://hdfs/"))]), + "\n\n \ + \n fs.defaultFS\n \ + hdfs://hdfs/\n \n" + ); + } + + #[test] + fn hadoop_xml_skips_none_values() { + assert_eq!( + xml(&[("kept", Some("1")), ("dropped", None)]), + "\n\n \ + \n kept\n \ + 1\n \n" + ); + } + + #[test] + fn hadoop_xml_escapes_special_characters() { + let rendered = xml(&[("k", Some("&b"))]); + assert!( + rendered.contains("<a>&b"), + "{rendered}" + ); + } + + #[test] + fn java_properties_renders_key_value() { + assert_eq!(props(&[("a", Some("1")), ("b", Some("2"))]), "a=1\nb=2\n"); + } + + #[test] + fn java_properties_renders_none_as_empty() { + assert_eq!(props(&[("none", None)]), "none=\n"); + } + + #[test] + fn java_properties_escapes_colon_in_value() { + assert_eq!( + props(&[("url", Some("file://this/location/file.abc"))]), + "url=file\\://this/location/file.abc\n" + ); + } +} From 2a3f6f1b5bef59bd9cc41b1083e011c859722f6e Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 15:43:34 +0200 Subject: [PATCH 04/18] feat: Add security.properties builder Co-Authored-By: Claude Opus 4.8 (1M context) --- .../build/properties/security_properties.rs | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/rust/operator-binary/src/controller/build/properties/security_properties.rs b/rust/operator-binary/src/controller/build/properties/security_properties.rs index ea4bfda5..4e477e28 100644 --- a/rust/operator-binary/src/controller/build/properties/security_properties.rs +++ b/rust/operator-binary/src/controller/build/properties/security_properties.rs @@ -1 +1,82 @@ -//! placeholder — implemented in a later task +//! Builder for `security.properties` (the JVM security properties file). +//! +//! Reproduces the product-config behaviour: `networkaddress.cache.ttl` and +//! `networkaddress.cache.negative.ttl` are `required` properties with recommended +//! values, so they are always emitted; user `security.properties` overrides win. + +use std::collections::BTreeMap; + +const NETWORKADDRESS_CACHE_TTL: &str = "networkaddress.cache.ttl"; +const NETWORKADDRESS_CACHE_NEGATIVE_TTL: &str = "networkaddress.cache.negative.ttl"; + +const DEFAULT_NETWORKADDRESS_CACHE_TTL: &str = "30"; +const DEFAULT_NETWORKADDRESS_CACHE_NEGATIVE_TTL: &str = "0"; + +/// Build the `security.properties` key/value pairs. +/// +/// `overrides` are the resolved user overrides for `security.properties` +/// (highest precedence). Values are wrapped in `Some` for the writer. +pub fn build(overrides: BTreeMap) -> BTreeMap> { + let mut props: BTreeMap> = BTreeMap::new(); + + // 1. Defaults (recommended values for the required properties). + props.insert( + NETWORKADDRESS_CACHE_TTL.to_string(), + Some(DEFAULT_NETWORKADDRESS_CACHE_TTL.to_string()), + ); + props.insert( + NETWORKADDRESS_CACHE_NEGATIVE_TTL.to_string(), + Some(DEFAULT_NETWORKADDRESS_CACHE_NEGATIVE_TTL.to_string()), + ); + + // 2. No automatic operator-injected values. + // 3. No merged_config contribution. + // 4. User overrides (highest precedence). + for (k, v) in overrides { + props.insert(k, Some(v)); + } + + props +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn defaults_present_without_overrides() { + let props = build(BTreeMap::new()); + assert_eq!( + props.get("networkaddress.cache.ttl"), + Some(&Some("30".to_string())) + ); + assert_eq!( + props.get("networkaddress.cache.negative.ttl"), + Some(&Some("0".to_string())) + ); + } + + #[test] + fn user_override_wins() { + let overrides = [("networkaddress.cache.ttl".to_string(), "60".to_string())] + .into_iter() + .collect(); + let props = build(overrides); + assert_eq!( + props.get("networkaddress.cache.ttl"), + Some(&Some("60".to_string())) + ); + } + + #[test] + fn extra_user_override_key_is_added() { + let overrides = [("custom.security.prop".to_string(), "x".to_string())] + .into_iter() + .collect(); + let props = build(overrides); + assert_eq!( + props.get("custom.security.prop"), + Some(&Some("x".to_string())) + ); + } +} From 7c07062125433a0402c558713dd88428dbe3ca3a Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 16:01:59 +0200 Subject: [PATCH 05/18] feat: Add hive-site.xml builder preserving product-config output Co-Authored-By: Claude Opus 4.8 (1M context) --- .../controller/build/properties/hive_site.rs | 293 +++++++++++++++++- 1 file changed, 292 insertions(+), 1 deletion(-) diff --git a/rust/operator-binary/src/controller/build/properties/hive_site.rs b/rust/operator-binary/src/controller/build/properties/hive_site.rs index ea4bfda5..243a2731 100644 --- a/rust/operator-binary/src/controller/build/properties/hive_site.rs +++ b/rust/operator-binary/src/controller/build/properties/hive_site.rs @@ -1 +1,292 @@ -//! placeholder — implemented in a later task +//! Builder for `hive-site.xml`. +//! +//! Precedence (matches the pre-product-config-removal behaviour): +//! 1. Defaults: `hive.metastore.port=9083` (required product-config property, default value). +//! 2. Automatic / operator-injected: warehouse dir (hardcoded `/stackable/warehouse`), +//! metrics enabled (`true`), JDBC driver/url/credentials, S3, Kerberos, OPA. +//! 3. Spec: `warehouseDir` from the merged config overrides the hardcoded warehouse dir. +//! 4. User `hive-site.xml` overrides (highest precedence). + +use std::collections::BTreeMap; + +use snafu::{ResultExt, Snafu}; +use stackable_operator::{ + crd::s3, + database_connections::drivers::jdbc::JdbcDatabaseConnectionDetails, + k8s_openapi::api::core::v1::EnvVar, + utils::cluster_info::KubernetesClusterInfo, +}; + +use crate::{ + config::opa::HiveOpaConfig, + crd::{ + MetaStoreConfig, + databases::{MetadataDatabaseConnection, derby_driver_class}, + v1alpha1, + }, + kerberos::kerberos_config_properties, +}; + +const DEFAULT_WAREHOUSE_DIR: &str = "/stackable/warehouse"; +const HIVE_METASTORE_PORT: &str = "hive.metastore.port"; +const DEFAULT_HIVE_METASTORE_PORT: &str = "9083"; + +#[derive(Debug, Snafu)] +pub enum Error { + #[snafu(display("failed to configure S3 connection"))] + ConfigureS3Connection { + source: stackable_operator::crd::s3::v1alpha1::ConnectionError, + }, +} + +type Result = std::result::Result; + +/// Build the `hive-site.xml` key/value pairs. Values are `Option` so the writer +/// can skip unset entries (no `None` is produced here, but the type matches the +/// writer's iterator interface). +#[allow(clippy::too_many_arguments)] +pub fn build( + hive: &v1alpha1::HiveCluster, + hive_namespace: &str, + product_version: &str, + merged_config: &MetaStoreConfig, + database_connection_details: &JdbcDatabaseConnectionDetails, + s3_connection_spec: Option<&s3::v1alpha1::ConnectionSpec>, + hive_opa_config: Option<&HiveOpaConfig>, + cluster_info: &KubernetesClusterInfo, + overrides: BTreeMap, +) -> Result>> { + let mut data: BTreeMap> = BTreeMap::new(); + + // 1. Defaults (required product-config property `hive.metastore.port`). + data.insert( + HIVE_METASTORE_PORT.to_string(), + Some(DEFAULT_HIVE_METASTORE_PORT.to_string()), + ); + + // 2. Automatic / operator-injected. + data.insert( + MetaStoreConfig::METASTORE_WAREHOUSE_DIR.to_string(), + Some(DEFAULT_WAREHOUSE_DIR.to_string()), + ); + data.insert( + MetaStoreConfig::METASTORE_METRICS_ENABLED.to_string(), + Some("true".to_string()), + ); + + // The Derby driver class needs special handling. + let driver = match &hive.spec.cluster_config.metadata_database { + MetadataDatabaseConnection::Derby(_) => derby_driver_class(product_version), + _ => database_connection_details.driver.as_str(), + }; + data.insert( + MetaStoreConfig::CONNECTION_DRIVER_NAME.to_string(), + Some(driver.to_owned()), + ); + data.insert( + MetaStoreConfig::CONNECTION_URL.to_string(), + Some(database_connection_details.connection_url.to_string()), + ); + if let Some(EnvVar { name, .. }) = &database_connection_details.username_env { + data.insert( + MetaStoreConfig::CONNECTION_USER_NAME.to_string(), + Some(format!("${{env:{name}}}")), + ); + } + if let Some(EnvVar { name, .. }) = &database_connection_details.password_env { + data.insert( + MetaStoreConfig::CONNECTION_PASSWORD.to_string(), + Some(format!("${{env:{name}}}")), + ); + } + + if let Some(s3) = s3_connection_spec { + data.insert( + MetaStoreConfig::S3_ENDPOINT.to_string(), + Some(s3.endpoint().context(ConfigureS3ConnectionSnafu)?.to_string()), + ); + data.insert( + MetaStoreConfig::S3_REGION_NAME.to_string(), + Some(s3.region.name.clone()), + ); + if let Some((access_key_file, secret_key_file)) = s3.credentials_mount_paths() { + data.insert( + MetaStoreConfig::S3_ACCESS_KEY.to_string(), + Some(format!("${{file:UTF-8:{access_key_file}}}")), + ); + data.insert( + MetaStoreConfig::S3_SECRET_KEY.to_string(), + Some(format!("${{file:UTF-8:{secret_key_file}}}")), + ); + } + data.insert( + MetaStoreConfig::S3_SSL_ENABLED.to_string(), + Some(s3.tls.uses_tls().to_string()), + ); + data.insert( + MetaStoreConfig::S3_PATH_STYLE_ACCESS.to_string(), + Some((s3.access_style == s3::v1alpha1::S3AccessStyle::Path).to_string()), + ); + } + + for (name, value) in kerberos_config_properties(hive, hive_namespace, cluster_info) { + data.insert(name.to_string(), Some(value.to_string())); + } + + if let Some(opa_config) = hive_opa_config { + data.extend( + opa_config + .as_config(product_version) + .into_iter() + .map(|(k, v)| (k, Some(v))), + ); + } + + // 3. Spec: warehouse dir from the merged CRD config (overrides the default). + if let Some(warehouse_dir) = &merged_config.warehouse_dir { + data.insert( + MetaStoreConfig::METASTORE_WAREHOUSE_DIR.to_string(), + Some(warehouse_dir.clone()), + ); + } + + // 4. User overrides (highest precedence). + for (k, v) in overrides { + data.insert(k, Some(v)); + } + + Ok(data) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn hive_cluster(yaml: &str) -> v1alpha1::HiveCluster { + stackable_operator::utils::yaml_from_str_singleton_map(yaml).expect("valid HiveCluster YAML") + } + + const DERBY_YAML: &str = r#" + apiVersion: hive.stackable.tech/v1alpha1 + kind: HiveCluster + metadata: + name: simple-hive + namespace: default + spec: + image: + productVersion: "4.0.0" + clusterConfig: + metadataDatabase: + derby: {} + metastore: + roleGroups: + default: + replicas: 1 + "#; + + fn cluster_info() -> KubernetesClusterInfo { + KubernetesClusterInfo { + cluster_domain: "cluster.local".parse().expect("valid domain"), + } + } + + fn db_details(hive: &v1alpha1::HiveCluster) -> JdbcDatabaseConnectionDetails { + hive.spec + .cluster_config + .metadata_database + .jdbc_connection_details("METADATA") + .expect("derby connection details") + } + + #[test] + fn defaults_present_for_minimal_derby_cluster() { + let hive = hive_cluster(DERBY_YAML); + let merged = MetaStoreConfig::default(); + let db = db_details(&hive); + + let data = build( + &hive, + "default", + "4.0.0", + &merged, + &db, + None, + None, + &cluster_info(), + BTreeMap::new(), + ) + .expect("build hive-site"); + + assert_eq!( + data.get("hive.metastore.port"), + Some(&Some("9083".to_string())) + ); + assert_eq!( + data.get("hive.metastore.metrics.enabled"), + Some(&Some("true".to_string())) + ); + assert_eq!( + data.get("hive.metastore.warehouse.dir"), + Some(&Some("/stackable/warehouse".to_string())) + ); + assert!(data.contains_key("javax.jdo.option.ConnectionDriverName")); + // No env credentials for an embedded Derby database. + assert!(!data.contains_key("javax.jdo.option.ConnectionUserName")); + } + + #[test] + fn warehouse_dir_spec_overrides_default() { + let hive = hive_cluster(DERBY_YAML); + let merged = MetaStoreConfig { + warehouse_dir: Some("/custom/warehouse".to_string()), + ..MetaStoreConfig::default() + }; + let db = db_details(&hive); + + let data = build( + &hive, + "default", + "4.0.0", + &merged, + &db, + None, + None, + &cluster_info(), + BTreeMap::new(), + ) + .expect("build hive-site"); + + assert_eq!( + data.get("hive.metastore.warehouse.dir"), + Some(&Some("/custom/warehouse".to_string())) + ); + } + + #[test] + fn user_override_wins_over_everything() { + let hive = hive_cluster(DERBY_YAML); + let merged = MetaStoreConfig::default(); + let db = db_details(&hive); + let overrides = [("hive.metastore.port".to_string(), "1234".to_string())] + .into_iter() + .collect(); + + let data = build( + &hive, + "default", + "4.0.0", + &merged, + &db, + None, + None, + &cluster_info(), + overrides, + ) + .expect("build hive-site"); + + assert_eq!( + data.get("hive.metastore.port"), + Some(&Some("1234".to_string())) + ); + } +} From a12527192bc713aacee5ef383061005ea94030af Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 16:07:14 +0200 Subject: [PATCH 06/18] feat: Add core-site.xml builder Co-Authored-By: Claude Opus 4.8 (1M context) --- .../controller/build/properties/core_site.rs | 118 +++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/rust/operator-binary/src/controller/build/properties/core_site.rs b/rust/operator-binary/src/controller/build/properties/core_site.rs index ea4bfda5..fbdfaed0 100644 --- a/rust/operator-binary/src/controller/build/properties/core_site.rs +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -1 +1,117 @@ -//! placeholder — implemented in a later task +//! Builder for `core-site.xml`. +//! +//! Only emitted when Kerberos is enabled and there is no HDFS backend (i.e. S3), +//! in which case `hadoop.security.authentication=kerberos` is required. + +use std::collections::BTreeMap; + +use crate::crd::v1alpha1; + +const HADOOP_SECURITY_AUTHENTICATION: &str = "hadoop.security.authentication"; + +/// Returns the `core-site.xml` properties, or `None` if the file should be omitted. +pub fn build(hive: &v1alpha1::HiveCluster) -> Option>> { + if hive.has_kerberos_enabled() && hive.spec.cluster_config.hdfs.is_none() { + let mut data = BTreeMap::new(); + data.insert( + HADOOP_SECURITY_AUTHENTICATION.to_string(), + Some("kerberos".to_string()), + ); + Some(data) + } else { + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn hive_cluster(yaml: &str) -> v1alpha1::HiveCluster { + stackable_operator::utils::yaml_from_str_singleton_map(yaml).expect("valid HiveCluster YAML") + } + + const NO_KERBEROS_YAML: &str = r#" + apiVersion: hive.stackable.tech/v1alpha1 + kind: HiveCluster + metadata: + name: simple-hive + namespace: default + spec: + image: + productVersion: "4.0.0" + clusterConfig: + metadataDatabase: + derby: {} + metastore: + roleGroups: + default: + replicas: 1 + "#; + + const KERBEROS_S3_YAML: &str = r#" + apiVersion: hive.stackable.tech/v1alpha1 + kind: HiveCluster + metadata: + name: simple-hive + namespace: default + spec: + image: + productVersion: "4.0.0" + clusterConfig: + authentication: + kerberos: + secretClass: kerberos + metadataDatabase: + derby: {} + metastore: + roleGroups: + default: + replicas: 1 + "#; + + const KERBEROS_HDFS_YAML: &str = r#" + apiVersion: hive.stackable.tech/v1alpha1 + kind: HiveCluster + metadata: + name: simple-hive + namespace: default + spec: + image: + productVersion: "4.0.0" + clusterConfig: + authentication: + kerberos: + secretClass: kerberos + metadataDatabase: + derby: {} + hdfs: + configMap: hdfs + metastore: + roleGroups: + default: + replicas: 1 + "#; + + #[test] + fn omitted_without_kerberos() { + let hive = hive_cluster(NO_KERBEROS_YAML); + assert!(build(&hive).is_none()); + } + + #[test] + fn emitted_with_kerberos_and_no_hdfs() { + let hive = hive_cluster(KERBEROS_S3_YAML); + let data = build(&hive).expect("core-site present"); + assert_eq!( + data.get("hadoop.security.authentication"), + Some(&Some("kerberos".to_string())) + ); + } + + #[test] + fn omitted_with_kerberos_but_hdfs_backend() { + let hive = hive_cluster(KERBEROS_HDFS_YAML); + assert!(build(&hive).is_none()); + } +} From f544de285d06e1fd03bfce49d514767b45778bd6 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 16:41:35 +0200 Subject: [PATCH 07/18] refactor!: Replace product-config validation/serialization with typed builders Reshape ValidatedCluster (name, image, cluster_config, role_group_configs) and validate via framework::role_utils::with_validated_config. Build hive-site.xml, security.properties and core-site.xml via dedicated builders + the vendored writer. Switch HiveConfigOverrides to v2 KeyValueConfigOverrides (key-by-key Merge). product-config is now only referenced by the crd Configuration impl. Co-Authored-By: Claude Opus 4.8 (1M context) --- rust/operator-binary/src/controller.rs | 432 +++++------------- .../src/controller/build/config_map.rs | 134 +++++- .../src/controller/build/properties.rs | 14 + .../src/controller/validate.rs | 113 ++--- rust/operator-binary/src/crd/mod.rs | 42 +- rust/operator-binary/src/main.rs | 9 +- 6 files changed, 306 insertions(+), 438 deletions(-) diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index a33ee292..96a5407f 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -1,29 +1,18 @@ //! Ensures that `Pod`s are configured and running for each [`v1alpha1::HiveCluster`] +mod build; mod dereference; mod validate; -#[allow(dead_code)] // wired up in a later task -mod build; -use std::{ - collections::{BTreeMap, HashMap}, - hash::Hasher, - sync::Arc, -}; +use std::{collections::BTreeMap, hash::Hasher, sync::Arc}; use const_format::concatcp; use fnv::FnvHasher; use indoc::formatdoc; -use product_config::{ - ProductConfigManager, - types::PropertyNameKind, - writer::{PropertiesWriterError, to_hadoop_xml, to_java_properties_string}, -}; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ builder::{ self, - configmap::ConfigMapBuilder, meta::ObjectMetaBuilder, pod::{ PodBuilder, @@ -50,8 +39,7 @@ use stackable_operator::{ api::{ apps::v1::{StatefulSet, StatefulSetSpec}, core::v1::{ - ConfigMap, ConfigMapVolumeSource, EmptyDirVolumeSource, EnvVar, Probe, - TCPSocketAction, Volume, + ConfigMapVolumeSource, EmptyDirVolumeSource, Probe, TCPSocketAction, Volume, }, }, apimachinery::pkg::{ @@ -82,7 +70,7 @@ use stackable_operator::{ compute_conditions, operations::ClusterOperationsConditionBuilder, statefulset::StatefulSetConditionBuilder, }, - utils::{COMMON_BASH_TRAP_FUNCTIONS, cluster_info::KubernetesClusterInfo}, + utils::COMMON_BASH_TRAP_FUNCTIONS, }; use strum::EnumDiscriminants; use tracing::warn; @@ -95,23 +83,16 @@ use crate::{ opa::{HiveOpaConfig, OPA_TLS_VOLUME_NAME}, }, crd::{ - APP_NAME, CORE_SITE_XML, Container, HIVE_PORT, HIVE_PORT_NAME, HIVE_SITE_XML, - HiveClusterStatus, HiveRole, JVM_SECURITY_PROPERTIES_FILE, METRICS_PORT, METRICS_PORT_NAME, - MetaStoreConfig, STACKABLE_CONFIG_DIR, STACKABLE_CONFIG_DIR_NAME, + APP_NAME, Container, HIVE_PORT, HIVE_PORT_NAME, HiveClusterStatus, HiveRole, METRICS_PORT, + METRICS_PORT_NAME, MetaStoreConfig, STACKABLE_CONFIG_DIR, STACKABLE_CONFIG_DIR_NAME, STACKABLE_CONFIG_MOUNT_DIR, STACKABLE_CONFIG_MOUNT_DIR_NAME, STACKABLE_LOG_CONFIG_MOUNT_DIR, STACKABLE_LOG_CONFIG_MOUNT_DIR_NAME, STACKABLE_LOG_DIR, - STACKABLE_LOG_DIR_NAME, - databases::{MetadataDatabaseConnection, derby_driver_class}, - v1alpha1, + STACKABLE_LOG_DIR_NAME, v1alpha1, }, discovery::{self}, - kerberos::{ - self, add_kerberos_pod_config, kerberos_config_properties, - kerberos_container_start_commands, - }, + kerberos::{self, add_kerberos_pod_config, kerberos_container_start_commands}, listener::{LISTENER_VOLUME_DIR, LISTENER_VOLUME_NAME, build_role_listener}, operations::{graceful_shutdown::add_graceful_shutdown_config, pdb::add_pdbs}, - product_logging::extend_role_group_config_map, service::{build_rolegroup_headless_service, build_rolegroup_metrics_service}, }; @@ -127,7 +108,6 @@ pub const MAX_HIVE_LOG_FILES_SIZE: MemoryQuantity = MemoryQuantity { pub struct Ctx { pub client: stackable_operator::client::Client, - pub product_config: ProductConfigManager, pub operator_environment: OperatorEnvironmentOptions, } @@ -145,8 +125,8 @@ pub enum Error { }, #[snafu(display("failed to build ConfigMap for {rolegroup}"))] - BuildRoleGroupConfig { - source: stackable_operator::builder::configmap::Error, + BuildRoleGroupConfigMap { + source: build::config_map::Error, rolegroup: RoleGroupRef, }, @@ -233,15 +213,6 @@ pub enum Error { #[snafu(display("internal operator failure"))] InternalOperatorFailure { source: crate::crd::Error }, - #[snafu(display( - "failed to serialize [{JVM_SECURITY_PROPERTIES_FILE}] for {}", - rolegroup - ))] - JvmSecurityPoperties { - source: PropertiesWriterError, - rolegroup: String, - }, - #[snafu(display("failed to create PodDisruptionBudget"))] FailedToCreatePdb { source: crate::operations::pdb::Error, @@ -327,14 +298,31 @@ impl ReconcilerError for Error { } } -/// The validated cluster: proves that product-config validation and config merging -/// succeeded for every role and role group before any resources are created. -/// Placed in the controller so that subsequent steps that reference this struct -/// only depend on the controller. +pub type RoleGroupName = String; + +/// A validated, merged Hive metastore role-group config. +pub type HiveRoleGroupConfig = crate::framework::role_utils::RoleGroupConfig< + MetaStoreConfig, + stackable_operator::role_utils::JavaCommonConfig, + v1alpha1::HiveConfigOverrides, +>; + +/// The validated cluster: the typed, merged result of the validate step. Subsequent +/// build steps consume this struct instead of re-reading the raw CRD. pub struct ValidatedCluster { + /// The validated cluster name. Part of the validated cluster identity (mirrors the + /// shared `v2` framework / trino-operator); consumed as more logic migrates onto + /// `ValidatedCluster`. + #[allow(dead_code)] + pub name: stackable_operator::v2::types::operator::ClusterName, pub image: ResolvedProductImage, - pub role_groups: BTreeMap, pub role_config: Option, + pub cluster_config: ValidatedClusterConfig, + pub role_group_configs: BTreeMap>, +} + +/// Cluster-wide settings resolved during validation and dereferencing. +pub struct ValidatedClusterConfig { pub metadata_database_connection_details: JdbcDatabaseConnectionDetails, pub s3_connection_spec: Option, pub hive_opa_config: Option, @@ -347,13 +335,6 @@ pub struct ValidatedRoleConfig { pub listener_class: String, } -/// Per-rolegroup configuration: the merged CRD config plus the product-config properties. -#[derive(Clone, Debug)] -pub struct ValidatedRoleGroupConfig { - pub merged_config: MetaStoreConfig, - pub product_config_properties: HashMap>, -} - pub async fn reconcile_hive( hive: Arc>, ctx: Arc, @@ -374,7 +355,6 @@ pub async fn reconcile_hive( let validated = validate::validate_cluster( hive, &ctx.operator_environment.image_repository, - &ctx.product_config, dereferenced_objects, ) .context(ValidateSnafu)?; @@ -410,74 +390,71 @@ pub async fn reconcile_hive( let mut ss_cond_builder = StatefulSetConditionBuilder::default(); - for (rolegroup_name, validated_rg_config) in &validated.role_groups { - let rolegroup = hive.metastore_rolegroup_ref(rolegroup_name); + for (hive_role, role_group_configs) in &validated.role_group_configs { + for (rolegroup_name, rg) in role_group_configs { + let rolegroup = hive.metastore_rolegroup_ref(rolegroup_name); - let rg_metrics_service = - build_rolegroup_metrics_service(hive, &validated.image, &rolegroup) - .context(ServiceConfigurationSnafu)?; + let rg_metrics_service = + build_rolegroup_metrics_service(hive, &validated.image, &rolegroup) + .context(ServiceConfigurationSnafu)?; - let rg_headless_service = - build_rolegroup_headless_service(hive, &validated.image, &rolegroup) - .context(ServiceConfigurationSnafu)?; + let rg_headless_service = + build_rolegroup_headless_service(hive, &validated.image, &rolegroup) + .context(ServiceConfigurationSnafu)?; - let rg_configmap = build_metastore_rolegroup_config_map( - hive, - &hive_namespace, - &validated.image, - &rolegroup, - &validated_rg_config.product_config_properties, - &validated.metadata_database_connection_details, - validated.s3_connection_spec.as_ref(), - &validated_rg_config.merged_config, - &client.kubernetes_cluster_info, - validated.hive_opa_config.as_ref(), - )?; - let rg_statefulset = build_metastore_rolegroup_statefulset( - hive, - &HiveRole::MetaStore, - &validated.image, - &rolegroup, - &validated_rg_config.product_config_properties, - &validated.metadata_database_connection_details, - validated.s3_connection_spec.as_ref(), - &validated_rg_config.merged_config, - &rbac_sa.name_any(), - validated.hive_opa_config.as_ref(), - )?; - - cluster_resources - .add(client, rg_metrics_service) - .await - .context(ApplyRoleGroupServiceSnafu { + let rg_configmap = build::config_map::build_metastore_rolegroup_config_map( + hive, + &hive_namespace, + &validated, + &rolegroup, + &client.kubernetes_cluster_info, + ) + .with_context(|_| BuildRoleGroupConfigMapSnafu { rolegroup: rolegroup.clone(), })?; - cluster_resources - .add(client, rg_headless_service) - .await - .context(ApplyRoleGroupServiceSnafu { - rolegroup: rolegroup.clone(), - })?; + let rg_statefulset = build_metastore_rolegroup_statefulset( + hive, + hive_role, + &validated, + &rolegroup, + rg, + &rbac_sa.name_any(), + )?; - cluster_resources - .add(client, rg_configmap) - .await - .context(ApplyRoleGroupConfigSnafu { - rolegroup: rolegroup.clone(), - })?; + cluster_resources + .add(client, rg_metrics_service) + .await + .context(ApplyRoleGroupServiceSnafu { + rolegroup: rolegroup.clone(), + })?; - // Note: The StatefulSet needs to be applied after all ConfigMaps and Secrets it mounts - // to prevent unnecessary Pod restarts. - // See https://github.com/stackabletech/commons-operator/issues/111 for details. - ss_cond_builder.add( cluster_resources - .add(client, rg_statefulset) + .add(client, rg_headless_service) .await - .context(ApplyRoleGroupStatefulSetSnafu { + .context(ApplyRoleGroupServiceSnafu { rolegroup: rolegroup.clone(), - })?, - ); + })?; + + cluster_resources + .add(client, rg_configmap) + .await + .context(ApplyRoleGroupConfigSnafu { + rolegroup: rolegroup.clone(), + })?; + + // Note: The StatefulSet needs to be applied after all ConfigMaps and Secrets it + // mounts to prevent unnecessary Pod restarts. + // See https://github.com/stackabletech/commons-operator/issues/111 for details. + ss_cond_builder.add( + cluster_resources + .add(client, rg_statefulset) + .await + .context(ApplyRoleGroupStatefulSetSnafu { + rolegroup: rolegroup.clone(), + })?, + ); + } } // std's SipHasher is deprecated, and DefaultHasher is unstable across Rust releases. @@ -552,216 +529,25 @@ pub async fn reconcile_hive( Ok(Action::await_change()) } -/// The rolegroup [`ConfigMap`] configures the rolegroup based on the configuration given by the administrator -#[allow(clippy::too_many_arguments)] -fn build_metastore_rolegroup_config_map( - hive: &v1alpha1::HiveCluster, - hive_namespace: &str, - resolved_product_image: &ResolvedProductImage, - rolegroup: &RoleGroupRef, - role_group_config: &HashMap>, - database_connection_details: &JdbcDatabaseConnectionDetails, - s3_connection_spec: Option<&s3::v1alpha1::ConnectionSpec>, - merged_config: &MetaStoreConfig, - cluster_info: &KubernetesClusterInfo, - hive_opa_config: Option<&HiveOpaConfig>, -) -> Result { - let mut hive_site_data = String::new(); - - for (property_name_kind, config) in role_group_config { - match property_name_kind { - PropertyNameKind::File(file_name) if file_name == HIVE_SITE_XML => { - let mut data = BTreeMap::new(); - - data.insert( - MetaStoreConfig::METASTORE_WAREHOUSE_DIR.to_string(), - Some("/stackable/warehouse".to_string()), - ); - - // The Derby driver class needs some special handling - let driver = match &hive.spec.cluster_config.metadata_database { - MetadataDatabaseConnection::Derby(_) => { - derby_driver_class(&resolved_product_image.product_version) - } - _ => database_connection_details.driver.as_str(), - }; - data.insert( - MetaStoreConfig::CONNECTION_DRIVER_NAME.to_string(), - Some(driver.to_owned()), - ); - data.insert( - MetaStoreConfig::CONNECTION_URL.to_string(), - Some(database_connection_details.connection_url.to_string()), - ); - if let Some(EnvVar { - name: username_env_name, - .. - }) = &database_connection_details.username_env - { - data.insert( - MetaStoreConfig::CONNECTION_USER_NAME.to_string(), - Some(format!("${{env:{username_env_name}}}",)), - ); - } - if let Some(EnvVar { - name: password_env_name, - .. - }) = &database_connection_details.password_env - { - data.insert( - MetaStoreConfig::CONNECTION_PASSWORD.to_string(), - Some(format!("${{env:{password_env_name}}}",)), - ); - } - - if let Some(s3) = s3_connection_spec { - data.insert( - MetaStoreConfig::S3_ENDPOINT.to_string(), - Some( - s3.endpoint() - .context(ConfigureS3ConnectionSnafu)? - .to_string(), - ), - ); - - data.insert( - MetaStoreConfig::S3_REGION_NAME.to_string(), - Some(s3.region.name.clone()), - ); - - if let Some((access_key_file, secret_key_file)) = s3.credentials_mount_paths() { - // Will be replaced by config-utils - data.insert( - MetaStoreConfig::S3_ACCESS_KEY.to_string(), - Some(format!("${{file:UTF-8:{access_key_file}}}")), - ); - data.insert( - MetaStoreConfig::S3_SECRET_KEY.to_string(), - Some(format!("${{file:UTF-8:{secret_key_file}}}")), - ); - } - - data.insert( - MetaStoreConfig::S3_SSL_ENABLED.to_string(), - Some(s3.tls.uses_tls().to_string()), - ); - data.insert( - MetaStoreConfig::S3_PATH_STYLE_ACCESS.to_string(), - Some((s3.access_style == s3::v1alpha1::S3AccessStyle::Path).to_string()), - ); - } - - for (property_name, property_value) in - kerberos_config_properties(hive, hive_namespace, cluster_info) - { - data.insert(property_name.to_string(), Some(property_value.to_string())); - } - - // OPA settings - if let Some(opa_config) = hive_opa_config { - data.extend( - opa_config - .as_config(&resolved_product_image.product_version) - .into_iter() - .map(|(k, v)| (k, Some(v))) - .collect::>>(), - ); - } - - // overrides - for (property_name, property_value) in config { - data.insert(property_name.to_string(), Some(property_value.to_string())); - } - - hive_site_data = to_hadoop_xml(data.iter()); - } - _ => {} - } - } - - let jvm_sec_props: BTreeMap> = role_group_config - .get(&PropertyNameKind::File( - JVM_SECURITY_PROPERTIES_FILE.to_string(), - )) - .cloned() - .unwrap_or_default() - .into_iter() - .map(|(k, v)| (k, Some(v))) - .collect(); - - let mut cm_builder = ConfigMapBuilder::new(); - - cm_builder - .metadata( - ObjectMetaBuilder::new() - .name_and_namespace(hive) - .name(rolegroup.object_name()) - .ownerreference_from_resource(hive, None, Some(true)) - .context(ObjectMissingMetadataForOwnerRefSnafu)? - .with_recommended_labels(&build_recommended_labels( - hive, - &resolved_product_image.app_version_label_value, - &rolegroup.role, - &rolegroup.role_group, - )) - .context(MetadataBuildSnafu)? - .build(), - ) - .add_data(HIVE_SITE_XML, hive_site_data) - .add_data( - JVM_SECURITY_PROPERTIES_FILE, - to_java_properties_string(jvm_sec_props.iter()).with_context(|_| { - JvmSecurityPopertiesSnafu { - rolegroup: rolegroup.role_group.clone(), - } - })?, - ); - - if hive.has_kerberos_enabled() && hive.spec.cluster_config.hdfs.is_none() { - // if kerberos is activated but we have no HDFS as backend (i.e. S3) then a core-site.xml is - // needed to set "hadoop.security.authentication" - let mut data = BTreeMap::new(); - data.insert( - "hadoop.security.authentication".to_string(), - Some("kerberos".to_string()), - ); - cm_builder.add_data(CORE_SITE_XML, to_hadoop_xml(data.iter())); - } - - extend_role_group_config_map(rolegroup, &merged_config.logging, &mut cm_builder).context( - InvalidLoggingConfigSnafu { - cm_name: rolegroup.object_name(), - }, - )?; - - cm_builder - .build() - .with_context(|_| BuildRoleGroupConfigSnafu { - rolegroup: rolegroup.clone(), - }) -} - /// The rolegroup [`StatefulSet`] runs the rolegroup, as configured by the administrator. /// /// The [`Pod`](`stackable_operator::k8s_openapi::api::core::v1::Pod`)s are accessible through the /// corresponding [`Service`](`stackable_operator::k8s_openapi::api::core::v1::Service`) (via [`build_rolegroup_headless_service`] and metrics from [`build_rolegroup_metrics_service`]). -#[allow(clippy::too_many_arguments)] fn build_metastore_rolegroup_statefulset( hive: &v1alpha1::HiveCluster, hive_role: &HiveRole, - resolved_product_image: &ResolvedProductImage, + cluster: &ValidatedCluster, rolegroup_ref: &RoleGroupRef, - metastore_config: &HashMap>, - database_connection_details: &JdbcDatabaseConnectionDetails, - s3_connection: Option<&s3::v1alpha1::ConnectionSpec>, - merged_config: &MetaStoreConfig, + rg: &HiveRoleGroupConfig, sa_name: &str, - hive_opa_config: Option<&HiveOpaConfig>, ) -> Result { + let resolved_product_image = &cluster.image; + let database_connection_details = &cluster.cluster_config.metadata_database_connection_details; + let s3_connection = cluster.cluster_config.s3_connection_spec.as_ref(); + let merged_config = &rg.config; + let hive_opa_config = cluster.cluster_config.hive_opa_config.as_ref(); + let role = hive.role(hive_role).context(InternalOperatorFailureSnafu)?; - let rolegroup = hive - .rolegroup(rolegroup_ref) - .context(InternalOperatorFailureSnafu)?; let mut container_builder = ContainerBuilder::new(APP_NAME).context(FailedToCreateHiveContainerSnafu { @@ -784,21 +570,17 @@ fn build_metastore_rolegroup_statefulset( ); database_connection_details.add_to_container(&mut container_builder); - for (property_name_kind, config) in metastore_config { - if property_name_kind == &PropertyNameKind::Env { - // overrides - for (property_name, property_value) in config { - if property_name.is_empty() { - warn!( - property_name, - property_value, - "The env variable had an empty name, not adding it to the container" - ); - continue; - } - container_builder.add_env_var(property_name, property_value); - } + // Environment variable overrides (highest precedence), merged from role and role group. + for (property_name, property_value) in &rg.env_overrides { + if property_name.is_empty() { + warn!( + property_name, + property_value, + "The env variable had an empty name, not adding it to the container" + ); + continue; } + container_builder.add_env_var(property_name, property_value); } let mut pod_builder = PodBuilder::new(); @@ -1085,8 +867,8 @@ fn build_metastore_rolegroup_statefulset( } let mut pod_template = pod_builder.build_template(); - pod_template.merge_from(role.config.pod_overrides.clone()); - pod_template.merge_from(rolegroup.config.pod_overrides.clone()); + // Pod overrides were already merged (role <- role group) during validation. + pod_template.merge_from(rg.pod_overrides.clone()); Ok(StatefulSet { metadata: ObjectMetaBuilder::new() @@ -1100,7 +882,7 @@ fn build_metastore_rolegroup_statefulset( .build(), spec: Some(StatefulSetSpec { pod_management_policy: Some("Parallel".to_string()), - replicas: rolegroup.replicas.map(i32::from), + replicas: Some(i32::from(rg.replicas)), selector: LabelSelector { match_labels: Some( Labels::role_group_selector( diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index ea4bfda5..31a1afc9 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -1 +1,133 @@ -//! placeholder — implemented in a later task +//! Build the per-rolegroup `ConfigMap` for the Hive metastore. + +use snafu::{OptionExt, ResultExt, Snafu}; +use stackable_operator::{ + builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, + k8s_openapi::api::core::v1::ConfigMap, + role_utils::RoleGroupRef, + utils::cluster_info::KubernetesClusterInfo, +}; + +use crate::{ + controller::{ + ValidatedCluster, build_recommended_labels, + build::properties::{core_site, hive_site, resolved_overrides, security_properties}, + }, + crd::{CORE_SITE_XML, HIVE_SITE_XML, HiveRole, JVM_SECURITY_PROPERTIES_FILE, v1alpha1}, + framework::writer::{to_hadoop_xml, to_java_properties_string}, + product_logging::extend_role_group_config_map, +}; + +#[derive(Debug, Snafu)] +pub enum Error { + #[snafu(display("missing rolegroup {role_group} under role metastore"))] + MissingRoleGroup { role_group: String }, + + #[snafu(display("failed to build hive-site.xml"))] + BuildHiveSite { source: hive_site::Error }, + + #[snafu(display("failed to serialize {JVM_SECURITY_PROPERTIES_FILE}"))] + WriteSecurityProperties { + source: crate::framework::writer::PropertiesWriterError, + }, + + #[snafu(display("object is missing metadata to build owner reference"))] + ObjectMissingMetadataForOwnerRef { + source: stackable_operator::builder::meta::Error, + }, + + #[snafu(display("failed to build metadata"))] + MetadataBuild { + source: stackable_operator::builder::meta::Error, + }, + + #[snafu(display("failed to add the logging configuration to the ConfigMap {cm_name}"))] + InvalidLoggingConfig { + source: crate::product_logging::Error, + cm_name: String, + }, + + #[snafu(display("failed to assemble ConfigMap for {rolegroup}"))] + Assemble { + source: stackable_operator::builder::configmap::Error, + rolegroup: RoleGroupRef, + }, +} + +type Result = std::result::Result; + +/// The rolegroup [`ConfigMap`] configures the rolegroup based on the configuration given by the +/// administrator. +pub fn build_metastore_rolegroup_config_map( + hive: &v1alpha1::HiveCluster, + hive_namespace: &str, + cluster: &ValidatedCluster, + rolegroup: &RoleGroupRef, + cluster_info: &KubernetesClusterInfo, +) -> Result { + let rg = cluster + .role_group_configs + .get(&HiveRole::MetaStore) + .and_then(|groups| groups.get(&rolegroup.role_group)) + .with_context(|| MissingRoleGroupSnafu { + role_group: rolegroup.role_group.clone(), + })?; + + // hive-site.xml + let hive_site_overrides = resolved_overrides(rg.config_overrides.hive_site_xml.clone()); + let hive_site_data = hive_site::build( + hive, + hive_namespace, + &cluster.image.product_version, + &rg.config, + &cluster.cluster_config.metadata_database_connection_details, + cluster.cluster_config.s3_connection_spec.as_ref(), + cluster.cluster_config.hive_opa_config.as_ref(), + cluster_info, + hive_site_overrides, + ) + .context(BuildHiveSiteSnafu)?; + + // security.properties + let security_overrides = resolved_overrides(rg.config_overrides.security_properties.clone()); + let security_data = security_properties::build(security_overrides); + + let mut cm_builder = ConfigMapBuilder::new(); + cm_builder + .metadata( + ObjectMetaBuilder::new() + .name_and_namespace(hive) + .name(rolegroup.object_name()) + .ownerreference_from_resource(hive, None, Some(true)) + .context(ObjectMissingMetadataForOwnerRefSnafu)? + .with_recommended_labels(&build_recommended_labels( + hive, + &cluster.image.app_version_label_value, + &rolegroup.role, + &rolegroup.role_group, + )) + .context(MetadataBuildSnafu)? + .build(), + ) + .add_data(HIVE_SITE_XML, to_hadoop_xml(hive_site_data.iter())) + .add_data( + JVM_SECURITY_PROPERTIES_FILE, + to_java_properties_string(security_data.iter()) + .context(WriteSecurityPropertiesSnafu)?, + ); + + // core-site.xml is only required when Kerberos is enabled without an HDFS backend. + if let Some(core_site_data) = core_site::build(hive) { + cm_builder.add_data(CORE_SITE_XML, to_hadoop_xml(core_site_data.iter())); + } + + extend_role_group_config_map(rolegroup, &rg.config.logging, &mut cm_builder).context( + InvalidLoggingConfigSnafu { + cm_name: rolegroup.object_name(), + }, + )?; + + cm_builder.build().with_context(|_| AssembleSnafu { + rolegroup: rolegroup.clone(), + }) +} diff --git a/rust/operator-binary/src/controller/build/properties.rs b/rust/operator-binary/src/controller/build/properties.rs index 2c337160..9de80ec8 100644 --- a/rust/operator-binary/src/controller/build/properties.rs +++ b/rust/operator-binary/src/controller/build/properties.rs @@ -1,5 +1,19 @@ //! Per-file builders for the Hive metastore config files. +use std::collections::BTreeMap; + +use stackable_operator::v2::config_overrides::KeyValueConfigOverrides; + pub mod core_site; pub mod hive_site; pub mod security_properties; + +/// Resolve user-provided key/value overrides into `(key, value)` pairs, dropping +/// entries whose value is unset (`None`). +pub(crate) fn resolved_overrides(overrides: KeyValueConfigOverrides) -> BTreeMap { + overrides + .overrides + .into_iter() + .filter_map(|(key, value)| value.map(|value| (key, value))) + .collect() +} diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index b68e1d7d..0f3f681f 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -1,22 +1,23 @@ -use std::{borrow::Cow, collections::BTreeMap}; +use std::{collections::BTreeMap, str::FromStr}; -use product_config::{ProductConfigManager, types::PropertyNameKind}; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ commons::product_image_selection, - product_config_utils::{transform_all_roles_to_config, validate_all_roles_and_groups_config}, - role_utils::GenericRoleConfig, + kube::ResourceExt as _, + role_utils::{GenericRoleConfig, JavaCommonConfig}, + v2::types::operator::ClusterName, }; use crate::{ controller::{ - CONTAINER_IMAGE_BASE_NAME, ValidatedCluster, ValidatedRoleConfig, ValidatedRoleGroupConfig, - dereference::DereferencedObjects, + CONTAINER_IMAGE_BASE_NAME, HiveRoleGroupConfig, RoleGroupName, ValidatedCluster, + ValidatedClusterConfig, ValidatedRoleConfig, dereference::DereferencedObjects, }, crd::{ - HIVE_SITE_XML, HiveRole, JVM_SECURITY_PROPERTIES_FILE, + HiveRole, MetaStoreConfig, v1alpha1::{self, HiveMetastoreRoleConfig}, }, + framework::role_utils::with_validated_config, }; #[derive(Snafu, Debug)] @@ -29,19 +30,17 @@ pub enum Error { #[snafu(display("object defines no metastore role"))] NoMetaStoreRole, - #[snafu(display("failed to generate product config"))] - GenerateProductConfig { - source: stackable_operator::product_config_utils::Error, + #[snafu(display("invalid cluster name"))] + InvalidClusterName { + source: stackable_operator::v2::macros::attributed_string_type::Error, }, - #[snafu(display("invalid product config"))] - InvalidProductConfig { - source: stackable_operator::product_config_utils::Error, + #[snafu(display("failed to resolve and merge config for role group {role_group}"))] + FailedToResolveConfig { + source: stackable_operator::config::fragment::ValidationError, + role_group: String, }, - #[snafu(display("failed to resolve and merge config for role and role group"))] - FailedToResolveConfig { source: crate::crd::Error }, - #[snafu(display("invalid metadata database connection"))] InvalidMetadataDatabaseConnection { source: stackable_operator::database_connections::Error, @@ -51,10 +50,9 @@ pub enum Error { pub fn validate_cluster( hive: &v1alpha1::HiveCluster, image_repository: &str, - product_config_manager: &ProductConfigManager, dereferenced_objects: DereferencedObjects, ) -> Result { - let resolved_product_image = hive + let image = hive .spec .image .resolve( @@ -64,39 +62,8 @@ pub fn validate_cluster( ) .context(ResolveProductImageSnafu)?; - let role = hive.spec.metastore.as_ref().context(NoMetaStoreRoleSnafu)?; - - let validated_config = validate_all_roles_and_groups_config( - &resolved_product_image.product_version, - &transform_all_roles_to_config( - hive, - &[( - HiveRole::MetaStore.to_string(), - ( - vec![ - PropertyNameKind::Env, - PropertyNameKind::Cli, - PropertyNameKind::File(HIVE_SITE_XML.to_string()), - PropertyNameKind::File(JVM_SECURITY_PROPERTIES_FILE.to_string()), - ], - role.clone(), - ), - )] - .into(), - ) - .context(GenerateProductConfigSnafu)?, - product_config_manager, - false, - false, - ) - .context(InvalidProductConfigSnafu)?; - - let metastore_config = validated_config - .get(&HiveRole::MetaStore.to_string()) - .map(Cow::Borrowed) - .unwrap_or_default(); - let hive_role = HiveRole::MetaStore; + let role = hive.spec.metastore.as_ref().context(NoMetaStoreRoleSnafu)?; let role_config = if let Some(HiveMetastoreRoleConfig { common: GenericRoleConfig { @@ -113,23 +80,26 @@ pub fn validate_cluster( None }; - let mut group_configs = BTreeMap::new(); - for (rolegroup_name, rolegroup_config) in metastore_config.iter() { - let rolegroup = hive.metastore_rolegroup_ref(rolegroup_name); - - let merged_config = hive - .merged_config(&hive_role, &rolegroup) - .context(FailedToResolveConfigSnafu)?; - - group_configs.insert( - rolegroup_name.clone(), - ValidatedRoleGroupConfig { - merged_config, - product_config_properties: rolegroup_config.clone(), - }, - ); + let default_config = MetaStoreConfig::default_config(&hive.name_any(), &hive_role); + + let mut groups: BTreeMap = BTreeMap::new(); + for (rg_name, rg) in &role.role_groups { + let validated_rg = with_validated_config::< + MetaStoreConfig, + JavaCommonConfig, + crate::crd::MetaStoreConfigFragment, + HiveMetastoreRoleConfig, + v1alpha1::HiveConfigOverrides, + >(rg, role, &default_config) + .with_context(|_| FailedToResolveConfigSnafu { + role_group: rg_name.clone(), + })?; + groups.insert(rg_name.clone(), validated_rg); } + let mut role_group_configs = BTreeMap::new(); + role_group_configs.insert(hive_role, groups); + let metadata_database_connection_details = hive .spec .cluster_config @@ -138,11 +108,14 @@ pub fn validate_cluster( .context(InvalidMetadataDatabaseConnectionSnafu)?; Ok(ValidatedCluster { - image: resolved_product_image, - role_groups: group_configs, + name: ClusterName::from_str(&hive.name_any()).context(InvalidClusterNameSnafu)?, + image, role_config, - metadata_database_connection_details, - s3_connection_spec: dereferenced_objects.s3_connection_spec, - hive_opa_config: dereferenced_objects.hive_opa_config, + cluster_config: ValidatedClusterConfig { + metadata_database_connection_details, + s3_connection_spec: dereferenced_objects.s3_connection_spec, + hive_opa_config: dereferenced_objects.hive_opa_config, + }, + role_group_configs, }) } diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 2b046f18..9d5e2b67 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -19,7 +19,7 @@ use stackable_operator::{ fragment::{self, Fragment, ValidationError}, merge::Merge, }, - config_overrides::{KeyValueConfigOverrides, KeyValueOverridesProvider}, + v2::config_overrides::KeyValueConfigOverrides, crd::s3, deep_merger::ObjectOverrides, k8s_openapi::apimachinery::pkg::api::resource::Quantity, @@ -192,22 +192,14 @@ pub mod versioned { pub vector_aggregator_config_map_name: Option, } - #[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] + #[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, Merge, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct HiveConfigOverrides { - #[serde( - default, - rename = "hive-site.xml", - skip_serializing_if = "Option::is_none" - )] - pub hive_site_xml: Option, - - #[serde( - default, - rename = "security.properties", - skip_serializing_if = "Option::is_none" - )] - pub security_properties: Option, + #[serde(default, rename = "hive-site.xml")] + pub hive_site_xml: KeyValueConfigOverrides, + + #[serde(default, rename = "security.properties")] + pub security_properties: KeyValueConfigOverrides, } } @@ -355,24 +347,6 @@ impl v1alpha1::HiveCluster { } } -impl KeyValueOverridesProvider for v1alpha1::HiveConfigOverrides { - fn get_key_value_overrides(&self, file: &str) -> BTreeMap> { - match file { - HIVE_SITE_XML => self - .hive_site_xml - .as_ref() - .map(KeyValueConfigOverrides::as_product_config_overrides) - .unwrap_or_default(), - JVM_SECURITY_PROPERTIES_FILE => self - .security_properties - .as_ref() - .map(KeyValueConfigOverrides::as_product_config_overrides) - .unwrap_or_default(), - _ => BTreeMap::new(), - } - } -} - #[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct HdfsConnection { @@ -509,7 +483,7 @@ impl MetaStoreConfig { pub const S3_SECRET_KEY: &'static str = "fs.s3a.secret.key"; pub const S3_SSL_ENABLED: &'static str = "fs.s3a.connection.ssl.enabled"; - fn default_config(cluster_name: &str, role: &HiveRole) -> MetaStoreConfigFragment { + pub(crate) fn default_config(cluster_name: &str, role: &HiveRole) -> MetaStoreConfigFragment { MetaStoreConfigFragment { warehouse_dir: None, resources: ResourcesFragment { diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 4a3b34c4..66726e2c 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -42,7 +42,6 @@ mod config; mod controller; mod crd; mod discovery; -#[allow(dead_code)] // wired up in the validate refactor (a later task) mod framework; mod kerberos; mod listener; @@ -73,7 +72,7 @@ async fn main() -> anyhow::Result<()> { Command::Run(RunArguments { operator_environment, watch_namespace, - product_config, + product_config: _, maintenance, common, }) => { @@ -120,11 +119,6 @@ async fn main() -> anyhow::Result<()> { .run(sigterm_watcher.handle()) .map_err(|err| anyhow!(err).context("failed to run webhook server")); - let product_config = product_config.load(&[ - "deploy/config-spec/properties.yaml", - "/etc/stackable/hive-operator/config-spec/properties.yaml", - ])?; - let event_recorder = Arc::new(Recorder::new( client.as_kube_client(), Reporter { @@ -169,7 +163,6 @@ async fn main() -> anyhow::Result<()> { Arc::new(controller::Ctx { client: client.clone(), operator_environment, - product_config, }), ) // We can let the reporting happen in the background From 0bf8d5577f957dd66322ff41a4befec597fe76a3 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 17:02:42 +0200 Subject: [PATCH 08/18] chore!: Drop the direct product-config dependency Remove the Configuration impl for MetaStoreConfigFragment and the product-config crate from the workspace. product-config now only appears transitively via stackable-operator. The deploy/config-spec packaging is left in place to mirror trino-operator (it is operator-templating-managed infrastructure). Co-Authored-By: Claude Opus 4.8 (1M context) --- Cargo.lock | 1 - Cargo.toml | 1 - rust/operator-binary/Cargo.toml | 1 - rust/operator-binary/src/crd/mod.rs | 46 ----------------------------- 4 files changed, 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ecf2dbd2..d2a0549e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2921,7 +2921,6 @@ dependencies = [ "indoc", "java-properties", "pin-project", - "product-config", "rstest", "semver", "serde", diff --git a/Cargo.toml b/Cargo.toml index 2a45bd1e..860878d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ edition = "2021" repository = "https://github.com/stackabletech/hive-operator" [workspace.dependencies] -product-config = { git = "https://github.com/stackabletech/product-config.git", tag = "0.8.0" } stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.111.0", features = ["crds", "webhook"] } anyhow = "1.0" diff --git a/rust/operator-binary/Cargo.toml b/rust/operator-binary/Cargo.toml index fafcd2ac..8583dedd 100644 --- a/rust/operator-binary/Cargo.toml +++ b/rust/operator-binary/Cargo.toml @@ -9,7 +9,6 @@ repository.workspace = true publish = false [dependencies] -product-config.workspace = true stackable-operator.workspace = true anyhow.workspace = true diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 9d5e2b67..d6e1443c 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -24,7 +24,6 @@ use stackable_operator::{ deep_merger::ObjectOverrides, k8s_openapi::apimachinery::pkg::api::resource::Quantity, kube::{CustomResource, ResourceExt, runtime::reflector::ObjectRef}, - product_config_utils::{self, Configuration}, product_logging::{self, spec::Logging}, role_utils::{GenericRoleConfig, JavaCommonConfig, Role, RoleGroup, RoleGroupRef}, schemars::{self, JsonSchema}, @@ -510,51 +509,6 @@ impl MetaStoreConfig { } } -impl Configuration for MetaStoreConfigFragment { - type Configurable = v1alpha1::HiveCluster; - - fn compute_env( - &self, - _hive: &Self::Configurable, - _role_name: &str, - ) -> Result>, product_config_utils::Error> { - // Well product-config strikes again... - Ok(BTreeMap::new()) - } - - fn compute_cli( - &self, - _hive: &Self::Configurable, - _role_name: &str, - ) -> Result>, product_config_utils::Error> { - Ok(BTreeMap::new()) - } - - fn compute_files( - &self, - _hive: &Self::Configurable, - _role_name: &str, - file: &str, - ) -> Result>, product_config_utils::Error> { - let mut result = BTreeMap::new(); - - if file == HIVE_SITE_XML { - if let Some(warehouse_dir) = &self.warehouse_dir { - result.insert( - MetaStoreConfig::METASTORE_WAREHOUSE_DIR.to_string(), - Some(warehouse_dir.to_string()), - ); - } - result.insert( - MetaStoreConfig::METASTORE_METRICS_ENABLED.to_string(), - Some("true".to_string()), - ); - } - - Ok(result) - } -} - #[derive(Clone, Default, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct HiveClusterStatus { From 1f10eca58c7b62da82262a8b1a5db014a9b9713b Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 17:05:25 +0200 Subject: [PATCH 09/18] chore: Apply rustfmt and add CHANGELOG entry for product-config removal Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 1 + rust/operator-binary/src/controller.rs | 9 ++++----- .../src/controller/build/config_map.rs | 3 ++- .../src/controller/build/properties/core_site.rs | 3 ++- .../src/controller/build/properties/hive_site.rs | 15 +++++++++------ rust/operator-binary/src/crd/mod.rs | 2 +- 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e72448a2..424e049f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. This struct is consistent between different CRDs, so that you can easily copy/paste it between stacklets. Read on the [Hive database documentation](https://docs.stackable.tech/home/nightly/hive/usage-guide/database-driver) for details ([#674]). - Internal operator refactoring: introduce dereference() and validate() steps in the reconciler ([#707]). +- Remove the direct `product-config` dependency; `hive-site.xml`, `security.properties` and `core-site.xml` are now rendered by typed Rust builders. Switch `stackable-operator` to the `smooth-operator` branch and adopt its shared `v2::` framework ([#XXX]). - test: Bump vector-aggregator to 0.55.0, replace /graphql call with gRPC call ([#713]). - Deprecated support for `4.0.1` ([#711]). diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 96a5407f..ee046631 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -436,12 +436,11 @@ pub async fn reconcile_hive( rolegroup: rolegroup.clone(), })?; - cluster_resources - .add(client, rg_configmap) - .await - .context(ApplyRoleGroupConfigSnafu { + cluster_resources.add(client, rg_configmap).await.context( + ApplyRoleGroupConfigSnafu { rolegroup: rolegroup.clone(), - })?; + }, + )?; // Note: The StatefulSet needs to be applied after all ConfigMaps and Secrets it // mounts to prevent unnecessary Pod restarts. diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index 31a1afc9..8f447993 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -10,8 +10,9 @@ use stackable_operator::{ use crate::{ controller::{ - ValidatedCluster, build_recommended_labels, + ValidatedCluster, build::properties::{core_site, hive_site, resolved_overrides, security_properties}, + build_recommended_labels, }, crd::{CORE_SITE_XML, HIVE_SITE_XML, HiveRole, JVM_SECURITY_PROPERTIES_FILE, v1alpha1}, framework::writer::{to_hadoop_xml, to_java_properties_string}, diff --git a/rust/operator-binary/src/controller/build/properties/core_site.rs b/rust/operator-binary/src/controller/build/properties/core_site.rs index fbdfaed0..b96a1e02 100644 --- a/rust/operator-binary/src/controller/build/properties/core_site.rs +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -28,7 +28,8 @@ mod tests { use super::*; fn hive_cluster(yaml: &str) -> v1alpha1::HiveCluster { - stackable_operator::utils::yaml_from_str_singleton_map(yaml).expect("valid HiveCluster YAML") + stackable_operator::utils::yaml_from_str_singleton_map(yaml) + .expect("valid HiveCluster YAML") } const NO_KERBEROS_YAML: &str = r#" diff --git a/rust/operator-binary/src/controller/build/properties/hive_site.rs b/rust/operator-binary/src/controller/build/properties/hive_site.rs index 243a2731..4c7e77b3 100644 --- a/rust/operator-binary/src/controller/build/properties/hive_site.rs +++ b/rust/operator-binary/src/controller/build/properties/hive_site.rs @@ -11,10 +11,8 @@ use std::collections::BTreeMap; use snafu::{ResultExt, Snafu}; use stackable_operator::{ - crd::s3, - database_connections::drivers::jdbc::JdbcDatabaseConnectionDetails, - k8s_openapi::api::core::v1::EnvVar, - utils::cluster_info::KubernetesClusterInfo, + crd::s3, database_connections::drivers::jdbc::JdbcDatabaseConnectionDetails, + k8s_openapi::api::core::v1::EnvVar, utils::cluster_info::KubernetesClusterInfo, }; use crate::{ @@ -103,7 +101,11 @@ pub fn build( if let Some(s3) = s3_connection_spec { data.insert( MetaStoreConfig::S3_ENDPOINT.to_string(), - Some(s3.endpoint().context(ConfigureS3ConnectionSnafu)?.to_string()), + Some( + s3.endpoint() + .context(ConfigureS3ConnectionSnafu)? + .to_string(), + ), ); data.insert( MetaStoreConfig::S3_REGION_NAME.to_string(), @@ -163,7 +165,8 @@ mod tests { use super::*; fn hive_cluster(yaml: &str) -> v1alpha1::HiveCluster { - stackable_operator::utils::yaml_from_str_singleton_map(yaml).expect("valid HiveCluster YAML") + stackable_operator::utils::yaml_from_str_singleton_map(yaml) + .expect("valid HiveCluster YAML") } const DERBY_YAML: &str = r#" diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index d6e1443c..0198f228 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -19,7 +19,6 @@ use stackable_operator::{ fragment::{self, Fragment, ValidationError}, merge::Merge, }, - v2::config_overrides::KeyValueConfigOverrides, crd::s3, deep_merger::ObjectOverrides, k8s_openapi::apimachinery::pkg::api::resource::Quantity, @@ -30,6 +29,7 @@ use stackable_operator::{ shared::time::Duration, status::condition::{ClusterCondition, HasStatusCondition}, utils::cluster_info::KubernetesClusterInfo, + v2::config_overrides::KeyValueConfigOverrides, versioned::versioned, }; use strum::{Display, EnumIter, EnumString, IntoEnumIterator}; From 8f6ee27f0b1565d4667a3d5b777c0fb6293da00b Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 19:13:25 +0200 Subject: [PATCH 10/18] refactor: Decouple config-file builders from the HiveCluster spec Resolve the JDBC driver, Kerberos hive-site entries and the core-site decision into ValidatedClusterConfig during validation, so hive_site/core_site builders consume only ValidatedClusterConfig. config_map keeps an explicit `owner: &HiveCluster` solely for the ObjectMeta owner reference. Rename the reconcile binding `validated` -> `validated_cluster`. Co-Authored-By: Claude Opus 4.8 (1M context) --- rust/operator-binary/src/controller.rs | 32 +++-- .../src/controller/build/config_map.rs | 20 +-- .../src/controller/build/properties.rs | 56 ++++++++ .../controller/build/properties/core_site.rs | 98 ++----------- .../controller/build/properties/hive_site.rs | 131 +++--------------- .../src/controller/validate.rs | 27 ++++ 6 files changed, 146 insertions(+), 218 deletions(-) diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index ee046631..943ad82d 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -322,10 +322,20 @@ pub struct ValidatedCluster { } /// Cluster-wide settings resolved during validation and dereferencing. +/// +/// Everything the config-file builders need is resolved here so they never have to +/// read the raw [`v1alpha1::HiveCluster`] spec. pub struct ValidatedClusterConfig { pub metadata_database_connection_details: JdbcDatabaseConnectionDetails, + /// The resolved JDBC driver class (Derby version special-casing already applied). + pub connection_driver: String, pub s3_connection_spec: Option, pub hive_opa_config: Option, + /// Kerberos-related `hive-site.xml` entries (empty when Kerberos is disabled). + pub kerberos_config: BTreeMap, + /// Whether a `core-site.xml` with `hadoop.security.authentication=kerberos` is + /// required (Kerberos enabled and no HDFS backend). + pub needs_kerberos_core_site: bool, } /// Per-role configuration extracted during validation. @@ -352,9 +362,11 @@ pub async fn reconcile_hive( .await .context(DereferenceSnafu)?; - let validated = validate::validate_cluster( + let validated_cluster = validate::validate_cluster( hive, &ctx.operator_environment.image_repository, + &hive_namespace, + &client.kubernetes_cluster_info, dereferenced_objects, ) .context(ValidateSnafu)?; @@ -390,24 +402,22 @@ pub async fn reconcile_hive( let mut ss_cond_builder = StatefulSetConditionBuilder::default(); - for (hive_role, role_group_configs) in &validated.role_group_configs { + for (hive_role, role_group_configs) in &validated_cluster.role_group_configs { for (rolegroup_name, rg) in role_group_configs { let rolegroup = hive.metastore_rolegroup_ref(rolegroup_name); let rg_metrics_service = - build_rolegroup_metrics_service(hive, &validated.image, &rolegroup) + build_rolegroup_metrics_service(hive, &validated_cluster.image, &rolegroup) .context(ServiceConfigurationSnafu)?; let rg_headless_service = - build_rolegroup_headless_service(hive, &validated.image, &rolegroup) + build_rolegroup_headless_service(hive, &validated_cluster.image, &rolegroup) .context(ServiceConfigurationSnafu)?; let rg_configmap = build::config_map::build_metastore_rolegroup_config_map( hive, - &hive_namespace, - &validated, + &validated_cluster, &rolegroup, - &client.kubernetes_cluster_info, ) .with_context(|_| BuildRoleGroupConfigMapSnafu { rolegroup: rolegroup.clone(), @@ -416,7 +426,7 @@ pub async fn reconcile_hive( let rg_statefulset = build_metastore_rolegroup_statefulset( hive, hive_role, - &validated, + &validated_cluster, &rolegroup, rg, &rbac_sa.name_any(), @@ -460,7 +470,7 @@ pub async fn reconcile_hive( // We don't /need/ stability, but it's still nice to avoid spurious changes where possible. let mut discovery_hash = FnvHasher::with_key(0); - if let Some(role_config) = validated.role_config { + if let Some(role_config) = validated_cluster.role_config { add_pdbs( &role_config.pdb, hive, @@ -473,7 +483,7 @@ pub async fn reconcile_hive( let role_listener: Listener = build_role_listener( hive, - &validated.image, + &validated_cluster.image, &HiveRole::MetaStore, &role_config.listener_class, ) @@ -488,7 +498,7 @@ pub async fn reconcile_hive( hive, hive, HiveRole::MetaStore, - &validated.image, + &validated_cluster.image, None, listener, ) diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index 8f447993..5b07edb1 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -5,7 +5,6 @@ use stackable_operator::{ builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, k8s_openapi::api::core::v1::ConfigMap, role_utils::RoleGroupRef, - utils::cluster_info::KubernetesClusterInfo, }; use crate::{ @@ -60,11 +59,9 @@ type Result = std::result::Result; /// The rolegroup [`ConfigMap`] configures the rolegroup based on the configuration given by the /// administrator. pub fn build_metastore_rolegroup_config_map( - hive: &v1alpha1::HiveCluster, - hive_namespace: &str, + owner: &v1alpha1::HiveCluster, cluster: &ValidatedCluster, rolegroup: &RoleGroupRef, - cluster_info: &KubernetesClusterInfo, ) -> Result { let rg = cluster .role_group_configs @@ -77,14 +74,9 @@ pub fn build_metastore_rolegroup_config_map( // hive-site.xml let hive_site_overrides = resolved_overrides(rg.config_overrides.hive_site_xml.clone()); let hive_site_data = hive_site::build( - hive, - hive_namespace, + &cluster.cluster_config, &cluster.image.product_version, &rg.config, - &cluster.cluster_config.metadata_database_connection_details, - cluster.cluster_config.s3_connection_spec.as_ref(), - cluster.cluster_config.hive_opa_config.as_ref(), - cluster_info, hive_site_overrides, ) .context(BuildHiveSiteSnafu)?; @@ -97,12 +89,12 @@ pub fn build_metastore_rolegroup_config_map( cm_builder .metadata( ObjectMetaBuilder::new() - .name_and_namespace(hive) + .name_and_namespace(owner) .name(rolegroup.object_name()) - .ownerreference_from_resource(hive, None, Some(true)) + .ownerreference_from_resource(owner, None, Some(true)) .context(ObjectMissingMetadataForOwnerRefSnafu)? .with_recommended_labels(&build_recommended_labels( - hive, + owner, &cluster.image.app_version_label_value, &rolegroup.role, &rolegroup.role_group, @@ -118,7 +110,7 @@ pub fn build_metastore_rolegroup_config_map( ); // core-site.xml is only required when Kerberos is enabled without an HDFS backend. - if let Some(core_site_data) = core_site::build(hive) { + if let Some(core_site_data) = core_site::build(&cluster.cluster_config) { cm_builder.add_data(CORE_SITE_XML, to_hadoop_xml(core_site_data.iter())); } diff --git a/rust/operator-binary/src/controller/build/properties.rs b/rust/operator-binary/src/controller/build/properties.rs index 9de80ec8..a027c11e 100644 --- a/rust/operator-binary/src/controller/build/properties.rs +++ b/rust/operator-binary/src/controller/build/properties.rs @@ -17,3 +17,59 @@ pub(crate) fn resolved_overrides(overrides: KeyValueConfigOverrides) -> BTreeMap .filter_map(|(key, value)| value.map(|value| (key, value))) .collect() } + +#[cfg(test)] +pub(crate) mod test_support { + use std::collections::BTreeMap; + + use crate::{ + controller::ValidatedClusterConfig, + crd::{ + databases::{MetadataDatabaseConnection, derby_driver_class}, + v1alpha1, + }, + }; + + pub const DERBY_YAML: &str = r#" + apiVersion: hive.stackable.tech/v1alpha1 + kind: HiveCluster + metadata: + name: simple-hive + namespace: default + spec: + image: + productVersion: "4.0.0" + clusterConfig: + metadataDatabase: + derby: {} + metastore: + roleGroups: + default: + replicas: 1 + "#; + + /// Build a minimal Derby-backed [`ValidatedClusterConfig`] for builder tests. + pub fn derby_cluster_config() -> ValidatedClusterConfig { + let hive: v1alpha1::HiveCluster = + stackable_operator::utils::yaml_from_str_singleton_map(DERBY_YAML) + .expect("valid HiveCluster YAML"); + let metadata_database_connection_details = hive + .spec + .cluster_config + .metadata_database + .jdbc_connection_details("METADATA") + .expect("derby connection details"); + let connection_driver = match &hive.spec.cluster_config.metadata_database { + MetadataDatabaseConnection::Derby(_) => derby_driver_class("4.0.0").to_owned(), + _ => metadata_database_connection_details.driver.clone(), + }; + ValidatedClusterConfig { + metadata_database_connection_details, + connection_driver, + s3_connection_spec: None, + hive_opa_config: None, + kerberos_config: BTreeMap::new(), + needs_kerberos_core_site: false, + } + } +} diff --git a/rust/operator-binary/src/controller/build/properties/core_site.rs b/rust/operator-binary/src/controller/build/properties/core_site.rs index b96a1e02..0d33f7de 100644 --- a/rust/operator-binary/src/controller/build/properties/core_site.rs +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -1,17 +1,18 @@ //! Builder for `core-site.xml`. //! -//! Only emitted when Kerberos is enabled and there is no HDFS backend (i.e. S3), -//! in which case `hadoop.security.authentication=kerberos` is required. +//! Only emitted when Kerberos is enabled without an HDFS backend (resolved during +//! validation as [`ValidatedClusterConfig::needs_kerberos_core_site`]), in which case +//! `hadoop.security.authentication=kerberos` is required. use std::collections::BTreeMap; -use crate::crd::v1alpha1; +use crate::controller::ValidatedClusterConfig; const HADOOP_SECURITY_AUTHENTICATION: &str = "hadoop.security.authentication"; /// Returns the `core-site.xml` properties, or `None` if the file should be omitted. -pub fn build(hive: &v1alpha1::HiveCluster) -> Option>> { - if hive.has_kerberos_enabled() && hive.spec.cluster_config.hdfs.is_none() { +pub fn build(cluster_config: &ValidatedClusterConfig) -> Option>> { + if cluster_config.needs_kerberos_core_site { let mut data = BTreeMap::new(); data.insert( HADOOP_SECURITY_AUTHENTICATION.to_string(), @@ -26,93 +27,22 @@ pub fn build(hive: &v1alpha1::HiveCluster) -> Option v1alpha1::HiveCluster { - stackable_operator::utils::yaml_from_str_singleton_map(yaml) - .expect("valid HiveCluster YAML") - } - - const NO_KERBEROS_YAML: &str = r#" - apiVersion: hive.stackable.tech/v1alpha1 - kind: HiveCluster - metadata: - name: simple-hive - namespace: default - spec: - image: - productVersion: "4.0.0" - clusterConfig: - metadataDatabase: - derby: {} - metastore: - roleGroups: - default: - replicas: 1 - "#; - - const KERBEROS_S3_YAML: &str = r#" - apiVersion: hive.stackable.tech/v1alpha1 - kind: HiveCluster - metadata: - name: simple-hive - namespace: default - spec: - image: - productVersion: "4.0.0" - clusterConfig: - authentication: - kerberos: - secretClass: kerberos - metadataDatabase: - derby: {} - metastore: - roleGroups: - default: - replicas: 1 - "#; - - const KERBEROS_HDFS_YAML: &str = r#" - apiVersion: hive.stackable.tech/v1alpha1 - kind: HiveCluster - metadata: - name: simple-hive - namespace: default - spec: - image: - productVersion: "4.0.0" - clusterConfig: - authentication: - kerberos: - secretClass: kerberos - metadataDatabase: - derby: {} - hdfs: - configMap: hdfs - metastore: - roleGroups: - default: - replicas: 1 - "#; + use crate::controller::build::properties::test_support::derby_cluster_config; #[test] - fn omitted_without_kerberos() { - let hive = hive_cluster(NO_KERBEROS_YAML); - assert!(build(&hive).is_none()); + fn omitted_when_not_required() { + let cluster_config = derby_cluster_config(); + assert!(build(&cluster_config).is_none()); } #[test] - fn emitted_with_kerberos_and_no_hdfs() { - let hive = hive_cluster(KERBEROS_S3_YAML); - let data = build(&hive).expect("core-site present"); + fn emitted_when_required() { + let mut cluster_config = derby_cluster_config(); + cluster_config.needs_kerberos_core_site = true; + let data = build(&cluster_config).expect("core-site present"); assert_eq!( data.get("hadoop.security.authentication"), Some(&Some("kerberos".to_string())) ); } - - #[test] - fn omitted_with_kerberos_but_hdfs_backend() { - let hive = hive_cluster(KERBEROS_HDFS_YAML); - assert!(build(&hive).is_none()); - } } diff --git a/rust/operator-binary/src/controller/build/properties/hive_site.rs b/rust/operator-binary/src/controller/build/properties/hive_site.rs index 4c7e77b3..5d4ef763 100644 --- a/rust/operator-binary/src/controller/build/properties/hive_site.rs +++ b/rust/operator-binary/src/controller/build/properties/hive_site.rs @@ -6,24 +6,16 @@ //! metrics enabled (`true`), JDBC driver/url/credentials, S3, Kerberos, OPA. //! 3. Spec: `warehouseDir` from the merged config overrides the hardcoded warehouse dir. //! 4. User `hive-site.xml` overrides (highest precedence). +//! +//! All inputs are read from the validated [`ValidatedClusterConfig`]; this builder never +//! touches the raw `HiveCluster` spec. use std::collections::BTreeMap; use snafu::{ResultExt, Snafu}; -use stackable_operator::{ - crd::s3, database_connections::drivers::jdbc::JdbcDatabaseConnectionDetails, - k8s_openapi::api::core::v1::EnvVar, utils::cluster_info::KubernetesClusterInfo, -}; +use stackable_operator::{crd::s3, k8s_openapi::api::core::v1::EnvVar}; -use crate::{ - config::opa::HiveOpaConfig, - crd::{ - MetaStoreConfig, - databases::{MetadataDatabaseConnection, derby_driver_class}, - v1alpha1, - }, - kerberos::kerberos_config_properties, -}; +use crate::{controller::ValidatedClusterConfig, crd::MetaStoreConfig}; const DEFAULT_WAREHOUSE_DIR: &str = "/stackable/warehouse"; const HIVE_METASTORE_PORT: &str = "hive.metastore.port"; @@ -42,18 +34,13 @@ type Result = std::result::Result; /// Build the `hive-site.xml` key/value pairs. Values are `Option` so the writer /// can skip unset entries (no `None` is produced here, but the type matches the /// writer's iterator interface). -#[allow(clippy::too_many_arguments)] pub fn build( - hive: &v1alpha1::HiveCluster, - hive_namespace: &str, + cluster_config: &ValidatedClusterConfig, product_version: &str, merged_config: &MetaStoreConfig, - database_connection_details: &JdbcDatabaseConnectionDetails, - s3_connection_spec: Option<&s3::v1alpha1::ConnectionSpec>, - hive_opa_config: Option<&HiveOpaConfig>, - cluster_info: &KubernetesClusterInfo, overrides: BTreeMap, ) -> Result>> { + let database_connection_details = &cluster_config.metadata_database_connection_details; let mut data: BTreeMap> = BTreeMap::new(); // 1. Defaults (required product-config property `hive.metastore.port`). @@ -72,14 +59,9 @@ pub fn build( Some("true".to_string()), ); - // The Derby driver class needs special handling. - let driver = match &hive.spec.cluster_config.metadata_database { - MetadataDatabaseConnection::Derby(_) => derby_driver_class(product_version), - _ => database_connection_details.driver.as_str(), - }; data.insert( MetaStoreConfig::CONNECTION_DRIVER_NAME.to_string(), - Some(driver.to_owned()), + Some(cluster_config.connection_driver.clone()), ); data.insert( MetaStoreConfig::CONNECTION_URL.to_string(), @@ -98,7 +80,7 @@ pub fn build( ); } - if let Some(s3) = s3_connection_spec { + if let Some(s3) = cluster_config.s3_connection_spec.as_ref() { data.insert( MetaStoreConfig::S3_ENDPOINT.to_string(), Some( @@ -131,11 +113,12 @@ pub fn build( ); } - for (name, value) in kerberos_config_properties(hive, hive_namespace, cluster_info) { - data.insert(name.to_string(), Some(value.to_string())); + // Kerberos entries (resolved during validation; empty when Kerberos is disabled). + for (name, value) in &cluster_config.kerberos_config { + data.insert(name.clone(), Some(value.clone())); } - if let Some(opa_config) = hive_opa_config { + if let Some(opa_config) = cluster_config.hive_opa_config.as_ref() { data.extend( opa_config .as_config(product_version) @@ -163,62 +146,15 @@ pub fn build( #[cfg(test)] mod tests { use super::*; - - fn hive_cluster(yaml: &str) -> v1alpha1::HiveCluster { - stackable_operator::utils::yaml_from_str_singleton_map(yaml) - .expect("valid HiveCluster YAML") - } - - const DERBY_YAML: &str = r#" - apiVersion: hive.stackable.tech/v1alpha1 - kind: HiveCluster - metadata: - name: simple-hive - namespace: default - spec: - image: - productVersion: "4.0.0" - clusterConfig: - metadataDatabase: - derby: {} - metastore: - roleGroups: - default: - replicas: 1 - "#; - - fn cluster_info() -> KubernetesClusterInfo { - KubernetesClusterInfo { - cluster_domain: "cluster.local".parse().expect("valid domain"), - } - } - - fn db_details(hive: &v1alpha1::HiveCluster) -> JdbcDatabaseConnectionDetails { - hive.spec - .cluster_config - .metadata_database - .jdbc_connection_details("METADATA") - .expect("derby connection details") - } + use crate::controller::build::properties::test_support::derby_cluster_config; #[test] fn defaults_present_for_minimal_derby_cluster() { - let hive = hive_cluster(DERBY_YAML); + let cluster_config = derby_cluster_config(); let merged = MetaStoreConfig::default(); - let db = db_details(&hive); - let data = build( - &hive, - "default", - "4.0.0", - &merged, - &db, - None, - None, - &cluster_info(), - BTreeMap::new(), - ) - .expect("build hive-site"); + let data = + build(&cluster_config, "4.0.0", &merged, BTreeMap::new()).expect("build hive-site"); assert_eq!( data.get("hive.metastore.port"), @@ -239,25 +175,14 @@ mod tests { #[test] fn warehouse_dir_spec_overrides_default() { - let hive = hive_cluster(DERBY_YAML); + let cluster_config = derby_cluster_config(); let merged = MetaStoreConfig { warehouse_dir: Some("/custom/warehouse".to_string()), ..MetaStoreConfig::default() }; - let db = db_details(&hive); - let data = build( - &hive, - "default", - "4.0.0", - &merged, - &db, - None, - None, - &cluster_info(), - BTreeMap::new(), - ) - .expect("build hive-site"); + let data = + build(&cluster_config, "4.0.0", &merged, BTreeMap::new()).expect("build hive-site"); assert_eq!( data.get("hive.metastore.warehouse.dir"), @@ -267,25 +192,13 @@ mod tests { #[test] fn user_override_wins_over_everything() { - let hive = hive_cluster(DERBY_YAML); + let cluster_config = derby_cluster_config(); let merged = MetaStoreConfig::default(); - let db = db_details(&hive); let overrides = [("hive.metastore.port".to_string(), "1234".to_string())] .into_iter() .collect(); - let data = build( - &hive, - "default", - "4.0.0", - &merged, - &db, - None, - None, - &cluster_info(), - overrides, - ) - .expect("build hive-site"); + let data = build(&cluster_config, "4.0.0", &merged, overrides).expect("build hive-site"); assert_eq!( data.get("hive.metastore.port"), diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 0f3f681f..7f841381 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -5,6 +5,7 @@ use stackable_operator::{ commons::product_image_selection, kube::ResourceExt as _, role_utils::{GenericRoleConfig, JavaCommonConfig}, + utils::cluster_info::KubernetesClusterInfo, v2::types::operator::ClusterName, }; @@ -15,9 +16,11 @@ use crate::{ }, crd::{ HiveRole, MetaStoreConfig, + databases::{MetadataDatabaseConnection, derby_driver_class}, v1alpha1::{self, HiveMetastoreRoleConfig}, }, framework::role_utils::with_validated_config, + kerberos::kerberos_config_properties, }; #[derive(Snafu, Debug)] @@ -50,6 +53,8 @@ pub enum Error { pub fn validate_cluster( hive: &v1alpha1::HiveCluster, image_repository: &str, + namespace: &str, + cluster_info: &KubernetesClusterInfo, dereferenced_objects: DereferencedObjects, ) -> Result { let image = hive @@ -107,14 +112,36 @@ pub fn validate_cluster( .jdbc_connection_details("METADATA") .context(InvalidMetadataDatabaseConnectionSnafu)?; + // The Derby driver class needs special handling per product version. + let connection_driver = match &hive.spec.cluster_config.metadata_database { + MetadataDatabaseConnection::Derby(_) => { + derby_driver_class(&image.product_version).to_owned() + } + _ => metadata_database_connection_details.driver.clone(), + }; + + // Kerberos-related `hive-site.xml` entries (empty when Kerberos is disabled). + let kerberos_config = kerberos_config_properties(hive, namespace, cluster_info) + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + + // A `core-site.xml` with `hadoop.security.authentication=kerberos` is required when + // Kerberos is enabled and there is no HDFS backend (i.e. S3). + let needs_kerberos_core_site = + hive.has_kerberos_enabled() && hive.spec.cluster_config.hdfs.is_none(); + Ok(ValidatedCluster { name: ClusterName::from_str(&hive.name_any()).context(InvalidClusterNameSnafu)?, image, role_config, cluster_config: ValidatedClusterConfig { metadata_database_connection_details, + connection_driver, s3_connection_spec: dereferenced_objects.s3_connection_spec, hive_opa_config: dereferenced_objects.hive_opa_config, + kerberos_config, + needs_kerberos_core_site, }, role_group_configs, }) From a6a81ba294d2f07785131df794c9fbd74693c0d9 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 19:15:52 +0200 Subject: [PATCH 11/18] fix: move parameter order --- rust/operator-binary/src/controller.rs | 2 +- rust/operator-binary/src/controller/build/config_map.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index 943ad82d..edb0a913 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -415,9 +415,9 @@ pub async fn reconcile_hive( .context(ServiceConfigurationSnafu)?; let rg_configmap = build::config_map::build_metastore_rolegroup_config_map( - hive, &validated_cluster, &rolegroup, + hive, ) .with_context(|_| BuildRoleGroupConfigMapSnafu { rolegroup: rolegroup.clone(), diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index 5b07edb1..363d8774 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -59,9 +59,9 @@ type Result = std::result::Result; /// The rolegroup [`ConfigMap`] configures the rolegroup based on the configuration given by the /// administrator. pub fn build_metastore_rolegroup_config_map( - owner: &v1alpha1::HiveCluster, cluster: &ValidatedCluster, rolegroup: &RoleGroupRef, + owner: &v1alpha1::HiveCluster, ) -> Result { let rg = cluster .role_group_configs From 9d94d086de473945bbcbe931073456baa7ea4d21 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Thu, 4 Jun 2026 13:29:23 +0200 Subject: [PATCH 12/18] refactor: move discovery & product logging --- .../src/{ => controller/build}/discovery.rs | 0 .../src/controller/{build.rs => build/mod.rs} | 0 .../{properties.rs => properties/mod.rs} | 0 rust/operator-binary/src/product_logging.rs | 85 ------------------- 4 files changed, 85 deletions(-) rename rust/operator-binary/src/{ => controller/build}/discovery.rs (100%) rename rust/operator-binary/src/controller/{build.rs => build/mod.rs} (100%) rename rust/operator-binary/src/controller/build/{properties.rs => properties/mod.rs} (100%) delete mode 100644 rust/operator-binary/src/product_logging.rs diff --git a/rust/operator-binary/src/discovery.rs b/rust/operator-binary/src/controller/build/discovery.rs similarity index 100% rename from rust/operator-binary/src/discovery.rs rename to rust/operator-binary/src/controller/build/discovery.rs diff --git a/rust/operator-binary/src/controller/build.rs b/rust/operator-binary/src/controller/build/mod.rs similarity index 100% rename from rust/operator-binary/src/controller/build.rs rename to rust/operator-binary/src/controller/build/mod.rs diff --git a/rust/operator-binary/src/controller/build/properties.rs b/rust/operator-binary/src/controller/build/properties/mod.rs similarity index 100% rename from rust/operator-binary/src/controller/build/properties.rs rename to rust/operator-binary/src/controller/build/properties/mod.rs diff --git a/rust/operator-binary/src/product_logging.rs b/rust/operator-binary/src/product_logging.rs deleted file mode 100644 index 30e9318b..00000000 --- a/rust/operator-binary/src/product_logging.rs +++ /dev/null @@ -1,85 +0,0 @@ -use snafu::Snafu; -use stackable_operator::{ - builder::configmap::ConfigMapBuilder, - memory::BinaryMultiple, - product_logging::{ - self, - spec::{ContainerLogConfig, ContainerLogConfigChoice, Logging}, - }, - role_utils::RoleGroupRef, -}; - -use crate::{ - controller::MAX_HIVE_LOG_FILES_SIZE, - crd::{Container, HIVE_METASTORE_LOG4J2_PROPERTIES, STACKABLE_LOG_DIR, v1alpha1}, -}; - -#[derive(Snafu, Debug)] -pub enum Error { - #[snafu(display("object has no namespace"))] - ObjectHasNoNamespace, - #[snafu(display("failed to retrieve the ConfigMap [{cm_name}]"))] - ConfigMapNotFound { - source: stackable_operator::client::Error, - cm_name: String, - }, - #[snafu(display("failed to retrieve the entry [{entry}] for ConfigMap [{cm_name}]"))] - MissingConfigMapEntry { - entry: &'static str, - cm_name: String, - }, - #[snafu(display("crd validation failure"))] - CrdValidationFailure { source: crate::crd::Error }, -} - -type Result = std::result::Result; - -const CONSOLE_CONVERSION_PATTERN: &str = "%d{ISO8601} %5p [%t] %c{2}: %m%n"; -const HIVE_LOG_FILE: &str = "hive.log4j2.xml"; - -/// Extend the role group ConfigMap with logging and Vector configurations -pub fn extend_role_group_config_map( - rolegroup: &RoleGroupRef, - logging: &Logging, - cm_builder: &mut ConfigMapBuilder, -) -> Result<()> { - if let Some(ContainerLogConfig { - choice: Some(ContainerLogConfigChoice::Automatic(log_config)), - }) = logging.containers.get(&Container::Hive) - { - cm_builder.add_data( - HIVE_METASTORE_LOG4J2_PROPERTIES, - product_logging::framework::create_log4j2_config( - &format!( - "{STACKABLE_LOG_DIR}/{container}", - container = Container::Hive - ), - HIVE_LOG_FILE, - MAX_HIVE_LOG_FILES_SIZE - .scale_to(BinaryMultiple::Mebi) - .floor() - .value as u32, - CONSOLE_CONVERSION_PATTERN, - log_config, - ), - ); - } - - let vector_log_config = if let Some(ContainerLogConfig { - choice: Some(ContainerLogConfigChoice::Automatic(log_config)), - }) = logging.containers.get(&Container::Vector) - { - Some(log_config) - } else { - None - }; - - if logging.enable_vector_agent { - cm_builder.add_data( - product_logging::framework::VECTOR_CONFIG_FILE, - product_logging::framework::create_vector_config(rolegroup, vector_log_config), - ); - } - - Ok(()) -} From 404a335944200907b3b420870df24a37c45c632a Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Thu, 4 Jun 2026 13:29:47 +0200 Subject: [PATCH 13/18] chore: regenerate und linters --- Cargo.nix | 509 +++++++++--------- crate-hashes.json | 18 +- extra/crds.yaml | 12 +- rust/operator-binary/src/controller.rs | 8 +- .../src/controller/build/config_map.rs | 28 +- .../src/controller/build/mod.rs | 1 + .../controller/build/properties/logging.rs | 75 +++ .../src/controller/build/properties/mod.rs | 1 + rust/operator-binary/src/main.rs | 2 - 9 files changed, 375 insertions(+), 279 deletions(-) create mode 100644 rust/operator-binary/src/controller/build/properties/logging.rs diff --git a/Cargo.nix b/Cargo.nix index cb47a36c..ecd8da90 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -489,9 +489,9 @@ rec { }; "autocfg" = rec { crateName = "autocfg"; - version = "1.5.0"; + version = "1.5.1"; edition = "2015"; - sha256 = "1s77f98id9l4af4alklmzq46f21c980v13z2r1pcxx6bqgw0d1n0"; + sha256 = "0lqasy5i30flcgih1b50kvsk6z32g09r1q4ql7q81pj6228jy0zj"; authors = [ "Josh Stone " ]; @@ -866,9 +866,9 @@ rec { }; "bitflags" = rec { crateName = "bitflags"; - version = "2.11.1"; + version = "2.12.1"; edition = "2021"; - sha256 = "1cvqijg3rvwgis20a66vfdxannjsxfy5fgjqkaq3l13gyfcj4lf4"; + sha256 = "02phhjm7w380zdh8928zf13cfi1bw2qz2ay36ml2jmwmmv8cxmw4"; authors = [ "The Rust Project Developers" ]; @@ -898,9 +898,9 @@ rec { }; "built" = rec { crateName = "built"; - version = "0.8.0"; - edition = "2021"; - sha256 = "0r5f08lpjsr6j5ajkbmd0ymfmajpq8ddbfvi8ji8rx48y88qzbgl"; + version = "0.8.1"; + edition = "2024"; + sha256 = "1saq332pd6g3svvc9ah8myjpfvgqlzl2ksb1ypp3976kjcfm63jw"; authors = [ "Lukas Lueg " ]; @@ -924,15 +924,16 @@ rec { "chrono" = [ "dep:chrono" ]; "dependency-tree" = [ "cargo-lock/dependency-tree" ]; "git2" = [ "dep:git2" ]; + "gix" = [ "dep:gix" ]; "semver" = [ "dep:semver" ]; }; resolvedDefaultFeatures = [ "chrono" "git2" ]; }; "bumpalo" = rec { crateName = "bumpalo"; - version = "3.20.2"; + version = "3.20.3"; edition = "2021"; - sha256 = "1jrgxlff76k9glam0akhwpil2fr1w32gbjdf5hpipc7ld2c7h82x"; + sha256 = "0jc6va3nwcqikm7chnpdv1s87my3gs2j7g1sc7g3k91brg3arxbj"; authors = [ "Nick Fitzgerald " ]; @@ -961,9 +962,9 @@ rec { }; "cc" = rec { crateName = "cc"; - version = "1.2.60"; + version = "1.2.63"; edition = "2018"; - sha256 = "084a8ziprdlyrj865f3303qr0b7aaggilkl18slncss6m4yp1ia3"; + sha256 = "0zy2bqc4nvj6bv2cipx4h4bn65wf1zqf1fw1hsh64mmvg1hh2vjm"; authors = [ "Alex Crichton " ]; @@ -1906,9 +1907,9 @@ rec { }; "displaydoc" = rec { crateName = "displaydoc"; - version = "0.2.5"; + version = "0.2.6"; edition = "2021"; - sha256 = "1q0alair462j21iiqwrr21iabkfnb13d6x5w95lkdg21q2xrqdlp"; + sha256 = "0kyxwfbdmagd8afzb2pzja7wj8dhah7smxdsgw00iq8pa2jhmiqs"; procMacro = true; authors = [ "Jane Lusby " @@ -2108,12 +2109,9 @@ rec { }; "either" = rec { crateName = "either"; - version = "1.15.0"; + version = "1.16.0"; edition = "2021"; - sha256 = "069p1fknsmzn9llaizh77kip0pqmcwpdsykv2x30xpjyija5gis8"; - authors = [ - "bluss" - ]; + sha256 = "17k7jfbdz7k440h6lws9baz8p9zlxgb41sig3w81h80nwzsjyqli"; features = { "default" = [ "std" ]; "serde" = [ "dep:serde" ]; @@ -2830,9 +2828,9 @@ rec { }; "futures-timer" = rec { crateName = "futures-timer"; - version = "3.0.3"; + version = "3.0.4"; edition = "2018"; - sha256 = "094vw8k37djpbwv74bwf2qb7n6v6ghif4myss6smd6hgyajb127j"; + sha256 = "0s39in8ivw7g4d37pf31q02y44zd1hpfkd1pgra2slcqibdzlhxg"; libName = "futures_timer"; authors = [ "Alex Crichton " @@ -3090,9 +3088,9 @@ rec { }; "git2" = rec { crateName = "git2"; - version = "0.20.4"; - edition = "2018"; - sha256 = "0azykjpk3j6s354z23jkyq3r3pbmlw9ha1zsxkw5cnnpi1h2b23v"; + version = "0.21.0"; + edition = "2021"; + sha256 = "0bmqga9vlyx5sdlr0i28z0362s89xv9i4qcv20vvx9j54y9vzpfx"; authors = [ "Josh Triplett " "Alex Crichton " @@ -3114,17 +3112,14 @@ rec { name = "log"; packageId = "log"; } - { - name = "url"; - packageId = "url"; - } ]; features = { - "default" = [ "ssh" "https" ]; - "https" = [ "libgit2-sys/https" "openssl-sys" "openssl-probe" ]; + "cred" = [ "dep:url" ]; + "https" = [ "libgit2-sys/https" "openssl-sys" "openssl-probe" "cred" ]; "openssl-probe" = [ "dep:openssl-probe" ]; "openssl-sys" = [ "dep:openssl-sys" ]; - "ssh" = [ "libgit2-sys/ssh" ]; + "ssh" = [ "libgit2-sys/ssh" "cred" ]; + "unstable-sha256" = [ "libgit2-sys/unstable-sha256" ]; "vendored-libgit2" = [ "libgit2-sys/vendored" ]; "vendored-openssl" = [ "openssl-sys/vendored" "libgit2-sys/vendored-openssl" ]; "zlib-ng-compat" = [ "libgit2-sys/zlib-ng-compat" ]; @@ -3214,9 +3209,9 @@ rec { }; "h2" = rec { crateName = "h2"; - version = "0.4.13"; + version = "0.4.14"; edition = "2021"; - sha256 = "0m6w5gg0n0m1m5915bxrv8n4rlazhx5icknkslz719jhh4xdli1g"; + sha256 = "0cw7jk7kn2vn6f8w8ssh6gis1mljnfjxd606gvi4sjpyjayfy7qp"; authors = [ "Carl Lerche " "Sean McArthur " @@ -3327,14 +3322,11 @@ rec { }; resolvedDefaultFeatures = [ "allocator-api2" "default" "default-hasher" "equivalent" "inline-more" "raw-entry" ]; }; - "hashbrown 0.17.0" = rec { + "hashbrown 0.17.1" = rec { crateName = "hashbrown"; - version = "0.17.0"; + version = "0.17.1"; edition = "2024"; - sha256 = "0l8gvcz80lvinb7x22h53cqbi2y1fm603y2jhhh9qwygvkb7sijg"; - authors = [ - "Amanieu d'Antras " - ]; + sha256 = "0jmqz7i4yl6cm7rbn0i2ffkfrmwi6xkmzkaldr2v8bcsx2v0jngd"; features = { "alloc" = [ "dep:alloc" ]; "allocator-api2" = [ "dep:allocator-api2" ]; @@ -3409,9 +3401,9 @@ rec { }; "http" = rec { crateName = "http"; - version = "1.4.0"; + version = "1.4.1"; edition = "2021"; - sha256 = "06iind4cwsj1d6q8c2xgq8i2wka4ps74kmws24gsi1bzdlw2mfp3"; + sha256 = "1l7k2ia57z3q7q3ka497krzps795kd3fymm2k12lr623y4nldrwb"; authors = [ "Alex Crichton " "Carl Lerche " @@ -3528,9 +3520,9 @@ rec { }; "hyper" = rec { crateName = "hyper"; - version = "1.9.0"; + version = "1.10.1"; edition = "2021"; - sha256 = "1jmwbwqcaficskg76kq402gbymbnh2z4v99xwq3l5aa6n8bg16b2"; + sha256 = "1624nwrh1ci34psqcl3q8q266kha8kd6fmqjj14qck49l59iqa2m"; authors = [ "Sean McArthur " ]; @@ -4301,9 +4293,9 @@ rec { }; "idna_adapter" = rec { crateName = "idna_adapter"; - version = "1.2.1"; - edition = "2021"; - sha256 = "0i0339pxig6mv786nkqcxnwqa87v4m94b2653f6k3aj0jmhfkjis"; + version = "1.2.2"; + edition = "2024"; + sha256 = "0557p76l8hj35r9zn1yv7c6x1c0qbrsffmg80n0yy8361ly3fs6b"; authors = [ "The rust-url developers" ]; @@ -4337,7 +4329,7 @@ rec { } { name = "hashbrown"; - packageId = "hashbrown 0.17.0"; + packageId = "hashbrown 0.17.1"; usesDefaultFeatures = false; } ]; @@ -4395,39 +4387,6 @@ rec { }; resolvedDefaultFeatures = [ "default" "std" ]; }; - "iri-string" = rec { - crateName = "iri-string"; - version = "0.7.12"; - edition = "2021"; - sha256 = "082fpx6c5ghvmqpwxaf2b268m47z2ic3prajqbmi1s1qpfj5kri5"; - libName = "iri_string"; - authors = [ - "YOSHIOKA Takuma " - ]; - dependencies = [ - { - name = "memchr"; - packageId = "memchr"; - optional = true; - usesDefaultFeatures = false; - } - { - name = "serde"; - packageId = "serde"; - optional = true; - usesDefaultFeatures = false; - features = [ "derive" ]; - } - ]; - features = { - "alloc" = [ "serde?/alloc" ]; - "default" = [ "std" ]; - "memchr" = [ "dep:memchr" ]; - "serde" = [ "dep:serde" ]; - "std" = [ "alloc" "memchr?/std" "serde?/std" ]; - }; - resolvedDefaultFeatures = [ "alloc" "default" "std" ]; - }; "is_terminal_polyfill" = rec { crateName = "is_terminal_polyfill"; version = "1.70.2"; @@ -4497,9 +4456,9 @@ rec { }; "jiff" = rec { crateName = "jiff"; - version = "0.2.23"; + version = "0.2.28"; edition = "2021"; - sha256 = "0nc37n7jvgrzxdkcgc2hsfdf70lfagigjalh4igjrm5njvf4cd8s"; + sha256 = "00lixngcc7amh2fcsxfr0z38j06lllhapz192biv1qj97q1x60s6"; authors = [ "Andrew Gallant " ]; @@ -4545,12 +4504,10 @@ rec { usesDefaultFeatures = false; } { - name = "windows-sys"; - packageId = "windows-sys 0.61.2"; + name = "windows-link"; + packageId = "windows-link"; optional = true; - usesDefaultFeatures = false; target = { target, features }: (target."windows" or false); - features = [ "Win32_Foundation" "Win32_System_Time" ]; } ]; devDependencies = [ @@ -4569,7 +4526,7 @@ rec { "static-tz" = [ "dep:jiff-static" ]; "std" = [ "alloc" "log?/std" "serde_core?/std" ]; "tz-fat" = [ "jiff-static?/tz-fat" ]; - "tz-system" = [ "std" "dep:windows-sys" ]; + "tz-system" = [ "std" "dep:windows-link" ]; "tzdb-bundle-always" = [ "dep:jiff-tzdb" "alloc" ]; "tzdb-bundle-platform" = [ "dep:jiff-tzdb-platform" "alloc" ]; "tzdb-concatenated" = [ "std" ]; @@ -4579,9 +4536,9 @@ rec { }; "jiff-static" = rec { crateName = "jiff-static"; - version = "0.2.23"; + version = "0.2.28"; edition = "2021"; - sha256 = "192ss3cnixvg79cpa76clwkhn4mmz10vnwsbf7yjw8i484s8p31a"; + sha256 = "0irbhfh2f4i9w5l53jcmh6ssnhdd92wfy76978chgwnxilvk4bbq"; procMacro = true; libName = "jiff_static"; authors = [ @@ -4661,9 +4618,9 @@ rec { }; "js-sys" = rec { crateName = "js-sys"; - version = "0.3.95"; + version = "0.3.99"; edition = "2021"; - sha256 = "1jhj3kgxxgwm0cpdjiz7i2qapqr7ya9qswadmr63dhwx3lnyjr19"; + sha256 = "04azrzsz91gr5s3z0ij36lz0kj9ry4lw3jz0mmbiwb251rsc8aql"; libName = "js_sys"; authors = [ "The wasm-bindgen Developers" @@ -4672,7 +4629,6 @@ rec { { name = "cfg-if"; packageId = "cfg-if"; - optional = true; } { name = "futures-util"; @@ -4694,17 +4650,16 @@ rec { ]; features = { "default" = [ "std" "unsafe-eval" ]; - "futures" = [ "dep:cfg-if" "dep:futures-util" ]; - "futures-core-03-stream" = [ "futures" "dep:futures-core" ]; - "std" = [ "wasm-bindgen/std" ]; + "futures-core-03-stream" = [ "dep:futures-util" "dep:futures-core" ]; + "std" = [ "wasm-bindgen/std" "dep:futures-util" ]; }; - resolvedDefaultFeatures = [ "default" "futures" "std" "unsafe-eval" ]; + resolvedDefaultFeatures = [ "default" "std" "unsafe-eval" ]; }; "json-patch" = rec { crateName = "json-patch"; - version = "4.1.0"; + version = "4.2.0"; edition = "2021"; - sha256 = "147yaxmv3i4s0bdna86rgwpmqh2507fn4ighfpplaiqkw8ay807k"; + sha256 = "0wkv896d0pzq56i2kkl0giqpv117fwvhbpgs8iz85805w66l68bl"; libName = "json_patch"; authors = [ "Ivan Dubrov " @@ -4714,6 +4669,11 @@ rec { name = "jsonptr"; packageId = "jsonptr"; } + { + name = "schemars"; + packageId = "schemars"; + optional = true; + } { name = "serde"; packageId = "serde"; @@ -4725,10 +4685,14 @@ rec { } { name = "thiserror"; - packageId = "thiserror 1.0.69"; + packageId = "thiserror 2.0.18"; } ]; devDependencies = [ + { + name = "schemars"; + packageId = "schemars"; + } { name = "serde_json"; packageId = "serde_json"; @@ -4740,7 +4704,7 @@ rec { "schemars" = [ "dep:schemars" ]; "utoipa" = [ "dep:utoipa" ]; }; - resolvedDefaultFeatures = [ "default" "diff" ]; + resolvedDefaultFeatures = [ "default" "diff" "schemars" ]; }; "jsonpath-rust" = rec { crateName = "jsonpath-rust"; @@ -4866,8 +4830,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; libName = "k8s_version"; @@ -4886,7 +4850,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } ]; features = { @@ -5518,9 +5482,9 @@ rec { }; "libc" = rec { crateName = "libc"; - version = "0.2.185"; + version = "0.2.186"; edition = "2021"; - sha256 = "13rbdaa59l3w92q7kfcxx8zbikm99zzw54h59aqvcv5wx47jrzsj"; + sha256 = "0rnyhzjyqq9x56skkllbjzzzwym3r61lq3l4hqj64v71gw0r3av8"; authors = [ "The Rust Project Developers" ]; @@ -5534,10 +5498,10 @@ rec { }; "libgit2-sys" = rec { crateName = "libgit2-sys"; - version = "0.18.3+1.9.2"; + version = "0.18.5+1.9.4"; edition = "2021"; links = "git2"; - sha256 = "11rlbyihj3k35mnkxxz4yvsnlx33a4r9srl66c5vp08pp72arcy9"; + sha256 = "18lwqnhy7qxg4iw24s1a0n7aj7qbnryry1iy0w32k4f1xbk6lp80"; libName = "libgit2_sys"; libPath = "lib.rs"; authors = [ @@ -5595,10 +5559,10 @@ rec { }; "libz-sys" = rec { crateName = "libz-sys"; - version = "1.1.28"; + version = "1.1.29"; edition = "2018"; links = "z"; - sha256 = "08hyf9v85zifl3353xc7i5wr53v9b3scri856cmphl3gaxp24fpw"; + sha256 = "1n98kqya7a7a0cxf5n5z3g13rj7a1vqxynk2xc7bja1qfxbrdg45"; libName = "libz_sys"; authors = [ "Alex Crichton " @@ -5675,9 +5639,9 @@ rec { }; "log" = rec { crateName = "log"; - version = "0.4.29"; + version = "0.4.31"; edition = "2021"; - sha256 = "15q8j9c8g5zpkcw0hnd6cf2z7fxqnvsjh3rw5mv5q10r83i34l2y"; + sha256 = "0kq2fh6q2bjkrm8m6hj8kb7gxfd7cr7qbcpxd1lc1xq5rns30fqi"; authors = [ "The Rust Project Developers" ]; @@ -5731,9 +5695,9 @@ rec { }; "memchr" = rec { crateName = "memchr"; - version = "2.8.0"; + version = "2.8.1"; edition = "2021"; - sha256 = "0y9zzxcqxvdqg6wyag7vc3h0blhdn7hkq164bxyx2vph8zs5ijpq"; + sha256 = "1n448jx01h5z2xknj6x2dhxgr8s8fb717cf6vfqj5lmhkpj7m53b"; authors = [ "Andrew Gallant " "bluss" @@ -5794,9 +5758,9 @@ rec { }; "mio" = rec { crateName = "mio"; - version = "1.2.0"; + version = "1.2.1"; edition = "2021"; - sha256 = "1hanrh4fwsfkdqdaqfidz48zz1wdix23zwn3r2x78am0garfbdsh"; + sha256 = "1nkggmrlnjs93w8rja4lvjj4aml1xqahgimv1h0p7d373kvhmg82"; authors = [ "Carl Lerche " "Thomas de Zeeuw " @@ -5932,9 +5896,9 @@ rec { }; "num-conv" = rec { crateName = "num-conv"; - version = "0.2.1"; + version = "0.2.2"; edition = "2021"; - sha256 = "0rqrr29brafaa2za352pbmhkk556n7f8z9rrkgmjp1idvdl3fry6"; + sha256 = "0hg4f9bwmy7cwpxdkm165dmkfc8jhkkayci234jsmi5ssb33j5sj"; libName = "num_conv"; authors = [ "Jacob Pratt " @@ -6882,9 +6846,9 @@ rec { }; "pin-project" = rec { crateName = "pin-project"; - version = "1.1.11"; + version = "1.1.13"; edition = "2021"; - sha256 = "05zm3y3bl83ypsr6favxvny2kys4i19jiz1y18ylrbxwsiz9qx7i"; + sha256 = "09091qp946lpmjz4yp0xil1r5v4hgc91fi19dg5csayhdqrv4ri4"; libName = "pin_project"; dependencies = [ { @@ -6896,9 +6860,9 @@ rec { }; "pin-project-internal" = rec { crateName = "pin-project-internal"; - version = "1.1.11"; + version = "1.1.13"; edition = "2021"; - sha256 = "1ik4mpb92da75inmjvxf2qm61vrnwml3x24wddvrjlqh1z9hxcnr"; + sha256 = "12rzlh07i1sdgrvzj6wgkka5bjqyvbfsl8knq6qi7g16m7q9aqy9"; procMacro = true; libName = "pin_project_internal"; dependencies = [ @@ -8250,9 +8214,9 @@ rec { }; "rustls" = rec { crateName = "rustls"; - version = "0.23.38"; + version = "0.23.40"; edition = "2021"; - sha256 = "089ssmhd79f0kd22brh6lkaadql2p3pi6579ax1s0kn1n9pldyb9"; + sha256 = "12qnv3ag4wrw7aj8jng74kgrilpjm2b1rfcjaac8h691frccv1pg"; dependencies = [ { name = "log"; @@ -8319,9 +8283,9 @@ rec { }; "rustls-native-certs" = rec { crateName = "rustls-native-certs"; - version = "0.8.3"; + version = "0.8.4"; edition = "2021"; - sha256 = "0qrajg2n90bcr3bcq6j95gjm7a9lirfkkdmjj32419dyyzan0931"; + sha256 = "0kgazl8zc1sv63qg179bz96ilzh56lzfa5k92ji7d265f4kibdfs"; libName = "rustls_native_certs"; dependencies = [ { @@ -8350,9 +8314,9 @@ rec { }; "rustls-pki-types" = rec { crateName = "rustls-pki-types"; - version = "1.14.0"; + version = "1.14.1"; edition = "2021"; - sha256 = "1p9zsgslvwzzkzhm6bqicffqndr4jpx67992b0vl0pi21a5hy15y"; + sha256 = "1a9pr54y0f3qr97bxpd3ahjldq0gqdld0h799xbnwdzbwxx1k9rh"; libName = "rustls_pki_types"; dependencies = [ { @@ -8888,9 +8852,9 @@ rec { }; "serde_json" = rec { crateName = "serde_json"; - version = "1.0.149"; + version = "1.0.150"; edition = "2021"; - sha256 = "11jdx4vilzrjjd1dpgy67x5lgzr0laplz30dhv75lnf5ffa07z43"; + sha256 = "1ffgfhy9kndjnrz8lmy95pr758p2zk8dxv6yi99x0vkkni24w0g8"; authors = [ "Erick Tryzelaar " "David Tolnay " @@ -9131,9 +9095,9 @@ rec { }; "shlex" = rec { crateName = "shlex"; - version = "1.3.0"; - edition = "2015"; - sha256 = "0r1y6bv26c1scpxvhg2cabimrmwgbp4p3wy6syj9n0c4s3q2znhg"; + version = "2.0.1"; + edition = "2018"; + sha256 = "1fjsll1cd7d2bcpdij9kd6w62rpbc7qqzvydvs021vsmr1cxvypq"; authors = [ "comex " "Fenhl " @@ -9312,29 +9276,25 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" "rust_1_61" "rust_1_65" "std" ]; }; - "snafu 0.9.0" = rec { + "snafu 0.9.1" = rec { crateName = "snafu"; - version = "0.9.0"; + version = "0.9.1"; edition = "2018"; - sha256 = "1ii9r99x5qcn754m624yzgb9hzvkqkrcygf0aqh0pyb9dbnvrm6i"; + sha256 = "08k5yfydxdlshivfhrdq9km8qn02r93q28gkyvazbqz2icr1586i"; authors = [ "Jake Goulding " ]; dependencies = [ { name = "snafu-derive"; - packageId = "snafu-derive 0.9.0"; + packageId = "snafu-derive 0.9.1"; } ]; features = { - "backtrace" = [ "dep:backtrace" ]; - "backtraces-impl-backtrace-crate" = [ "backtrace" ]; + "backtraces-impl-backtrace-crate" = [ "dep:backtrace" ]; "default" = [ "std" "rust_1_81" ]; - "futures" = [ "futures-core-crate" "pin-project" ]; - "futures-core-crate" = [ "dep:futures-core-crate" ]; - "futures-crate" = [ "dep:futures-crate" ]; - "internal-dev-dependencies" = [ "futures-crate" ]; - "pin-project" = [ "dep:pin-project" ]; + "futures" = [ "dep:futures-core" "dep:pin-project" ]; + "internal-dev-dependencies" = [ "dep:futures" ]; "std" = [ "alloc" ]; "unstable-provider-api" = [ "snafu-derive/unstable-provider-api" ]; }; @@ -9402,11 +9362,11 @@ rec { }; resolvedDefaultFeatures = [ "rust_1_61" ]; }; - "snafu-derive 0.9.0" = rec { + "snafu-derive 0.9.1" = rec { crateName = "snafu-derive"; - version = "0.9.0"; + version = "0.9.1"; edition = "2018"; - sha256 = "0h0x61kyj4fvilcr2nj02l85shw1ika64vq9brf2gyna662ln9al"; + sha256 = "1nkfi7bis72pz3w7vb64m79w49qsv20sbf19jkd471vbhr83q42z"; procMacro = true; libName = "snafu_derive"; authors = [ @@ -9432,7 +9392,7 @@ rec { name = "syn"; packageId = "syn 2.0.117"; usesDefaultFeatures = false; - features = [ "clone-impls" "derive" "full" "parsing" "printing" "proc-macro" ]; + features = [ "clone-impls" "derive" "full" "parsing" "printing" "proc-macro" "visit-mut" ]; } ]; features = { @@ -9440,9 +9400,9 @@ rec { }; "socket2" = rec { crateName = "socket2"; - version = "0.6.3"; + version = "0.6.4"; edition = "2021"; - sha256 = "0gkjjcyn69hqhhlh5kl8byk5m0d7hyrp2aqwzbs3d33q208nwxis"; + sha256 = "0ldyp5rhba15spwxj1n94xh7sjks1398c3vwpwkxkd1087nwzlaj"; authors = [ "Alex Crichton " "Thomas de Zeeuw " @@ -9540,8 +9500,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; libName = "stackable_certs"; @@ -9600,7 +9560,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-shared"; @@ -9679,12 +9639,12 @@ rec { packageId = "indoc"; } { - name = "pin-project"; - packageId = "pin-project"; + name = "java-properties"; + packageId = "java-properties"; } { - name = "product-config"; - packageId = "product-config"; + name = "pin-project"; + packageId = "pin-project"; } { name = "semver"; @@ -9701,7 +9661,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-operator"; @@ -9722,6 +9682,10 @@ rec { name = "tracing"; packageId = "tracing"; } + { + name = "xml"; + packageId = "xml"; + } ]; buildDependencies = [ { @@ -9744,12 +9708,12 @@ rec { }; "stackable-operator" = rec { crateName = "stackable-operator"; - version = "0.111.0"; + version = "0.111.1"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; libName = "stackable_operator"; @@ -9807,6 +9771,7 @@ rec { { name = "json-patch"; packageId = "json-patch"; + features = [ "schemars" ]; } { name = "k8s-openapi"; @@ -9856,7 +9821,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-operator-derive"; @@ -9910,6 +9875,10 @@ rec { packageId = "url"; features = [ "serde" ]; } + { + name = "uuid"; + packageId = "uuid"; + } ]; features = { "certs" = [ "dep:stackable-certs" ]; @@ -9928,8 +9897,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; procMacro = true; @@ -9963,8 +9932,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; libName = "stackable_shared"; @@ -10009,7 +9978,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "strum"; @@ -10044,8 +10013,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; libName = "stackable_telemetry"; @@ -10097,7 +10066,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "strum"; @@ -10154,8 +10123,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; libName = "stackable_versioned"; @@ -10189,7 +10158,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-versioned-macros"; @@ -10204,8 +10173,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; procMacro = true; @@ -10272,8 +10241,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "b7c8a3a5483b4d35d0abfa11f6db6c153bda8a51"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; }; libName = "stackable_webhook"; @@ -10346,7 +10315,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-certs"; @@ -10918,9 +10887,9 @@ rec { }; "tokio" = rec { crateName = "tokio"; - version = "1.52.1"; + version = "1.52.3"; edition = "2021"; - sha256 = "1imw1dkkv38p66i33m5hsyk3d6prsbyrayjvqhndjvz89ybywzdn"; + sha256 = "1zpzazypkg61sw91na1m85x5s4rsjym335fwwhwm1hcs70dz1iwg"; authors = [ "Tokio Contributors " ]; @@ -11230,9 +11199,9 @@ rec { }; "toml_edit" = rec { crateName = "toml_edit"; - version = "0.25.11+spec-1.1.0"; + version = "0.25.12+spec-1.1.0"; edition = "2024"; - sha256 = "0awzffbkx33v9x4h19b5mfrwp3sn4ifr16y58sbk6j6l5v9c8n8b"; + sha256 = "1mx5paq837rjw7w51zprrjynk1vaig9yzxfqz9ac79jmd7f3w5fj"; dependencies = [ { name = "indexmap"; @@ -11285,9 +11254,9 @@ rec { }; "tonic" = rec { crateName = "tonic"; - version = "0.14.5"; - edition = "2021"; - sha256 = "1v4k7aa28m7722gz9qak2jiy7lis1ycm4fdmq63iip4m0qdcdizy"; + version = "0.14.6"; + edition = "2024"; + sha256 = "1vs5ci6z6b9xhfsnx4s8qx6bqi1zzcrxncjp71147a0gqwc5aamc"; authors = [ "Lucio Franco " ]; @@ -11414,9 +11383,9 @@ rec { }; "tonic-prost" = rec { crateName = "tonic-prost"; - version = "0.14.5"; - edition = "2021"; - sha256 = "02fkg2bv87q0yds2wz3w0s7i1x6qcgbrl00dy6ipajdapfh7clx5"; + version = "0.14.6"; + edition = "2024"; + sha256 = "184y40nf0iyzc5rg32ivgd88snv68sqy1kchynn55r1vhml9z12h"; libName = "tonic_prost"; authors = [ "Lucio Franco " @@ -11558,9 +11527,9 @@ rec { }; "tower-http" = rec { crateName = "tower-http"; - version = "0.6.8"; + version = "0.6.11"; edition = "2018"; - sha256 = "1y514jwzbyrmrkbaajpwmss4rg0mak82k16d6588w9ncaffmbrnl"; + sha256 = "0h08wjgs3hwnq11iwwzlmnabn1h4cl0fzd48svaccvqffkiggz2c"; libName = "tower_http"; authors = [ "Tower Maintainers " @@ -11594,11 +11563,6 @@ rec { packageId = "http-body"; optional = true; } - { - name = "iri-string"; - packageId = "iri-string"; - optional = true; - } { name = "mime"; packageId = "mime"; @@ -11628,6 +11592,11 @@ rec { optional = true; usesDefaultFeatures = false; } + { + name = "url"; + packageId = "url"; + optional = true; + } ]; devDependencies = [ { @@ -11649,35 +11618,33 @@ rec { } ]; features = { - "async-compression" = [ "dep:async-compression" ]; "auth" = [ "base64" "validate-request" ]; "base64" = [ "dep:base64" ]; "catch-panic" = [ "tracing" "futures-util/std" "dep:http-body" "dep:http-body-util" ]; - "compression-br" = [ "async-compression/brotli" "futures-core" "dep:http-body" "tokio-util" "tokio" ]; - "compression-deflate" = [ "async-compression/zlib" "futures-core" "dep:http-body" "tokio-util" "tokio" ]; + "compression-br" = [ "dep:async-compression" "async-compression?/brotli" "futures-core" "dep:http-body" "tokio-util" "dep:tokio" ]; + "compression-deflate" = [ "dep:async-compression" "async-compression?/zlib" "futures-core" "dep:http-body" "tokio-util" "dep:tokio" ]; "compression-full" = [ "compression-br" "compression-deflate" "compression-gzip" "compression-zstd" ]; - "compression-gzip" = [ "async-compression/gzip" "futures-core" "dep:http-body" "tokio-util" "tokio" ]; - "compression-zstd" = [ "async-compression/zstd" "futures-core" "dep:http-body" "tokio-util" "tokio" ]; - "decompression-br" = [ "async-compression/brotli" "futures-core" "dep:http-body" "dep:http-body-util" "tokio-util" "tokio" ]; - "decompression-deflate" = [ "async-compression/zlib" "futures-core" "dep:http-body" "dep:http-body-util" "tokio-util" "tokio" ]; + "compression-gzip" = [ "dep:async-compression" "async-compression?/gzip" "futures-core" "dep:http-body" "tokio-util" "dep:tokio" ]; + "compression-zstd" = [ "dep:async-compression" "async-compression?/zstd" "futures-core" "dep:http-body" "tokio-util" "dep:tokio" ]; + "decompression-br" = [ "dep:async-compression" "async-compression?/brotli" "futures-core" "dep:http-body" "dep:http-body-util" "tokio-util" "dep:tokio" ]; + "decompression-deflate" = [ "dep:async-compression" "async-compression?/zlib" "futures-core" "dep:http-body" "dep:http-body-util" "tokio-util" "dep:tokio" ]; "decompression-full" = [ "decompression-br" "decompression-deflate" "decompression-gzip" "decompression-zstd" ]; - "decompression-gzip" = [ "async-compression/gzip" "futures-core" "dep:http-body" "dep:http-body-util" "tokio-util" "tokio" ]; - "decompression-zstd" = [ "async-compression/zstd" "futures-core" "dep:http-body" "dep:http-body-util" "tokio-util" "tokio" ]; - "follow-redirect" = [ "futures-util" "dep:http-body" "iri-string" "tower/util" ]; - "fs" = [ "futures-core" "futures-util" "dep:http-body" "dep:http-body-util" "tokio/fs" "tokio-util/io" "tokio/io-util" "dep:http-range-header" "mime_guess" "mime" "percent-encoding" "httpdate" "set-status" "futures-util/alloc" "tracing" ]; - "full" = [ "add-extension" "auth" "catch-panic" "compression-full" "cors" "decompression-full" "follow-redirect" "fs" "limit" "map-request-body" "map-response-body" "metrics" "normalize-path" "propagate-header" "redirect" "request-id" "sensitive-headers" "set-header" "set-status" "timeout" "trace" "util" "validate-request" ]; + "decompression-gzip" = [ "dep:async-compression" "async-compression?/gzip" "futures-core" "dep:http-body" "dep:http-body-util" "tokio-util" "dep:tokio" ]; + "decompression-zstd" = [ "dep:async-compression" "async-compression?/zstd" "futures-core" "dep:http-body" "dep:http-body-util" "tokio-util" "dep:tokio" ]; + "follow-redirect" = [ "futures-util" "dep:http-body" "dep:url" "tower/util" ]; + "fs" = [ "dep:tokio" "tokio?/fs" "tokio?/io-util" "futures-core" "futures-util" "dep:http-body" "dep:http-body-util" "tokio-util/io" "dep:http-range-header" "mime_guess" "mime" "percent-encoding" "httpdate" "set-status" "futures-util/alloc" ]; + "full" = [ "add-extension" "auth" "catch-panic" "compression-full" "cors" "decompression-full" "follow-redirect" "fs" "limit" "map-request-body" "map-response-body" "metrics" "normalize-path" "on-early-drop" "propagate-header" "redirect" "request-id" "sensitive-headers" "set-header" "set-status" "timeout" "trace" "util" "validate-request" ]; "futures-core" = [ "dep:futures-core" ]; "futures-util" = [ "dep:futures-util" ]; "httpdate" = [ "dep:httpdate" ]; - "iri-string" = [ "dep:iri-string" ]; "limit" = [ "dep:http-body" "dep:http-body-util" ]; - "metrics" = [ "dep:http-body" "tokio/time" ]; + "metrics" = [ "dep:http-body" "dep:tokio" "tokio?/time" ]; "mime" = [ "dep:mime" ]; "mime_guess" = [ "dep:mime_guess" ]; + "on-early-drop" = [ "dep:http-body" ]; "percent-encoding" = [ "dep:percent-encoding" ]; "request-id" = [ "uuid" ]; - "timeout" = [ "dep:http-body" "tokio/time" ]; - "tokio" = [ "dep:tokio" ]; + "timeout" = [ "dep:http-body" "dep:tokio" "tokio?/time" ]; "tokio-util" = [ "dep:tokio-util" ]; "tower" = [ "dep:tower" ]; "trace" = [ "dep:http-body" "tracing" ]; @@ -11686,7 +11653,7 @@ rec { "uuid" = [ "dep:uuid" ]; "validate-request" = [ "mime" ]; }; - resolvedDefaultFeatures = [ "auth" "base64" "default" "follow-redirect" "futures-util" "iri-string" "map-response-body" "mime" "tower" "trace" "tracing" "util" "validate-request" ]; + resolvedDefaultFeatures = [ "auth" "base64" "default" "follow-redirect" "futures-util" "map-response-body" "mime" "tower" "trace" "tracing" "util" "validate-request" ]; }; "tower-layer" = rec { crateName = "tower-layer"; @@ -12130,13 +12097,9 @@ rec { }; "typenum" = rec { crateName = "typenum"; - version = "1.20.0"; + version = "1.20.1"; edition = "2018"; - sha256 = "1pj35y6q11d3y55gdl6g1h2dfhmybjming0jdi9bh0bpnqm11kj0"; - authors = [ - "Paho Lurie-Gregg " - "Andre Bogus " - ]; + sha256 = "086s9ly0906kw5yw41249fba97w5zfxf03pyfwdkffvcprqfixdn"; features = { "scale-info" = [ "dep:scale-info" ]; "scale_info" = [ "scale-info/derive" ]; @@ -12169,9 +12132,9 @@ rec { }; "unicode-segmentation" = rec { crateName = "unicode-segmentation"; - version = "1.13.2"; + version = "1.13.3"; edition = "2018"; - sha256 = "135a26m4a0wj319gcw28j6a5aqvz00jmgwgmcs6szgxjf942facn"; + sha256 = "1a47zaq83p386r3baq4m018xd5q4q0grdg56i1x042dzn71x7xf6"; libName = "unicode_segmentation"; authors = [ "kwantam " @@ -12297,6 +12260,66 @@ rec { }; resolvedDefaultFeatures = [ "default" ]; }; + "uuid" = rec { + crateName = "uuid"; + version = "1.23.2"; + edition = "2021"; + sha256 = "1xy942s4z0bi8p3441wvd4ry3hx6ry1c7s6fgrr38462xqybhn6j"; + authors = [ + "Ashley Mannix" + "Dylan DPC" + "Hunar Roop Kahlon" + ]; + dependencies = [ + { + name = "js-sys"; + packageId = "js-sys"; + optional = true; + usesDefaultFeatures = false; + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)) && (builtins.elem "atomics" targetFeatures)); + } + { + name = "wasm-bindgen"; + packageId = "wasm-bindgen"; + optional = true; + usesDefaultFeatures = false; + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); + } + ]; + devDependencies = [ + { + name = "wasm-bindgen"; + packageId = "wasm-bindgen"; + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); + } + ]; + features = { + "arbitrary" = [ "dep:arbitrary" ]; + "atomic" = [ "dep:atomic" ]; + "borsh" = [ "dep:borsh" "dep:borsh-derive" ]; + "bytemuck" = [ "dep:bytemuck" ]; + "default" = [ "std" ]; + "fast-rng" = [ "rng" "dep:rand" ]; + "js" = [ "dep:wasm-bindgen" "dep:js-sys" ]; + "md5" = [ "dep:md-5" ]; + "rng" = [ "dep:getrandom" ]; + "rng-getrandom" = [ "rng" "dep:getrandom" "uuid-rng-internal-lib" "uuid-rng-internal-lib/getrandom" ]; + "rng-rand" = [ "rng" "dep:rand" "uuid-rng-internal-lib" "uuid-rng-internal-lib/rand" ]; + "serde" = [ "dep:serde_core" ]; + "sha1" = [ "dep:sha1_smol" ]; + "slog" = [ "dep:slog" ]; + "std" = [ "wasm-bindgen?/std" "js-sys?/std" ]; + "uuid-rng-internal-lib" = [ "dep:uuid-rng-internal-lib" ]; + "v1" = [ "atomic" ]; + "v3" = [ "md5" ]; + "v4" = [ "rng" ]; + "v5" = [ "sha1" ]; + "v6" = [ "atomic" ]; + "v7" = [ "rng" ]; + "zerocopy" = [ "dep:zerocopy" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "valuable" = rec { crateName = "valuable"; version = "0.1.1"; @@ -12384,9 +12407,9 @@ rec { }; "wasm-bindgen" = rec { crateName = "wasm-bindgen"; - version = "0.2.118"; + version = "0.2.122"; edition = "2021"; - sha256 = "129s5r14fx4v4xrzpx2c6l860nkxpl48j50y7kl6j16bpah3iy8b"; + sha256 = "02flix96brsb2r1i3grnikii302iqpdm337kl3xv5lklz5v4bl1y"; libName = "wasm_bindgen"; authors = [ "The wasm-bindgen Developers" @@ -12435,9 +12458,9 @@ rec { }; "wasm-bindgen-futures" = rec { crateName = "wasm-bindgen-futures"; - version = "0.4.68"; + version = "0.4.72"; edition = "2021"; - sha256 = "1y7bq5d9fk7s9xaayx38bgs9ns35na0kpb5zw19944zvya1x6wgk"; + sha256 = "03qb24gfr072rk8hb69glfdc8yhqqqq2rhy3j5i0ps8sk79dnwwl"; libName = "wasm_bindgen_futures"; authors = [ "The wasm-bindgen Developers" @@ -12447,7 +12470,6 @@ rec { name = "js-sys"; packageId = "js-sys"; usesDefaultFeatures = false; - features = [ "futures" ]; } { name = "wasm-bindgen"; @@ -12464,9 +12486,9 @@ rec { }; "wasm-bindgen-macro" = rec { crateName = "wasm-bindgen-macro"; - version = "0.2.118"; + version = "0.2.122"; edition = "2021"; - sha256 = "1v98r8vs17cj8918qsg0xx4nlg4nxk1g0jd4nwnyrh1687w29zzf"; + sha256 = "1inyl55bvdifx7l60q9wl0ivmw7236jg7jqmcqpxhsx3knq52qci"; procMacro = true; libName = "wasm_bindgen_macro"; authors = [ @@ -12488,9 +12510,9 @@ rec { }; "wasm-bindgen-macro-support" = rec { crateName = "wasm-bindgen-macro-support"; - version = "0.2.118"; + version = "0.2.122"; edition = "2021"; - sha256 = "0169jr0q469hfx5zqxfyywf2h2f4aj17vn4zly02nfwqmxghc24x"; + sha256 = "0pjw5kc2mbfz59agk5l21kh4hxzp94rygdvsnr4f3z6b5hv4g419"; libName = "wasm_bindgen_macro_support"; authors = [ "The wasm-bindgen Developers" @@ -12524,10 +12546,10 @@ rec { }; "wasm-bindgen-shared" = rec { crateName = "wasm-bindgen-shared"; - version = "0.2.118"; + version = "0.2.122"; edition = "2021"; links = "wasm_bindgen"; - sha256 = "0ag1vvdzi4334jlzilsy14y3nyzwddf1ndn62fyhf6bg62g4vl2z"; + sha256 = "0ds4mmfqvxwc5fp33hn0jblf0f6b4lghrd9mpkls66zic4n9p4ls"; libName = "wasm_bindgen_shared"; authors = [ "The wasm-bindgen Developers" @@ -12542,9 +12564,9 @@ rec { }; "web-sys" = rec { crateName = "web-sys"; - version = "0.3.95"; + version = "0.3.99"; edition = "2021"; - sha256 = "0zfr2jy5bpkkggl88i43yy37p538hg20i56kwn421yj9g6qznbag"; + sha256 = "0dilfvl9jnyhi4skl6cry9wc300r693j0w82jjbq8yy3rx0i8qkd"; libName = "web_sys"; authors = [ "The wasm-bindgen Developers" @@ -12628,6 +12650,7 @@ rec { "CssStyleSheet" = [ "StyleSheet" ]; "CssSupportsRule" = [ "CssConditionRule" "CssGroupingRule" "CssRule" ]; "CssTransition" = [ "Animation" "EventTarget" ]; + "CssViewTransitionRule" = [ "CssRule" ]; "CustomEvent" = [ "Event" ]; "DedicatedWorkerGlobalScope" = [ "EventTarget" "WorkerGlobalScope" ]; "DelayNode" = [ "AudioNode" "EventTarget" ]; @@ -13704,7 +13727,7 @@ rec { "Win32_Web" = [ "Win32" ]; "Win32_Web_InternetExplorer" = [ "Win32_Web" ]; }; - resolvedDefaultFeatures = [ "Wdk" "Wdk_Foundation" "Wdk_Storage" "Wdk_Storage_FileSystem" "Wdk_System" "Wdk_System_IO" "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_Security" "Win32_Security_Authentication" "Win32_Security_Authentication_Identity" "Win32_Security_Credentials" "Win32_Security_Cryptography" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Console" "Win32_System_Diagnostics" "Win32_System_Diagnostics_Debug" "Win32_System_IO" "Win32_System_LibraryLoader" "Win32_System_Memory" "Win32_System_Pipes" "Win32_System_SystemInformation" "Win32_System_SystemServices" "Win32_System_Threading" "Win32_System_Time" "Win32_System_WindowsProgramming" "default" ]; + resolvedDefaultFeatures = [ "Wdk" "Wdk_Foundation" "Wdk_Storage" "Wdk_Storage_FileSystem" "Wdk_System" "Wdk_System_IO" "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_Security" "Win32_Security_Authentication" "Win32_Security_Authentication_Identity" "Win32_Security_Credentials" "Win32_Security_Cryptography" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Console" "Win32_System_Diagnostics" "Win32_System_Diagnostics_Debug" "Win32_System_IO" "Win32_System_LibraryLoader" "Win32_System_Memory" "Win32_System_Pipes" "Win32_System_SystemInformation" "Win32_System_SystemServices" "Win32_System_Threading" "Win32_System_WindowsProgramming" "default" ]; }; "windows-targets" = rec { crateName = "windows-targets"; @@ -13841,9 +13864,9 @@ rec { }; "winnow" = rec { crateName = "winnow"; - version = "1.0.1"; + version = "1.0.3"; edition = "2021"; - sha256 = "1dbji1bwviy08pl74f2qw2m4w9hc4p3vyl3lfj05jdydy59w1nh9"; + sha256 = "1wajycd3krn6h699vydjv7hm0ll5l31p899qzpk59y2is74y34h5"; dependencies = [ { name = "memchr"; @@ -13955,9 +13978,9 @@ rec { }; "xml" = rec { crateName = "xml"; - version = "1.2.1"; + version = "1.3.0"; edition = "2021"; - sha256 = "0ak4k990faralbli5a0rb8kvwihccb2rp0r94d4azfy94a6lkamq"; + sha256 = "128s58qhq8whrx90zbw8r5algr7lakgbf7mn05jfk234rbjqavv3"; authors = [ "Vladimir Matveev " "Kornel (https://github.com/kornelski)" @@ -14032,9 +14055,9 @@ rec { }; "zerocopy" = rec { crateName = "zerocopy"; - version = "0.8.48"; + version = "0.8.50"; edition = "2021"; - sha256 = "1sb8plax8jbrsng1jdval7bdhk7hhrx40dz3hwh074k6knzkgm7f"; + sha256 = "1laahnfxs4qyfb1fdf5nbb2qfshi72b1hbi0ffp2zy2m1r7ms1iv"; authors = [ "Joshua Liebow-Feeser " "Jack Wrenn " @@ -14068,9 +14091,9 @@ rec { }; "zerocopy-derive" = rec { crateName = "zerocopy-derive"; - version = "0.8.48"; + version = "0.8.50"; edition = "2021"; - sha256 = "1m5s0g92cxggqc74j83k1priz24k3z93sj5gadppd20p9c4cvqvh"; + sha256 = "0fdnr9qslx1hbn2i9rsvy9s95mychfy2vj90ajsjm2basccinqqb"; procMacro = true; libName = "zerocopy_derive"; authors = [ @@ -14103,11 +14126,11 @@ rec { }; "zerofrom" = rec { crateName = "zerofrom"; - version = "0.1.7"; + version = "0.1.8"; edition = "2021"; - sha256 = "1py40in4rirc9q8w36q67pld0zk8ssg024xhh0cncxgal7ra3yk9"; + sha256 = "0wjjdj7gdmd0iq91gzkxl7dlv0nhkk80l4bmdpzh3a1yh48mmh0f"; authors = [ - "Manish Goregaokar " + "The ICU4X Project Developers" ]; dependencies = [ { diff --git a/crate-hashes.json b/crate-hashes.json index 71fbc1c3..362b463b 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,12 +1,12 @@ { - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#k8s-version@0.1.3": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-certs@0.4.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-operator-derive@0.3.1": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-operator@0.111.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-shared@0.1.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-telemetry@0.6.3": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-versioned-macros@0.10.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-versioned@0.10.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.0#stackable-webhook@0.9.1": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#k8s-version@0.1.3": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-certs@0.4.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator-derive@0.3.1": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator@0.111.1": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-shared@0.1.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-telemetry@0.6.3": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned-macros@0.10.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned@0.10.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-webhook@0.9.1": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", "git+https://github.com/stackabletech/product-config.git?tag=0.8.0#product-config@0.8.0": "1dz70kapm2wdqcr7ndyjji0lhsl98bsq95gnb2lw487wf6yr7987" } \ No newline at end of file diff --git a/extra/crds.yaml b/extra/crds.yaml index 7d82b11b..dc998634 100644 --- a/extra/crds.yaml +++ b/extra/crds.yaml @@ -798,23 +798,25 @@ spec: properties: hive-site.xml: additionalProperties: + nullable: true type: string + default: {} description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. This is backwards-compatible with the existing flat key-value YAML format used by `HashMap`. - nullable: true type: object security.properties: additionalProperties: + nullable: true type: string + default: {} description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. This is backwards-compatible with the existing flat key-value YAML format used by `HashMap`. - nullable: true type: object type: object envOverrides: @@ -1255,23 +1257,25 @@ spec: properties: hive-site.xml: additionalProperties: + nullable: true type: string + default: {} description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. This is backwards-compatible with the existing flat key-value YAML format used by `HashMap`. - nullable: true type: object security.properties: additionalProperties: + nullable: true type: string + default: {} description: |- Flat key-value overrides for `*.properties`, Hadoop XML, etc. This is backwards-compatible with the existing flat key-value YAML format used by `HashMap`. - nullable: true type: object type: object envOverrides: diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index edb0a913..eef9d0c4 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -82,6 +82,7 @@ use crate::{ jvm::{construct_hadoop_heapsize_env, construct_non_heap_jvm_args}, opa::{HiveOpaConfig, OPA_TLS_VOLUME_NAME}, }, + controller::build::discovery, crd::{ APP_NAME, Container, HIVE_PORT, HIVE_PORT_NAME, HiveClusterStatus, HiveRole, METRICS_PORT, METRICS_PORT_NAME, MetaStoreConfig, STACKABLE_CONFIG_DIR, STACKABLE_CONFIG_DIR_NAME, @@ -89,7 +90,6 @@ use crate::{ STACKABLE_LOG_CONFIG_MOUNT_DIR, STACKABLE_LOG_CONFIG_MOUNT_DIR_NAME, STACKABLE_LOG_DIR, STACKABLE_LOG_DIR_NAME, v1alpha1, }, - discovery::{self}, kerberos::{self, add_kerberos_pod_config, kerberos_container_start_commands}, listener::{LISTENER_VOLUME_DIR, LISTENER_VOLUME_NAME, build_role_listener}, operations::{graceful_shutdown::add_graceful_shutdown_config, pdb::add_pdbs}, @@ -189,12 +189,6 @@ pub enum Error { #[snafu(display("vector agent is enabled but vector aggregator ConfigMap is missing"))] VectorAggregatorConfigMapMissing, - #[snafu(display("failed to add the logging configuration to the ConfigMap [{cm_name}]"))] - InvalidLoggingConfig { - source: crate::product_logging::Error, - cm_name: String, - }, - #[snafu(display("failed to patch service account"))] ApplyServiceAccount { source: stackable_operator::cluster_resources::Error, diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index 363d8774..af9c23fb 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -4,18 +4,23 @@ use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, k8s_openapi::api::core::v1::ConfigMap, + product_logging::framework::VECTOR_CONFIG_FILE, role_utils::RoleGroupRef, }; use crate::{ controller::{ ValidatedCluster, - build::properties::{core_site, hive_site, resolved_overrides, security_properties}, + build::properties::{ + core_site, hive_site, logging, resolved_overrides, security_properties, + }, build_recommended_labels, }, - crd::{CORE_SITE_XML, HIVE_SITE_XML, HiveRole, JVM_SECURITY_PROPERTIES_FILE, v1alpha1}, + crd::{ + CORE_SITE_XML, HIVE_METASTORE_LOG4J2_PROPERTIES, HIVE_SITE_XML, HiveRole, + JVM_SECURITY_PROPERTIES_FILE, v1alpha1, + }, framework::writer::{to_hadoop_xml, to_java_properties_string}, - product_logging::extend_role_group_config_map, }; #[derive(Debug, Snafu)] @@ -41,12 +46,6 @@ pub enum Error { source: stackable_operator::builder::meta::Error, }, - #[snafu(display("failed to add the logging configuration to the ConfigMap {cm_name}"))] - InvalidLoggingConfig { - source: crate::product_logging::Error, - cm_name: String, - }, - #[snafu(display("failed to assemble ConfigMap for {rolegroup}"))] Assemble { source: stackable_operator::builder::configmap::Error, @@ -114,11 +113,12 @@ pub fn build_metastore_rolegroup_config_map( cm_builder.add_data(CORE_SITE_XML, to_hadoop_xml(core_site_data.iter())); } - extend_role_group_config_map(rolegroup, &rg.config.logging, &mut cm_builder).context( - InvalidLoggingConfigSnafu { - cm_name: rolegroup.object_name(), - }, - )?; + if let Some(log4j2_properties) = logging::build_log4j2(&rg.config.logging) { + cm_builder.add_data(HIVE_METASTORE_LOG4J2_PROPERTIES, log4j2_properties); + } + if let Some(vector_config) = logging::build_vector_config(rolegroup, &rg.config.logging) { + cm_builder.add_data(VECTOR_CONFIG_FILE, vector_config); + } cm_builder.build().with_context(|_| AssembleSnafu { rolegroup: rolegroup.clone(), diff --git a/rust/operator-binary/src/controller/build/mod.rs b/rust/operator-binary/src/controller/build/mod.rs index 21024b3f..8fe8557f 100644 --- a/rust/operator-binary/src/controller/build/mod.rs +++ b/rust/operator-binary/src/controller/build/mod.rs @@ -1,4 +1,5 @@ //! Builders that turn a `ValidatedCluster` into Kubernetes resources. pub mod config_map; +pub mod discovery; pub mod properties; diff --git a/rust/operator-binary/src/controller/build/properties/logging.rs b/rust/operator-binary/src/controller/build/properties/logging.rs new file mode 100644 index 00000000..7de71d3e --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/logging.rs @@ -0,0 +1,75 @@ +//! Renders the logging config files (`log4j2.properties` and the Vector agent +//! config) assembled into the rolegroup `ConfigMap`. + +use stackable_operator::{ + memory::BinaryMultiple, + product_logging::{ + self, + spec::{ + AutomaticContainerLogConfig, ContainerLogConfig, ContainerLogConfigChoice, Logging, + }, + }, + role_utils::RoleGroupRef, +}; + +use crate::{ + controller::MAX_HIVE_LOG_FILES_SIZE, + crd::{Container, STACKABLE_LOG_DIR, v1alpha1}, +}; + +const CONSOLE_CONVERSION_PATTERN: &str = "%d{ISO8601} %5p [%t] %c{2}: %m%n"; +const HIVE_LOG_FILE: &str = "hive.log4j2.xml"; + +/// Renders `log4j2.properties` for the Hive metastore container. +/// +/// Returns `None` when the Hive container does not use the operator's automatic logging +/// configuration (e.g. a custom log ConfigMap is referenced instead), in which case no +/// `log4j2.properties` should be added to the rolegroup `ConfigMap`. +pub fn build_log4j2(logging: &Logging) -> Option { + match logging.containers.get(&Container::Hive) { + Some(ContainerLogConfig { + choice: Some(ContainerLogConfigChoice::Automatic(log_config)), + }) => Some(log4j2_config(log_config)), + _ => None, + } +} + +/// Renders the Vector agent config (`vector.yaml`). +/// +/// Returns `None` when the Vector agent is disabled for this role group. +pub fn build_vector_config( + rolegroup: &RoleGroupRef, + logging: &Logging, +) -> Option { + if !logging.enable_vector_agent { + return None; + } + + let vector_log_config = match logging.containers.get(&Container::Vector) { + Some(ContainerLogConfig { + choice: Some(ContainerLogConfigChoice::Automatic(log_config)), + }) => Some(log_config), + _ => None, + }; + + Some(product_logging::framework::create_vector_config( + rolegroup, + vector_log_config, + )) +} + +fn log4j2_config(log_config: &AutomaticContainerLogConfig) -> String { + product_logging::framework::create_log4j2_config( + &format!( + "{STACKABLE_LOG_DIR}/{container}", + container = Container::Hive + ), + HIVE_LOG_FILE, + MAX_HIVE_LOG_FILES_SIZE + .scale_to(BinaryMultiple::Mebi) + .floor() + .value as u32, + CONSOLE_CONVERSION_PATTERN, + log_config, + ) +} diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index a027c11e..ca12d084 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -6,6 +6,7 @@ use stackable_operator::v2::config_overrides::KeyValueConfigOverrides; pub mod core_site; pub mod hive_site; +pub mod logging; pub mod security_properties; /// Resolve user-provided key/value overrides into `(key, value)` pairs, dropping diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 66726e2c..337a7b73 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -41,12 +41,10 @@ mod command; mod config; mod controller; mod crd; -mod discovery; mod framework; mod kerberos; mod listener; mod operations; -mod product_logging; mod service; mod webhooks; From 88e71d5b48293f6beebff547450f295342a41e32 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Thu, 4 Jun 2026 13:37:07 +0200 Subject: [PATCH 14/18] refactor: use ConfigFileName enum where possible --- .../src/controller/build/config_map.rs | 23 ++++++++------- .../src/controller/build/properties/mod.rs | 29 +++++++++++++++++++ rust/operator-binary/src/crd/mod.rs | 2 +- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index af9c23fb..481a4255 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -12,14 +12,11 @@ use crate::{ controller::{ ValidatedCluster, build::properties::{ - core_site, hive_site, logging, resolved_overrides, security_properties, + ConfigFileName, core_site, hive_site, logging, resolved_overrides, security_properties, }, build_recommended_labels, }, - crd::{ - CORE_SITE_XML, HIVE_METASTORE_LOG4J2_PROPERTIES, HIVE_SITE_XML, HiveRole, - JVM_SECURITY_PROPERTIES_FILE, v1alpha1, - }, + crd::{HiveRole, v1alpha1}, framework::writer::{to_hadoop_xml, to_java_properties_string}, }; @@ -31,7 +28,7 @@ pub enum Error { #[snafu(display("failed to build hive-site.xml"))] BuildHiveSite { source: hive_site::Error }, - #[snafu(display("failed to serialize {JVM_SECURITY_PROPERTIES_FILE}"))] + #[snafu(display("failed to serialize {}", ConfigFileName::Security))] WriteSecurityProperties { source: crate::framework::writer::PropertiesWriterError, }, @@ -101,20 +98,26 @@ pub fn build_metastore_rolegroup_config_map( .context(MetadataBuildSnafu)? .build(), ) - .add_data(HIVE_SITE_XML, to_hadoop_xml(hive_site_data.iter())) .add_data( - JVM_SECURITY_PROPERTIES_FILE, + ConfigFileName::HiveSite.to_string(), + to_hadoop_xml(hive_site_data.iter()), + ) + .add_data( + ConfigFileName::Security.to_string(), to_java_properties_string(security_data.iter()) .context(WriteSecurityPropertiesSnafu)?, ); // core-site.xml is only required when Kerberos is enabled without an HDFS backend. if let Some(core_site_data) = core_site::build(&cluster.cluster_config) { - cm_builder.add_data(CORE_SITE_XML, to_hadoop_xml(core_site_data.iter())); + cm_builder.add_data( + ConfigFileName::CoreSite.to_string(), + to_hadoop_xml(core_site_data.iter()), + ); } if let Some(log4j2_properties) = logging::build_log4j2(&rg.config.logging) { - cm_builder.add_data(HIVE_METASTORE_LOG4J2_PROPERTIES, log4j2_properties); + cm_builder.add_data(ConfigFileName::Log4j2.to_string(), log4j2_properties); } if let Some(vector_config) = logging::build_vector_config(rolegroup, &rg.config.logging) { cm_builder.add_data(VECTOR_CONFIG_FILE, vector_config); diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index ca12d084..5a7bd13c 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -19,6 +19,35 @@ pub(crate) fn resolved_overrides(overrides: KeyValueConfigOverrides) -> BTreeMap .collect() } +/// The names of the Hive config files assembled into the rolegroup `ConfigMap`. +#[derive(Clone, Copy, Debug, strum::Display)] +pub enum ConfigFileName { + #[strum(serialize = "hive-site.xml")] + HiveSite, + #[strum(serialize = "core-site.xml")] + CoreSite, + #[strum(serialize = "security.properties")] + Security, + #[strum(serialize = "metastore-log4j2.properties")] + Log4j2, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn file_names_match_the_hive_on_disk_names() { + assert_eq!(ConfigFileName::HiveSite.to_string(), "hive-site.xml"); + assert_eq!(ConfigFileName::CoreSite.to_string(), "core-site.xml"); + assert_eq!(ConfigFileName::Security.to_string(), "security.properties"); + assert_eq!( + ConfigFileName::Log4j2.to_string(), + "metastore-log4j2.properties" + ); + } +} + #[cfg(test)] pub(crate) mod test_support { use std::collections::BTreeMap; diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 0198f228..584fa94e 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -55,7 +55,7 @@ pub const STACKABLE_LOG_CONFIG_MOUNT_DIR: &str = "/stackable/mount/log-config"; pub const STACKABLE_LOG_CONFIG_MOUNT_DIR_NAME: &str = "log-config-mount"; // Config file names -pub const CORE_SITE_XML: &str = "core-site.xml"; +// TODO(@maltesander): remove once fully consolidated with ConfigFileName pub const HIVE_SITE_XML: &str = "hive-site.xml"; pub const HIVE_METASTORE_LOG4J2_PROPERTIES: &str = "metastore-log4j2.properties"; pub const JVM_SECURITY_PROPERTIES_FILE: &str = "security.properties"; From f950a0ff22c4d4ed90718b7e7d1be7e54a9201c1 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Thu, 4 Jun 2026 13:45:44 +0200 Subject: [PATCH 15/18] chore: regenerate nix --- Cargo.nix | 18 +++++++++--------- crate-hashes.json | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.nix b/Cargo.nix index ecd8da90..04fec6d1 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -4832,7 +4832,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "k8s_version"; authors = [ @@ -9502,7 +9502,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_certs"; authors = [ @@ -9714,7 +9714,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_operator"; authors = [ @@ -9899,7 +9899,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; procMacro = true; libName = "stackable_operator_derive"; @@ -9934,7 +9934,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_shared"; authors = [ @@ -10015,7 +10015,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_telemetry"; authors = [ @@ -10125,7 +10125,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_versioned"; authors = [ @@ -10175,7 +10175,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; procMacro = true; libName = "stackable_versioned_macros"; @@ -10243,7 +10243,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_webhook"; authors = [ diff --git a/crate-hashes.json b/crate-hashes.json index 362b463b..c76bf06c 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,12 +1,12 @@ { - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#k8s-version@0.1.3": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-certs@0.4.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator-derive@0.3.1": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator@0.111.1": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-shared@0.1.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-telemetry@0.6.3": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned-macros@0.10.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned@0.10.0": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-webhook@0.9.1": "14q10sppdjdf3vbcbxz12rlgm1g9l6p87nk9wr707w2a71z8vgxc", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#k8s-version@0.1.3": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-certs@0.4.0": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator-derive@0.3.1": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator@0.111.1": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-shared@0.1.0": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-telemetry@0.6.3": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned-macros@0.10.0": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned@0.10.0": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-webhook@0.9.1": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", "git+https://github.com/stackabletech/product-config.git?tag=0.8.0#product-config@0.8.0": "1dz70kapm2wdqcr7ndyjji0lhsl98bsq95gnb2lw487wf6yr7987" } \ No newline at end of file From fdee09f81179a5ba16dc78bcf9469a638f120bc0 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Thu, 4 Jun 2026 13:47:49 +0200 Subject: [PATCH 16/18] chore: adapt changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 424e049f..3ea2d003 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ All notable changes to this project will be documented in this file. - Remove the direct `product-config` dependency; `hive-site.xml`, `security.properties` and `core-site.xml` are now rendered by typed Rust builders. Switch `stackable-operator` to the `smooth-operator` branch and adopt its shared `v2::` framework ([#XXX]). - test: Bump vector-aggregator to 0.55.0, replace /graphql call with gRPC call ([#713]). - Deprecated support for `4.0.1` ([#711]). +- BREAKING: Removed product-config machinery. This is a breaking change in terms of configuration. + Users relying on the product-config `properties.yaml` file have to set these properties via the CRD ([#716]). ### Removed @@ -33,6 +35,7 @@ All notable changes to this project will be documented in this file. [#707]: https://github.com/stackabletech/hive-operator/pull/707 [#711]: https://github.com/stackabletech/hive-operator/pull/711 [#713]: https://github.com/stackabletech/hive-operator/pull/713 +[#716]: https://github.com/stackabletech/hive-operator/pull/716 ## [26.3.0] - 2026-03-16 From fbd81c2a07f193e1cdbb298f4cd70c917b7a9bf8 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Thu, 4 Jun 2026 13:49:08 +0200 Subject: [PATCH 17/18] docs: remove product config from cli & env --- .../reference/commandline-parameters.adoc | 13 ---------- .../reference/environment-variables.adoc | 26 ------------------- 2 files changed, 39 deletions(-) diff --git a/docs/modules/hive/pages/reference/commandline-parameters.adoc b/docs/modules/hive/pages/reference/commandline-parameters.adoc index 053f93b7..62ee7145 100644 --- a/docs/modules/hive/pages/reference/commandline-parameters.adoc +++ b/docs/modules/hive/pages/reference/commandline-parameters.adoc @@ -2,19 +2,6 @@ This operator accepts the following command line parameters: -== product-config - -*Default value*: `/etc/stackable/hive-operator/config-spec/properties.yaml` - -*Required*: false - -*Multiple values:* false - -[source] ----- -stackable-hive-operator run --product-config /foo/bar/properties.yaml ----- - == watch-namespace *Default value*: All namespaces diff --git a/docs/modules/hive/pages/reference/environment-variables.adoc b/docs/modules/hive/pages/reference/environment-variables.adoc index fc329cfd..61cee5e9 100644 --- a/docs/modules/hive/pages/reference/environment-variables.adoc +++ b/docs/modules/hive/pages/reference/environment-variables.adoc @@ -33,32 +33,6 @@ docker run \ oci.stackable.tech/sdp/hive-operator:0.0.0-dev ---- -== PRODUCT_CONFIG - -*Default value*: `/etc/stackable/hive-operator/config-spec/properties.yaml` - -*Required*: false - -*Multiple values*: false - -[source] ----- -export PRODUCT_CONFIG=/foo/bar/properties.yaml -stackable-hive-operator run ----- - -or via docker: - ----- -docker run \ - --name hive-operator \ - --network host \ - --env KUBECONFIG=/home/stackable/.kube/config \ - --env PRODUCT_CONFIG=/my/product/config.yaml \ - --mount type=bind,source="$HOME/.kube/config",target="/home/stackable/.kube/config" \ - oci.stackable.tech/sdp/hive-operator:0.0.0-dev ----- - == WATCH_NAMESPACE *Default value*: All namespaces From 379e88aaa3de2f62eed96be318333ec6425d4467 Mon Sep 17 00:00:00 2001 From: Andrew Kenworthy Date: Fri, 5 Jun 2026 16:08:28 +0200 Subject: [PATCH 18/18] refactor: consume the config-file writer from stackable-operator Replace the vendored java-properties/Hadoop-XML writer (rust/operator-binary/src/framework/writer.rs) with stackable_operator::v2::config_file_writer, which hosts the same code (moved there verbatim via operator-rs #1217 on the smooth-operator branch; hive's copy was byte-identical to hdfs's, the canonical source). Drop the now-unused java-properties and xml dependencies. The framework module now only contains role_utils. The base dependency tag moves from stackable-operator-0.111.0 to 0.111.1, matching the other operators; cargo only substitutes a [patch] whose package version matches, and the smooth-operator branch carries 0.111.1. No behaviour change; rendered output is byte-identical by construction (same code, new home). Co-Authored-By: Claude Opus 4.8 --- Cargo.lock | 88 ++++-- Cargo.nix | 299 ++++++++++-------- Cargo.toml | 4 +- crate-hashes.json | 4 +- rust/operator-binary/Cargo.toml | 2 - .../src/controller/build/config_map.rs | 6 +- rust/operator-binary/src/framework.rs | 1 - rust/operator-binary/src/framework/writer.rs | 145 --------- 8 files changed, 228 insertions(+), 321 deletions(-) delete mode 100644 rust/operator-binary/src/framework/writer.rs diff --git a/Cargo.lock b/Cargo.lock index d2a0549e..c41303c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1515,7 +1515,7 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "darling", "regex", @@ -1840,9 +1840,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "opentelemetry" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682" dependencies = [ "futures-core", "futures-sink", @@ -1854,9 +1854,9 @@ dependencies = [ [[package]] name = "opentelemetry-appender-tracing" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6a1ac5ca3accf562b8c306fa8483c85f4390f768185ab775f242f7fe8fdcc2" +checksum = "2c0080f0dc1d7c786f467cd85a4e395fcab11ee852004f39a29a18ab7c25d837" dependencies = [ "opentelemetry", "tracing", @@ -1866,9 +1866,9 @@ dependencies = [ [[package]] name = "opentelemetry-http" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331" dependencies = [ "async-trait", "bytes", @@ -1879,9 +1879,9 @@ dependencies = [ [[package]] name = "opentelemetry-otlp" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" +checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35" dependencies = [ "http", "opentelemetry", @@ -1893,14 +1893,14 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tonic", - "tracing", + "tonic-types", ] [[package]] name = "opentelemetry-proto" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -1911,21 +1911,22 @@ dependencies = [ [[package]] name = "opentelemetry-semantic-conventions" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e62e29dfe041afb8ed2a6c9737ab57db4907285d999ef8ad3a59092a36bdc846" +checksum = "6ca2f98a0437b427b4b08f19f1caa3c44db885a202bc12cfea13d6c702243d68" [[package]] name = "opentelemetry_sdk" -version = "0.31.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9" dependencies = [ "futures-channel", "futures-executor", "futures-util", "opentelemetry", "percent-encoding", + "portable-atomic", "rand 0.9.4", "thiserror 2.0.18", "tokio", @@ -2208,6 +2209,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost", +] + [[package]] name = "quote" version = "1.0.45" @@ -2347,9 +2357,9 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.12.28" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64", "bytes", @@ -2365,9 +2375,6 @@ dependencies = [ "log", "percent-encoding", "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", "sync_wrapper", "tokio", "tower", @@ -2887,7 +2894,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stackable-certs" version = "0.4.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "const-oid", "ecdsa", @@ -2919,7 +2926,6 @@ dependencies = [ "fnv", "futures 0.3.32", "indoc", - "java-properties", "pin-project", "rstest", "semver", @@ -2931,13 +2937,12 @@ dependencies = [ "strum", "tokio", "tracing", - "xml", ] [[package]] name = "stackable-operator" version = "0.111.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "base64", "clap", @@ -2949,6 +2954,7 @@ dependencies = [ "futures 0.3.32", "http", "indexmap", + "java-properties", "jiff", "json-patch", "k8s-openapi", @@ -2974,12 +2980,13 @@ dependencies = [ "tracing-subscriber", "url", "uuid", + "xml", ] [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "darling", "proc-macro2", @@ -2989,8 +2996,8 @@ dependencies = [ [[package]] name = "stackable-shared" -version = "0.1.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +version = "0.1.1" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "jiff", "k8s-openapi", @@ -3006,8 +3013,8 @@ dependencies = [ [[package]] name = "stackable-telemetry" -version = "0.6.3" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +version = "0.6.4" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "axum", "clap", @@ -3031,7 +3038,7 @@ dependencies = [ [[package]] name = "stackable-versioned" version = "0.10.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "kube", "schemars", @@ -3045,7 +3052,7 @@ dependencies = [ [[package]] name = "stackable-versioned-macros" version = "0.10.0" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "convert_case", "convert_case_extras", @@ -3063,7 +3070,7 @@ dependencies = [ [[package]] name = "stackable-webhook" version = "0.9.1" -source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#46cd3f93a788d44d177a8794fde91fbefa3156d7" dependencies = [ "arc-swap", "async-trait", @@ -3415,6 +3422,17 @@ dependencies = [ "tonic", ] +[[package]] +name = "tonic-types" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab1b02061f83d519bba3caa167f88f261ef05720ab8ebc954ade70de3348e8" +dependencies = [ + "prost", + "prost-types", + "tonic", +] + [[package]] name = "tower" version = "0.5.3" @@ -3526,9 +3544,9 @@ dependencies = [ [[package]] name = "tracing-opentelemetry" -version = "0.32.1" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc" +checksum = "adbc64cba7137545b8044cb1fe9814f7aacf3c6b5f9b45be8bb5db538befdb26" dependencies = [ "js-sys", "opentelemetry", diff --git a/Cargo.nix b/Cargo.nix index 04fec6d1..fe445794 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -4831,7 +4831,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "k8s_version"; @@ -6031,9 +6031,9 @@ rec { }; "opentelemetry" = rec { crateName = "opentelemetry"; - version = "0.31.0"; + version = "0.32.0"; edition = "2021"; - sha256 = "18629xsj4rsyiby9aj511q6wcw6s9m09gx3ymw1yjcvix1mcsjxq"; + sha256 = "10ln14d1jgc8rvw97mblc9blzcgpg1bimim4d170b7ia4mijq55h"; dependencies = [ { name = "futures-core"; @@ -6070,24 +6070,24 @@ rec { ]; features = { "default" = [ "trace" "metrics" "logs" "internal-logs" "futures" ]; + "experimental_metrics_bound_instruments" = [ "metrics" ]; "futures" = [ "futures-core" "futures-sink" "pin-project-lite" ]; "futures-core" = [ "dep:futures-core" ]; "futures-sink" = [ "dep:futures-sink" ]; "internal-logs" = [ "tracing" ]; "pin-project-lite" = [ "dep:pin-project-lite" ]; - "spec_unstable_logs_enabled" = [ "logs" ]; "testing" = [ "trace" ]; "thiserror" = [ "dep:thiserror" ]; "trace" = [ "futures" "thiserror" ]; "tracing" = [ "dep:tracing" ]; }; - resolvedDefaultFeatures = [ "default" "futures" "futures-core" "futures-sink" "internal-logs" "logs" "metrics" "pin-project-lite" "spec_unstable_logs_enabled" "thiserror" "trace" "tracing" ]; + resolvedDefaultFeatures = [ "default" "futures" "futures-core" "futures-sink" "internal-logs" "logs" "metrics" "pin-project-lite" "thiserror" "trace" "tracing" ]; }; "opentelemetry-appender-tracing" = rec { crateName = "opentelemetry-appender-tracing"; - version = "0.31.1"; + version = "0.32.0"; edition = "2021"; - sha256 = "1hnwizzgfhpjfnvml638yy846py8hf2gl1n3p1igbk1srb2ilspg"; + sha256 = "0dyq4myan64sl8wly02jx0gb3jjz7575mn3w8rpphz0xvkq8001c"; libName = "opentelemetry_appender_tracing"; dependencies = [ { @@ -6130,18 +6130,15 @@ rec { ]; features = { "experimental_metadata_attributes" = [ "dep:tracing-log" ]; - "experimental_use_tracing_span_context" = [ "tracing-opentelemetry" ]; "log" = [ "dep:log" ]; - "spec_unstable_logs_enabled" = [ "opentelemetry/spec_unstable_logs_enabled" ]; - "tracing-opentelemetry" = [ "dep:tracing-opentelemetry" ]; }; resolvedDefaultFeatures = [ "default" ]; }; "opentelemetry-http" = rec { crateName = "opentelemetry-http"; - version = "0.31.0"; + version = "0.32.0"; edition = "2021"; - sha256 = "0pc5nw1ds8v8w0nvyall39m92v8m1xl1p3vwvxk6nkhrffdd19np"; + sha256 = "0ca3drvm4fx5nskl7yn42dimy3bg35ppzc85y1p27pz215fh30sn"; libName = "opentelemetry_http"; dependencies = [ { @@ -6177,16 +6174,16 @@ rec { "internal-logs" = [ "opentelemetry/internal-logs" ]; "reqwest" = [ "dep:reqwest" ]; "reqwest-blocking" = [ "dep:reqwest" "reqwest/blocking" ]; - "reqwest-rustls" = [ "dep:reqwest" "reqwest/rustls-tls-native-roots" ]; - "reqwest-rustls-webpki-roots" = [ "dep:reqwest" "reqwest/rustls-tls-webpki-roots" ]; + "reqwest-rustls" = [ "dep:reqwest" "reqwest/default-tls" ]; + "reqwest-rustls-webpki-roots" = [ "dep:reqwest" "reqwest/default-tls" "reqwest/webpki-roots" ]; }; - resolvedDefaultFeatures = [ "internal-logs" "reqwest" "reqwest-blocking" ]; + resolvedDefaultFeatures = [ "reqwest" "reqwest-blocking" ]; }; "opentelemetry-otlp" = rec { crateName = "opentelemetry-otlp"; - version = "0.31.1"; + version = "0.32.0"; edition = "2021"; - sha256 = "07zp0b62b9dajnvvcd6j2ppw5zg7wp4ixka9z6fr3bxrrdmcss8z"; + sha256 = "0d9cys2flpidfxbr6h1103hjc633cax47ihnqgbj0xnicscr4rlr"; libName = "opentelemetry_otlp"; dependencies = [ { @@ -6247,10 +6244,9 @@ rec { usesDefaultFeatures = false; } { - name = "tracing"; - packageId = "tracing"; + name = "tonic-types"; + packageId = "tonic-types"; optional = true; - usesDefaultFeatures = false; } ]; devDependencies = [ @@ -6275,16 +6271,19 @@ rec { ]; features = { "default" = [ "http-proto" "reqwest-blocking-client" "trace" "metrics" "logs" "internal-logs" ]; + "experimental-grpc-retry" = [ "grpc-tonic" "opentelemetry_sdk/experimental_async_runtime" "opentelemetry_sdk/rt-tokio" ]; + "experimental-http-retry" = [ "opentelemetry_sdk/experimental_async_runtime" "opentelemetry_sdk/rt-tokio" "tokio" "httpdate" ]; "flate2" = [ "dep:flate2" ]; - "grpc-tonic" = [ "tonic" "prost" "http" "tokio" "opentelemetry-proto/gen-tonic" ]; + "grpc-tonic" = [ "tonic" "tonic-types" "prost" "http" "tokio" "opentelemetry-proto/gen-tonic" ]; "gzip-http" = [ "flate2" ]; "gzip-tonic" = [ "tonic/gzip" ]; "http" = [ "dep:http" ]; "http-json" = [ "serde_json" "prost" "opentelemetry-http" "opentelemetry-proto/gen-tonic-messages" "opentelemetry-proto/with-serde" "http" "trace" "metrics" ]; "http-proto" = [ "prost" "opentelemetry-http" "opentelemetry-proto/gen-tonic-messages" "http" "trace" "metrics" ]; + "httpdate" = [ "dep:httpdate" ]; "hyper-client" = [ "opentelemetry-http/hyper" ]; "integration-testing" = [ "tonic" "prost" "tokio/full" "trace" "logs" ]; - "internal-logs" = [ "tracing" "opentelemetry_sdk/internal-logs" "opentelemetry-http/internal-logs" ]; + "internal-logs" = [ "opentelemetry_sdk/internal-logs" "opentelemetry/internal-logs" ]; "logs" = [ "opentelemetry/logs" "opentelemetry_sdk/logs" "opentelemetry-proto/logs" ]; "metrics" = [ "opentelemetry/metrics" "opentelemetry_sdk/metrics" "opentelemetry-proto/metrics" ]; "opentelemetry-http" = [ "dep:opentelemetry-http" ]; @@ -6297,27 +6296,27 @@ rec { "serde" = [ "dep:serde" ]; "serde_json" = [ "dep:serde_json" ]; "serialize" = [ "serde" "serde_json" ]; - "tls" = [ "tonic/tls-ring" ]; + "tls" = [ "tls-ring" ]; "tls-aws-lc" = [ "tonic/tls-aws-lc" ]; "tls-provider-agnostic" = [ "tonic/_tls-any" ]; "tls-ring" = [ "tonic/tls-ring" ]; - "tls-roots" = [ "tls" "tonic/tls-native-roots" ]; - "tls-webpki-roots" = [ "tls" "tonic/tls-webpki-roots" ]; + "tls-roots" = [ "tonic/tls-native-roots" ]; + "tls-webpki-roots" = [ "tonic/tls-webpki-roots" ]; "tokio" = [ "dep:tokio" ]; "tonic" = [ "dep:tonic" ]; + "tonic-types" = [ "dep:tonic-types" ]; "trace" = [ "opentelemetry/trace" "opentelemetry_sdk/trace" "opentelemetry-proto/trace" ]; - "tracing" = [ "dep:tracing" ]; "zstd" = [ "dep:zstd" ]; "zstd-http" = [ "zstd" ]; "zstd-tonic" = [ "tonic/zstd" ]; }; - resolvedDefaultFeatures = [ "default" "grpc-tonic" "gzip-tonic" "http" "http-proto" "internal-logs" "logs" "metrics" "opentelemetry-http" "prost" "reqwest" "reqwest-blocking-client" "tokio" "tonic" "trace" "tracing" ]; + resolvedDefaultFeatures = [ "default" "grpc-tonic" "gzip-tonic" "http" "http-proto" "internal-logs" "logs" "metrics" "opentelemetry-http" "prost" "reqwest" "reqwest-blocking-client" "tokio" "tonic" "tonic-types" "trace" ]; }; "opentelemetry-proto" = rec { crateName = "opentelemetry-proto"; - version = "0.31.0"; + version = "0.32.0"; edition = "2021"; - sha256 = "03xkjsjrsm7zkkx5gascqd9bg2z20wymm06l16cyxsp5dpq5s5x7"; + sha256 = "0f5ny4rpnpq6q5q34b8k2q548rf31rpbxkwjqjwzfqxg3yx5imjn"; libName = "opentelemetry_proto"; dependencies = [ { @@ -6361,30 +6360,29 @@ rec { "const-hex" = [ "dep:const-hex" ]; "default" = [ "full" ]; "full" = [ "gen-tonic" "trace" "logs" "metrics" "zpages" "with-serde" "internal-logs" ]; - "gen-tonic" = [ "gen-tonic-messages" "tonic/channel" ]; - "gen-tonic-messages" = [ "tonic" "tonic-prost" "prost" ]; + "gen-tonic" = [ "gen-tonic-messages" "tonic" "tonic-prost" "tonic/channel" ]; + "gen-tonic-messages" = [ "prost" ]; "internal-logs" = [ "opentelemetry/internal-logs" ]; "logs" = [ "opentelemetry/logs" "opentelemetry_sdk/logs" ]; "metrics" = [ "opentelemetry/metrics" "opentelemetry_sdk/metrics" ]; "prost" = [ "dep:prost" ]; "schemars" = [ "dep:schemars" ]; "serde" = [ "dep:serde" ]; - "serde_json" = [ "dep:serde_json" ]; "testing" = [ "opentelemetry/testing" ]; "tonic" = [ "dep:tonic" ]; "tonic-prost" = [ "dep:tonic-prost" ]; "trace" = [ "opentelemetry/trace" "opentelemetry_sdk/trace" ]; "with-schemars" = [ "schemars" ]; - "with-serde" = [ "serde" "const-hex" "base64" "serde_json" ]; + "with-serde" = [ "serde" "const-hex" "base64" ]; "zpages" = [ "trace" ]; }; resolvedDefaultFeatures = [ "gen-tonic" "gen-tonic-messages" "logs" "metrics" "prost" "tonic" "tonic-prost" "trace" ]; }; "opentelemetry-semantic-conventions" = rec { crateName = "opentelemetry-semantic-conventions"; - version = "0.31.0"; + version = "0.32.0"; edition = "2021"; - sha256 = "0in8plv2l2ar7anzi7lrbll0fjfvaymkg5vc5bnvibs1w3gjjbp6"; + sha256 = "0s1x4h1cgmhkxb7i5g02la2vhkf4lg5g26cgn2s2gd1p0j5gk8kc"; libName = "opentelemetry_semantic_conventions"; features = { }; @@ -6392,9 +6390,9 @@ rec { }; "opentelemetry_sdk" = rec { crateName = "opentelemetry_sdk"; - version = "0.31.0"; + version = "0.32.1"; edition = "2021"; - sha256 = "1gbjsggdxfpjbanjvaxa3nq32vfa37i3v13dvx4gsxhrk7sy8jp1"; + sha256 = "1ycl11syranrinhgn4c2hlzhyzyvpa06ryxq5mxgzmf4387ghncv"; dependencies = [ { name = "futures-channel"; @@ -6420,6 +6418,13 @@ rec { packageId = "percent-encoding"; optional = true; } + { + name = "portable-atomic"; + packageId = "portable-atomic"; + usesDefaultFeatures = false; + target = { target, features }: (!("64" == target."has_atomic" or null)); + features = [ "fallback" ]; + } { name = "rand"; packageId = "rand 0.9.4"; @@ -6444,10 +6449,18 @@ rec { optional = true; } ]; + devDependencies = [ + { + name = "tokio"; + packageId = "tokio"; + usesDefaultFeatures = false; + features = [ "macros" "rt-multi-thread" ]; + } + ]; features = { "default" = [ "trace" "metrics" "logs" "internal-logs" ]; "experimental_logs_batch_log_processor_with_async_runtime" = [ "logs" "experimental_async_runtime" ]; - "experimental_logs_concurrent_log_processor" = [ "logs" ]; + "experimental_metrics_bound_instruments" = [ "metrics" "opentelemetry/experimental_metrics_bound_instruments" ]; "experimental_metrics_custom_reader" = [ "metrics" ]; "experimental_metrics_disable_name_validation" = [ "metrics" ]; "experimental_metrics_periodicreader_with_async_runtime" = [ "metrics" "experimental_async_runtime" ]; @@ -6464,15 +6477,14 @@ rec { "rt-tokio-current-thread" = [ "tokio/rt" "tokio/time" "tokio-stream" "experimental_async_runtime" ]; "serde" = [ "dep:serde" ]; "serde_json" = [ "dep:serde_json" ]; - "spec_unstable_logs_enabled" = [ "logs" "opentelemetry/spec_unstable_logs_enabled" ]; "spec_unstable_metrics_views" = [ "metrics" ]; - "testing" = [ "opentelemetry/testing" "trace" "metrics" "logs" "rt-tokio" "rt-tokio-current-thread" "tokio/macros" "tokio/rt-multi-thread" ]; + "testing" = [ "opentelemetry/testing" "trace" "metrics" "logs" "tokio/sync" ]; "tokio" = [ "dep:tokio" ]; "tokio-stream" = [ "dep:tokio-stream" ]; "trace" = [ "opentelemetry/trace" "rand" "percent-encoding" ]; "url" = [ "dep:url" ]; }; - resolvedDefaultFeatures = [ "default" "experimental_async_runtime" "internal-logs" "logs" "metrics" "percent-encoding" "rand" "rt-tokio" "spec_unstable_logs_enabled" "tokio" "tokio-stream" "trace" ]; + resolvedDefaultFeatures = [ "default" "experimental_async_runtime" "internal-logs" "logs" "metrics" "percent-encoding" "rand" "rt-tokio" "tokio" "tokio-stream" "trace" ]; }; "ordered-float" = rec { crateName = "ordered-float"; @@ -6981,7 +6993,7 @@ rec { "default" = [ "fallback" ]; "serde" = [ "dep:serde" ]; }; - resolvedDefaultFeatures = [ "require-cas" ]; + resolvedDefaultFeatures = [ "fallback" "require-cas" ]; }; "portable-atomic-util" = rec { crateName = "portable-atomic-util"; @@ -7249,6 +7261,34 @@ rec { ]; }; + "prost-types" = rec { + crateName = "prost-types"; + version = "0.14.3"; + edition = "2021"; + sha256 = "1mrxrciryfgi6a0vmrgyj3g27r9hdhlgwkq71cgv3icbvg5w94c9"; + libName = "prost_types"; + authors = [ + "Dan Burkert " + "Lucio Franco " + "Casper Meijn " + "Tokio Contributors " + ]; + dependencies = [ + { + name = "prost"; + packageId = "prost"; + usesDefaultFeatures = false; + features = [ "derive" ]; + } + ]; + features = { + "arbitrary" = [ "dep:arbitrary" ]; + "chrono" = [ "dep:chrono" ]; + "default" = [ "std" ]; + "std" = [ "prost/std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "quote" = rec { crateName = "quote"; version = "1.0.45"; @@ -7678,9 +7718,9 @@ rec { }; "reqwest" = rec { crateName = "reqwest"; - version = "0.12.28"; + version = "0.13.4"; edition = "2021"; - sha256 = "0iqidijghgqbzl3bjg5hb4zmigwa4r612bgi0yiq0c90b6jkrpgd"; + sha256 = "1hy1plns9krbh3h1dy2sdjygsfkdcnxm6pbxdi0ya9b5vq8mi711"; authors = [ "Sean McArthur " ]; @@ -7697,7 +7737,7 @@ rec { name = "futures-channel"; packageId = "futures-channel"; optional = true; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "futures-core"; @@ -7717,62 +7757,44 @@ rec { { name = "http-body"; packageId = "http-body"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "http-body-util"; packageId = "http-body-util"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "hyper"; packageId = "hyper"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "http1" "client" ]; } { name = "hyper-util"; packageId = "hyper-util"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "http1" "client" "client-legacy" "client-proxy" "tokio" ]; } { name = "js-sys"; packageId = "js-sys"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); } { name = "log"; packageId = "log"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "percent-encoding"; packageId = "percent-encoding"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "pin-project-lite"; packageId = "pin-project-lite"; - target = { target, features }: (!("wasm32" == target."arch" or null)); - } - { - name = "serde"; - packageId = "serde"; - } - { - name = "serde_json"; - packageId = "serde_json"; - optional = true; - } - { - name = "serde_json"; - packageId = "serde_json"; - target = { target, features }: ("wasm32" == target."arch" or null); - } - { - name = "serde_urlencoded"; - packageId = "serde_urlencoded"; + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "sync_wrapper"; @@ -7783,27 +7805,27 @@ rec { name = "tokio"; packageId = "tokio"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "net" "time" ]; } { name = "tower"; packageId = "tower"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "retry" "timeout" "util" ]; } { name = "tower-http"; packageId = "tower-http"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "follow-redirect" ]; } { name = "tower-service"; packageId = "tower-service"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); } { name = "url"; @@ -7812,17 +7834,17 @@ rec { { name = "wasm-bindgen"; packageId = "wasm-bindgen"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); } { name = "wasm-bindgen-futures"; packageId = "wasm-bindgen-futures"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); } { name = "web-sys"; packageId = "web-sys"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); features = [ "AbortController" "AbortSignal" "Headers" "Request" "RequestInit" "RequestMode" "Response" "Window" "FormData" "Blob" "BlobPropertyBag" "ServiceWorkerGlobalScope" "RequestCredentials" "File" "ReadableStream" "RequestCache" ]; } ]; @@ -7831,33 +7853,27 @@ rec { name = "futures-util"; packageId = "futures-util"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "std" "alloc" ]; } { name = "hyper"; packageId = "hyper"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "http1" "http2" "client" "server" ]; } { name = "hyper-util"; packageId = "hyper-util"; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "http1" "http2" "client" "client-legacy" "server-auto" "server-graceful" "tokio" ]; } - { - name = "serde"; - packageId = "serde"; - target = { target, features }: (!("wasm32" == target."arch" or null)); - features = [ "derive" ]; - } { name = "tokio"; packageId = "tokio"; usesDefaultFeatures = false; - target = { target, features }: (!("wasm32" == target."arch" or null)); + target = { target, features }: (!(("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null)))); features = [ "macros" "rt-multi-thread" ]; } { @@ -7869,40 +7885,37 @@ rec { { name = "wasm-bindgen"; packageId = "wasm-bindgen"; - target = { target, features }: ("wasm32" == target."arch" or null); + target = { target, features }: (("wasm32" == target."arch" or null) && (("unknown" == target."os" or null) || ("none" == target."os" or null))); features = [ "serde-serialize" ]; } ]; features = { + "__native-tls" = [ "dep:hyper-tls" "dep:native-tls-crate" "__tls" "dep:tokio-native-tls" ]; + "__native-tls-alpn" = [ "native-tls-crate?/alpn" "hyper-tls?/alpn" ]; "__rustls" = [ "dep:hyper-rustls" "dep:tokio-rustls" "dep:rustls" "__tls" ]; - "__rustls-ring" = [ "hyper-rustls?/ring" "tokio-rustls?/ring" "rustls?/ring" "quinn?/ring" ]; + "__rustls-aws-lc-rs" = [ "hyper-rustls?/aws-lc-rs" "tokio-rustls?/aws-lc-rs" "rustls?/aws-lc-rs" "quinn?/rustls-aws-lc-rs" ]; "__tls" = [ "dep:rustls-pki-types" "tokio/io-util" ]; "blocking" = [ "dep:futures-channel" "futures-channel?/sink" "dep:futures-util" "futures-util?/io" "futures-util?/sink" "tokio/sync" ]; "brotli" = [ "tower-http/decompression-br" ]; "charset" = [ "dep:encoding_rs" "dep:mime" ]; "cookies" = [ "dep:cookie_crate" "dep:cookie_store" ]; "default" = [ "default-tls" "charset" "http2" "system-proxy" ]; - "default-tls" = [ "dep:hyper-tls" "dep:native-tls-crate" "__tls" "dep:tokio-native-tls" ]; + "default-tls" = [ "rustls" ]; "deflate" = [ "tower-http/decompression-deflate" ]; + "form" = [ "dep:serde" "dep:serde_urlencoded" ]; "gzip" = [ "tower-http/decompression-gzip" ]; - "h2" = [ "dep:h2" ]; "hickory-dns" = [ "dep:hickory-resolver" "dep:once_cell" ]; - "http2" = [ "h2" "hyper/http2" "hyper-util/http2" "hyper-rustls?/http2" ]; - "http3" = [ "rustls-tls-manual-roots" "dep:h3" "dep:h3-quinn" "dep:quinn" "tokio/macros" ]; - "json" = [ "dep:serde_json" ]; - "macos-system-configuration" = [ "system-proxy" ]; + "http2" = [ "dep:h2" "hyper/http2" "hyper-util/http2" "hyper-rustls?/http2" ]; + "http3" = [ "rustls" "dep:h3" "dep:h3-quinn" "dep:quinn" "tokio/macros" ]; + "json" = [ "dep:serde" "dep:serde_json" ]; "multipart" = [ "dep:mime_guess" "dep:futures-util" ]; - "native-tls" = [ "default-tls" ]; - "native-tls-alpn" = [ "native-tls" "native-tls-crate?/alpn" "hyper-tls?/alpn" ]; - "native-tls-vendored" = [ "native-tls" "native-tls-crate?/vendored" ]; - "rustls-tls" = [ "rustls-tls-webpki-roots" ]; - "rustls-tls-manual-roots" = [ "rustls-tls-manual-roots-no-provider" "__rustls-ring" ]; - "rustls-tls-manual-roots-no-provider" = [ "__rustls" ]; - "rustls-tls-native-roots" = [ "rustls-tls-native-roots-no-provider" "__rustls-ring" ]; - "rustls-tls-native-roots-no-provider" = [ "dep:rustls-native-certs" "hyper-rustls?/native-tokio" "__rustls" ]; - "rustls-tls-no-provider" = [ "rustls-tls-manual-roots-no-provider" ]; - "rustls-tls-webpki-roots" = [ "rustls-tls-webpki-roots-no-provider" "__rustls-ring" ]; - "rustls-tls-webpki-roots-no-provider" = [ "dep:webpki-roots" "hyper-rustls?/webpki-tokio" "__rustls" ]; + "native-tls" = [ "__native-tls" "__native-tls-alpn" ]; + "native-tls-no-alpn" = [ "__native-tls" ]; + "native-tls-vendored" = [ "__native-tls" "native-tls-crate?/vendored" "__native-tls-alpn" ]; + "native-tls-vendored-no-alpn" = [ "__native-tls" "native-tls-crate?/vendored" ]; + "query" = [ "dep:serde" "dep:serde_urlencoded" ]; + "rustls" = [ "__rustls-aws-lc-rs" "dep:rustls-platform-verifier" "__rustls" ]; + "rustls-no-provider" = [ "dep:rustls-platform-verifier" "__rustls" ]; "stream" = [ "tokio/fs" "dep:futures-util" "dep:tokio-util" "dep:wasm-streams" ]; "system-proxy" = [ "hyper-util/client-proxy-system" ]; "zstd" = [ "tower-http/decompression-zstd" ]; @@ -9501,7 +9514,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_certs"; @@ -9638,10 +9651,6 @@ rec { name = "indoc"; packageId = "indoc"; } - { - name = "java-properties"; - packageId = "java-properties"; - } { name = "pin-project"; packageId = "pin-project"; @@ -9682,10 +9691,6 @@ rec { name = "tracing"; packageId = "tracing"; } - { - name = "xml"; - packageId = "xml"; - } ]; buildDependencies = [ { @@ -9713,7 +9718,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_operator"; @@ -9764,6 +9769,10 @@ rec { name = "indexmap"; packageId = "indexmap"; } + { + name = "java-properties"; + packageId = "java-properties"; + } { name = "jiff"; packageId = "jiff"; @@ -9879,12 +9888,17 @@ rec { name = "uuid"; packageId = "uuid"; } + { + name = "xml"; + packageId = "xml"; + } ]; features = { "certs" = [ "dep:stackable-certs" ]; + "client-feature-gates" = [ "dep:winnow" ]; "crds" = [ "dep:stackable-versioned" ]; "default" = [ "crds" ]; - "full" = [ "crds" "certs" "time" "webhook" "kube-ws" ]; + "full" = [ "client-feature-gates" "crds" "certs" "time" "webhook" "kube-ws" ]; "kube-ws" = [ "kube/ws" ]; "time" = [ "stackable-shared/time" ]; "webhook" = [ "dep:stackable-webhook" ]; @@ -9898,7 +9912,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; procMacro = true; @@ -9928,12 +9942,12 @@ rec { }; "stackable-shared" = rec { crateName = "stackable-shared"; - version = "0.1.0"; + version = "0.1.1"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_shared"; @@ -10009,12 +10023,12 @@ rec { }; "stackable-telemetry" = rec { crateName = "stackable-telemetry"; - version = "0.6.3"; + version = "0.6.4"; edition = "2024"; workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_telemetry"; @@ -10058,7 +10072,7 @@ rec { { name = "opentelemetry_sdk"; packageId = "opentelemetry_sdk"; - features = [ "rt-tokio" "logs" "rt-tokio" "spec_unstable_logs_enabled" ]; + features = [ "rt-tokio" "logs" "rt-tokio" ]; } { name = "pin-project"; @@ -10124,7 +10138,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_versioned"; @@ -10174,7 +10188,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; procMacro = true; @@ -10242,7 +10256,7 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; - rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; + rev = "46cd3f93a788d44d177a8794fde91fbefa3156d7"; sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_webhook"; @@ -11406,6 +11420,33 @@ rec { } ]; + }; + "tonic-types" = rec { + crateName = "tonic-types"; + version = "0.14.6"; + edition = "2024"; + sha256 = "1s286gg71pjajny8xar0azq1w9lgz1ks3jm3pccxb0qz0q11pavk"; + libName = "tonic_types"; + authors = [ + "Lucio Franco " + "Rafael Lemos " + ]; + dependencies = [ + { + name = "prost"; + packageId = "prost"; + } + { + name = "prost-types"; + packageId = "prost-types"; + } + { + name = "tonic"; + packageId = "tonic"; + usesDefaultFeatures = false; + } + ]; + }; "tower" = rec { crateName = "tower"; @@ -11860,9 +11901,9 @@ rec { }; "tracing-opentelemetry" = rec { crateName = "tracing-opentelemetry"; - version = "0.32.1"; + version = "0.33.0"; edition = "2021"; - sha256 = "1z2jjmxbkm1qawlb3bm99x8xwf4g8wjkbcknm9z4fv1w14nqzhhs"; + sha256 = "09nvxy5m7nxmifz4b6szdcyczapp2jcgxcac0jw4ax8klz5n9g5d"; libName = "tracing_opentelemetry"; dependencies = [ { diff --git a/Cargo.toml b/Cargo.toml index 860878d3..834987d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" repository = "https://github.com/stackabletech/hive-operator" [workspace.dependencies] -stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.111.0", features = ["crds", "webhook"] } +stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.111.1", features = ["crds", "webhook"] } anyhow = "1.0" built = { version = "0.8", features = ["chrono", "git2"] } @@ -19,7 +19,6 @@ const_format = "0.2" fnv = "1.0" futures = { version = "0.3", features = ["compat"] } indoc = "2.0" -java-properties = "2.0" pin-project = "1.1" rstest = "0.26" semver = "1.0" @@ -30,7 +29,6 @@ snafu = "0.9" strum = { version = "0.28", features = ["derive"] } tokio = { version = "1.52", features = ["full"] } tracing = "0.1" -xml = "1.3" [patch."https://github.com/stackabletech/operator-rs.git"] stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "smooth-operator" } diff --git a/crate-hashes.json b/crate-hashes.json index c76bf06c..cd03561e 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -3,8 +3,8 @@ "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-certs@0.4.0": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator-derive@0.3.1": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator@0.111.1": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-shared@0.1.0": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-telemetry@0.6.3": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-shared@0.1.1": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-telemetry@0.6.4": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned-macros@0.10.0": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned@0.10.0": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-webhook@0.9.1": "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96", diff --git a/rust/operator-binary/Cargo.toml b/rust/operator-binary/Cargo.toml index 8583dedd..e3e8eb36 100644 --- a/rust/operator-binary/Cargo.toml +++ b/rust/operator-binary/Cargo.toml @@ -17,7 +17,6 @@ const_format.workspace = true fnv.workspace = true futures.workspace = true indoc.workspace = true -java-properties.workspace = true pin-project.workspace = true semver.workspace = true serde.workspace = true @@ -26,7 +25,6 @@ snafu.workspace = true strum.workspace = true tokio.workspace = true tracing.workspace = true -xml.workspace = true [dev-dependencies] rstest.workspace = true diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index 481a4255..30a4e184 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -6,6 +6,7 @@ use stackable_operator::{ k8s_openapi::api::core::v1::ConfigMap, product_logging::framework::VECTOR_CONFIG_FILE, role_utils::RoleGroupRef, + v2::config_file_writer::{PropertiesWriterError, to_hadoop_xml, to_java_properties_string}, }; use crate::{ @@ -17,7 +18,6 @@ use crate::{ build_recommended_labels, }, crd::{HiveRole, v1alpha1}, - framework::writer::{to_hadoop_xml, to_java_properties_string}, }; #[derive(Debug, Snafu)] @@ -29,9 +29,7 @@ pub enum Error { BuildHiveSite { source: hive_site::Error }, #[snafu(display("failed to serialize {}", ConfigFileName::Security))] - WriteSecurityProperties { - source: crate::framework::writer::PropertiesWriterError, - }, + WriteSecurityProperties { source: PropertiesWriterError }, #[snafu(display("object is missing metadata to build owner reference"))] ObjectMissingMetadataForOwnerRef { diff --git a/rust/operator-binary/src/framework.rs b/rust/operator-binary/src/framework.rs index 19b9d132..75d7a9cb 100644 --- a/rust/operator-binary/src/framework.rs +++ b/rust/operator-binary/src/framework.rs @@ -11,4 +11,3 @@ //! relaxes the `Merge` bound. pub mod role_utils; -pub mod writer; diff --git a/rust/operator-binary/src/framework/writer.rs b/rust/operator-binary/src/framework/writer.rs deleted file mode 100644 index 08250f9f..00000000 --- a/rust/operator-binary/src/framework/writer.rs +++ /dev/null @@ -1,145 +0,0 @@ -//! Writers for Hadoop XML config files and Java `.properties` files. -//! -//! Vendored from the `product-config` crate's `writer` module so the operator no -//! longer depends on `product-config` for rendering. - -use std::io::Write; - -use java_properties::{PropertiesError, PropertiesWriter}; -use snafu::{ResultExt, Snafu}; -use xml::escape::escape_str_attribute; - -#[derive(Debug, Snafu)] -pub enum PropertiesWriterError { - #[snafu(display("failed to create properties file"))] - Properties { source: PropertiesError }, - - #[snafu(display("failed to convert properties file byte array to UTF-8"))] - FromUtf8 { source: std::string::FromUtf8Error }, -} - -/// Creates a common Java properties file string in the format: -/// `property_1=value_1\nproperty_2=value_2\n`. -pub fn to_java_properties_string<'a, T>(properties: T) -> Result -where - T: Iterator)>, -{ - let mut output = Vec::new(); - write_java_properties(&mut output, properties)?; - String::from_utf8(output).context(FromUtf8Snafu) -} - -/// Writes Java properties to the given writer. A `None` value is written as an -/// empty value (`key=`). -fn write_java_properties<'a, W, T>(writer: W, properties: T) -> Result<(), PropertiesWriterError> -where - W: Write, - T: Iterator)>, -{ - let mut writer = PropertiesWriter::new(writer); - for (k, v) in properties { - let property_value = v.as_deref().unwrap_or_default(); - writer.write(k, property_value).context(PropertiesSnafu)?; - } - writer.flush().context(PropertiesSnafu)?; - Ok(()) -} - -/// Converts properties into a Hadoop configuration XML, including the wrapping -/// `...` elements. Properties with a `None` value -/// are skipped. Keys and values are XML-escaped. -pub fn to_hadoop_xml<'a, T>(properties: T) -> String -where - T: Iterator)>, -{ - let mut snippet = String::new(); - for (k, v) in properties { - let escaped_value = match v { - Some(value) => escape_str_attribute(value), - None => continue, - }; - let escaped_key = escape_str_attribute(k); - snippet.push_str(&format!( - " \n {escaped_key}\n {escaped_value}\n \n" - )); - } - format!("\n\n{snippet}") -} - -#[cfg(test)] -mod tests { - use std::collections::BTreeMap; - - use super::*; - - fn xml(pairs: &[(&str, Option<&str>)]) -> String { - let map: BTreeMap> = pairs - .iter() - .map(|(k, v)| (k.to_string(), v.map(str::to_string))) - .collect(); - to_hadoop_xml(map.iter()) - } - - fn props(pairs: &[(&str, Option<&str>)]) -> String { - let map: BTreeMap> = pairs - .iter() - .map(|(k, v)| (k.to_string(), v.map(str::to_string))) - .collect(); - to_java_properties_string(map.iter()).unwrap() - } - - #[test] - fn hadoop_xml_wraps_empty_configuration() { - assert_eq!( - xml(&[]), - "\n\n" - ); - } - - #[test] - fn hadoop_xml_renders_single_property() { - assert_eq!( - xml(&[("fs.defaultFS", Some("hdfs://hdfs/"))]), - "\n\n \ - \n fs.defaultFS\n \ - hdfs://hdfs/\n \n" - ); - } - - #[test] - fn hadoop_xml_skips_none_values() { - assert_eq!( - xml(&[("kept", Some("1")), ("dropped", None)]), - "\n\n \ - \n kept\n \ - 1\n \n" - ); - } - - #[test] - fn hadoop_xml_escapes_special_characters() { - let rendered = xml(&[("k", Some("&b"))]); - assert!( - rendered.contains("<a>&b"), - "{rendered}" - ); - } - - #[test] - fn java_properties_renders_key_value() { - assert_eq!(props(&[("a", Some("1")), ("b", Some("2"))]), "a=1\nb=2\n"); - } - - #[test] - fn java_properties_renders_none_as_empty() { - assert_eq!(props(&[("none", None)]), "none=\n"); - } - - #[test] - fn java_properties_escapes_colon_in_value() { - assert_eq!( - props(&[("url", Some("file://this/location/file.abc"))]), - "url=file\\://this/location/file.abc\n" - ); - } -}