From b590cda24b4aa7d1cf9cc582c5102ae4b36da4e6 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 18:29:19 +0200 Subject: [PATCH 01/18] chore(deps): switch stackable-operator to smooth-operator branch Patches stackable-operator to the operator-rs smooth-operator branch (provides the v2::config_overrides framework) as the prerequisite for removing the product-config dependency, mirroring trino-operator. Co-Authored-By: Claude Opus 4.8 (1M context) --- Cargo.lock | 30 +++++++++---- Cargo.nix | 112 ++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 1 + crate-hashes.json | 18 ++++---- 4 files changed, 124 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f0ca7fc..f1428a79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1473,6 +1473,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f300e415e2134745ef75f04562dd0145405c2f7fd92065db029ac4b16b57fe90" dependencies = [ "jsonptr", + "schemars", "serde", "serde_json", "thiserror 1.0.69", @@ -1517,7 +1518,7 @@ dependencies = [ [[package]] name = "k8s-version" version = "0.1.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "darling", "regex", @@ -2880,7 +2881,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.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "const-oid", "ecdsa", @@ -2927,7 +2928,7 @@ dependencies = [ [[package]] name = "stackable-operator" version = "0.111.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "base64", "clap", @@ -2963,12 +2964,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.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "darling", "proc-macro2", @@ -2979,7 +2981,7 @@ dependencies = [ [[package]] name = "stackable-shared" version = "0.1.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "jiff", "k8s-openapi", @@ -2996,7 +2998,7 @@ dependencies = [ [[package]] name = "stackable-telemetry" version = "0.6.3" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "axum", "clap", @@ -3020,7 +3022,7 @@ dependencies = [ [[package]] name = "stackable-versioned" version = "0.10.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "kube", "schemars", @@ -3034,7 +3036,7 @@ dependencies = [ [[package]] name = "stackable-versioned-macros" version = "0.10.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "convert_case", "convert_case_extras", @@ -3052,7 +3054,7 @@ dependencies = [ [[package]] name = "stackable-webhook" version = "0.9.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#7a5f0c3fbcd091340214a23f0607fcd4b4fcc152" +source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#a31cd2514445b251038fc4ea7abc28c57b2a6ad9" dependencies = [ "arc-swap", "async-trait", @@ -3638,6 +3640,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" diff --git a/Cargo.nix b/Cargo.nix index 8f272641..0b4d74ac 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -4667,6 +4667,11 @@ rec { name = "jsonptr"; packageId = "jsonptr"; } + { + name = "schemars"; + packageId = "schemars"; + optional = true; + } { name = "serde"; packageId = "serde"; @@ -4682,6 +4687,10 @@ rec { } ]; devDependencies = [ + { + name = "schemars"; + packageId = "schemars"; + } { name = "serde_json"; packageId = "serde_json"; @@ -4693,7 +4702,7 @@ rec { "schemars" = [ "dep:schemars" ]; "utoipa" = [ "dep:utoipa" ]; }; - resolvedDefaultFeatures = [ "default" "diff" ]; + resolvedDefaultFeatures = [ "default" "diff" "schemars" ]; }; "jsonpath-rust" = rec { crateName = "jsonpath-rust"; @@ -4819,8 +4828,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "k8s_version"; @@ -9467,8 +9476,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_certs"; @@ -9668,8 +9677,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_operator"; @@ -9727,6 +9736,7 @@ rec { { name = "json-patch"; packageId = "json-patch"; + features = [ "schemars" ]; } { name = "k8s-openapi"; @@ -9830,6 +9840,10 @@ rec { packageId = "url"; features = [ "serde" ]; } + { + name = "uuid"; + packageId = "uuid"; + } ]; features = { "certs" = [ "dep:stackable-certs" ]; @@ -9848,8 +9862,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; procMacro = true; @@ -9883,8 +9897,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_shared"; @@ -9964,8 +9978,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_telemetry"; @@ -10074,8 +10088,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_versioned"; @@ -10124,8 +10138,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; procMacro = true; @@ -10192,8 +10206,8 @@ rec { edition = "2024"; workspace_member = null; src = pkgs.fetchgit { - url = "https://github.com/stackabletech/operator-rs.git"; - rev = "7a5f0c3fbcd091340214a23f0607fcd4b4fcc152"; + url = "https://github.com/stackabletech//operator-rs.git"; + rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; }; libName = "stackable_webhook"; @@ -12244,6 +12258,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"; diff --git a/Cargo.toml b/Cargo.toml index 35a640d8..6b5da3a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,5 +31,6 @@ tracing = "0.1" tracing-futures = { version = "0.2", features = ["futures-03"] } [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" } diff --git a/crate-hashes.json b/crate-hashes.json index 86f2b840..5564a89e 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.1#k8s-version@0.1.3": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-certs@0.4.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-operator-derive@0.3.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-operator@0.111.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-shared@0.1.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-telemetry@0.6.3": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-versioned-macros@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-versioned@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.111.1#stackable-webhook@0.9.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#k8s-version@0.1.3": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-certs@0.4.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator-derive@0.3.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator@0.111.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-shared@0.1.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-telemetry@0.6.3": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned-macros@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-webhook@0.9.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", "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 284154c74bbe241a4c6d16372035a894df310860 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 18:56:12 +0200 Subject: [PATCH 02/18] refactor: vendor hadoop-xml and java-properties writers Copies product-config's writer functions (to_hadoop_xml, to_java_properties_string) into config::writer, backed directly by the xml and java-properties crates so output stays byte-identical with the kuttl ConfigMap snapshots. Removes all product_config::writer usage; the product-config dependency itself is dropped in a later phase. Adds unit tests pinning the exact XML/properties on-wire format. Co-Authored-By: Claude Opus 4.8 (1M context) --- Cargo.lock | 6 +- Cargo.nix | 12 +- Cargo.toml | 2 + rust/operator-binary/Cargo.toml | 2 + rust/operator-binary/src/config/mod.rs | 4 +- rust/operator-binary/src/config/writer.rs | 144 ++++++++++++++++++++ rust/operator-binary/src/hdfs_controller.rs | 11 +- 7 files changed, 170 insertions(+), 11 deletions(-) create mode 100644 rust/operator-binary/src/config/writer.rs diff --git a/Cargo.lock b/Cargo.lock index f1428a79..c8749e1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2912,6 +2912,7 @@ dependencies = [ "const_format", "futures 0.3.32", "indoc", + "java-properties", "product-config", "rstest", "serde", @@ -2923,6 +2924,7 @@ dependencies = [ "tokio", "tracing", "tracing-futures", + "xml", ] [[package]] @@ -4023,9 +4025,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" diff --git a/Cargo.nix b/Cargo.nix index 0b4d74ac..f97b0ac5 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -9610,6 +9610,10 @@ rec { name = "indoc"; packageId = "indoc"; } + { + name = "java-properties"; + packageId = "java-properties"; + } { name = "product-config"; packageId = "product-config"; @@ -9651,6 +9655,10 @@ rec { packageId = "tracing-futures"; features = [ "futures-03" ]; } + { + name = "xml"; + packageId = "xml"; + } ]; buildDependencies = [ { @@ -14373,9 +14381,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)" diff --git a/Cargo.toml b/Cargo.toml index 6b5da3a1..31052d9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ clap = "4.5" const_format = "0.2" futures = { version = "0.3", features = ["compat"] } indoc = "2.0" +java-properties = "2.0" rstest = "0.26" semver = "1.0" serde = { version = "1.0", features = ["derive"] } @@ -29,6 +30,7 @@ strum = { version = "0.28", features = ["derive"] } tokio = { version = "1.40", features = ["full"] } tracing = "0.1" tracing-futures = { version = "0.2", features = ["futures-03"] } +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 e55786f9..4e535267 100644 --- a/rust/operator-binary/Cargo.toml +++ b/rust/operator-binary/Cargo.toml @@ -17,6 +17,7 @@ clap.workspace = true const_format.workspace = true futures.workspace = true indoc.workspace = true +java-properties.workspace = true serde_json.workspace = true serde.workspace = true snafu.workspace = true @@ -24,6 +25,7 @@ strum.workspace = true tokio.workspace = true tracing-futures.workspace = true tracing.workspace = true +xml.workspace = true [dev-dependencies] rstest.workspace = true diff --git a/rust/operator-binary/src/config/mod.rs b/rust/operator-binary/src/config/mod.rs index 2d157aa5..76fcebfd 100644 --- a/rust/operator-binary/src/config/mod.rs +++ b/rust/operator-binary/src/config/mod.rs @@ -1,8 +1,9 @@ use std::collections::BTreeMap; -use product_config::writer::to_hadoop_xml; use stackable_operator::utils::cluster_info::KubernetesClusterInfo; +use crate::config::writer::to_hadoop_xml; + use crate::crd::{ HdfsPodRef, constants::{ @@ -20,6 +21,7 @@ use crate::crd::{ }; pub mod jvm; +pub mod writer; #[derive(Clone)] pub struct HdfsSiteConfigBuilder { diff --git a/rust/operator-binary/src/config/writer.rs b/rust/operator-binary/src/config/writer.rs new file mode 100644 index 00000000..20c1e1b6 --- /dev/null +++ b/rust/operator-binary/src/config/writer.rs @@ -0,0 +1,144 @@ +//! 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. The on-wire format is pinned +//! by the kuttl ConfigMap snapshots under +//! `tests/templates/kuttl/smoke/31_configmap_hdfs-*-default.yaml.j2`. + +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" + ); + } +} diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index 76090bee..1ca7a8f0 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -4,11 +4,7 @@ use std::{ }; use const_format::concatcp; -use product_config::{ - ProductConfigManager, - types::PropertyNameKind, - writer::{PropertiesWriterError, to_hadoop_xml, to_java_properties_string}, -}; +use product_config::{ProductConfigManager, types::PropertyNameKind}; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ builder::{ @@ -52,7 +48,10 @@ use strum::{EnumDiscriminants, IntoEnumIterator, IntoStaticStr}; use crate::{ OPERATOR_NAME, build_recommended_labels, - config::{CoreSiteConfigBuilder, HdfsSiteConfigBuilder}, + config::{ + CoreSiteConfigBuilder, HdfsSiteConfigBuilder, + writer::{PropertiesWriterError, to_hadoop_xml, to_java_properties_string}, + }, container::{self, ContainerConfig, TLS_STORE_DIR, TLS_STORE_PASSWORD}, crd::{ AnyNodeConfig, HdfsClusterStatus, HdfsNodeRole, HdfsPodRef, UpgradeState, From 0cea491dac0a2d4020e11cf5cc224d6f93a8f53c Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 19:01:38 +0200 Subject: [PATCH 03/18] refactor: add controller/build/properties module with ConfigFileName Introduces the controller/build/properties module structure (mirroring trino-operator) and a local ConfigFileName enum that replaces the bare filename string constants as the single source of truth for the rolegroup ConfigMap keys. Scaffolding for moving per-file rendering out of the monolithic rolegroup_config_map in the next phase. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/controller/build/mod.rs | 1 + .../src/controller/build/properties/mod.rs | 36 +++++++++++++++++++ rust/operator-binary/src/controller/mod.rs | 1 + rust/operator-binary/src/hdfs_controller.rs | 13 +++---- 4 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 rust/operator-binary/src/controller/build/mod.rs create mode 100644 rust/operator-binary/src/controller/build/properties/mod.rs diff --git a/rust/operator-binary/src/controller/build/mod.rs b/rust/operator-binary/src/controller/build/mod.rs new file mode 100644 index 00000000..09d2bb68 --- /dev/null +++ b/rust/operator-binary/src/controller/build/mod.rs @@ -0,0 +1 @@ +pub mod properties; diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs new file mode 100644 index 00000000..ef69a4dd --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -0,0 +1,36 @@ +//! Per-file builders for the HDFS config files assembled into the rolegroup +//! `ConfigMap`. Each `.rs` module produces the rendered content for one +//! config file; the shared [`crate::config::writer`] module serializes maps to +//! the Hadoop-XML / Java-properties on-wire format. + +/// The names of the HDFS config files assembled into the rolegroup `ConfigMap`. +#[derive(Clone, Copy, Debug, strum::Display)] +pub enum ConfigFileName { + #[strum(serialize = "hdfs-site.xml")] + HdfsSite, + #[strum(serialize = "core-site.xml")] + CoreSite, + #[strum(serialize = "hadoop-policy.xml")] + HadoopPolicy, + #[strum(serialize = "ssl-server.xml")] + SslServer, + #[strum(serialize = "ssl-client.xml")] + SslClient, + #[strum(serialize = "security.properties")] + Security, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn file_names_match_the_hadoop_on_disk_names() { + assert_eq!(ConfigFileName::HdfsSite.to_string(), "hdfs-site.xml"); + assert_eq!(ConfigFileName::CoreSite.to_string(), "core-site.xml"); + assert_eq!(ConfigFileName::HadoopPolicy.to_string(), "hadoop-policy.xml"); + assert_eq!(ConfigFileName::SslServer.to_string(), "ssl-server.xml"); + assert_eq!(ConfigFileName::SslClient.to_string(), "ssl-client.xml"); + assert_eq!(ConfigFileName::Security.to_string(), "security.properties"); + } +} diff --git a/rust/operator-binary/src/controller/mod.rs b/rust/operator-binary/src/controller/mod.rs index 1b261dfe..a1196d5d 100644 --- a/rust/operator-binary/src/controller/mod.rs +++ b/rust/operator-binary/src/controller/mod.rs @@ -1,2 +1,3 @@ +pub mod build; pub mod dereference; pub mod validate; diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index 1ca7a8f0..dd2d1001 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -52,6 +52,7 @@ use crate::{ CoreSiteConfigBuilder, HdfsSiteConfigBuilder, writer::{PropertiesWriterError, to_hadoop_xml, to_java_properties_string}, }, + controller::build::properties::ConfigFileName, container::{self, ContainerConfig, TLS_STORE_DIR, TLS_STORE_PASSWORD}, crd::{ AnyNodeConfig, HdfsClusterStatus, HdfsNodeRole, HdfsPodRef, UpgradeState, @@ -776,13 +777,13 @@ fn rolegroup_config_map( builder .metadata(metadata.build()) - .add_data(CORE_SITE_XML.to_string(), core_site_xml) - .add_data(HDFS_SITE_XML.to_string(), hdfs_site_xml) - .add_data(HADOOP_POLICY_XML.to_string(), hadoop_policy_xml) - .add_data(SSL_SERVER_XML, ssl_server_xml) - .add_data(SSL_CLIENT_XML, ssl_client_xml) + .add_data(ConfigFileName::CoreSite.to_string(), core_site_xml) + .add_data(ConfigFileName::HdfsSite.to_string(), hdfs_site_xml) + .add_data(ConfigFileName::HadoopPolicy.to_string(), hadoop_policy_xml) + .add_data(ConfigFileName::SslServer.to_string(), ssl_server_xml) + .add_data(ConfigFileName::SslClient.to_string(), ssl_client_xml) .add_data( - JVM_SECURITY_PROPERTIES_FILE, + ConfigFileName::Security.to_string(), to_java_properties_string(jvm_sec_props.iter()).with_context(|_| { JvmSecurityPropertiesSnafu { rolegroup: rolegroup_ref.role_group.clone(), From 96bd3c5ff959460ee333e069ec9abe7ecf92e01b Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 19:14:40 +0200 Subject: [PATCH 04/18] refactor: extract hadoop-policy, ssl and security builders Moves rendering of hadoop-policy.xml, ssl-server.xml, ssl-client.xml and security.properties out of the monolithic rolegroup_config_map match into dedicated controller/build/properties modules, each with unit tests pinning the exact output. Logic is copied verbatim (overrides applied last), so the rendered ConfigMap is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../build/properties/hadoop_policy.rs | 40 +++++++++ .../src/controller/build/properties/mod.rs | 16 ++++ .../build/properties/security_properties.rs | 41 +++++++++ .../controller/build/properties/ssl_client.rs | 77 ++++++++++++++++ .../controller/build/properties/ssl_server.rs | 89 +++++++++++++++++++ rust/operator-binary/src/hdfs_controller.rs | 75 +++------------- 6 files changed, 273 insertions(+), 65 deletions(-) create mode 100644 rust/operator-binary/src/controller/build/properties/hadoop_policy.rs create mode 100644 rust/operator-binary/src/controller/build/properties/security_properties.rs create mode 100644 rust/operator-binary/src/controller/build/properties/ssl_client.rs create mode 100644 rust/operator-binary/src/controller/build/properties/ssl_server.rs diff --git a/rust/operator-binary/src/controller/build/properties/hadoop_policy.rs b/rust/operator-binary/src/controller/build/properties/hadoop_policy.rs new file mode 100644 index 00000000..b43abdc8 --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/hadoop_policy.rs @@ -0,0 +1,40 @@ +//! Builds the `hadoop-policy.xml` config file. +//! +//! The operator sets no defaults here; the file exists purely so users can +//! supply `configOverrides`. + +use std::collections::BTreeMap; + +use crate::{config::writer::to_hadoop_xml, controller::build::properties::optional_values}; + +/// Renders `hadoop-policy.xml` from the user-provided overrides only. +pub fn build(overrides: &BTreeMap) -> String { + to_hadoop_xml(optional_values(overrides).iter()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn empty_overrides_render_empty_configuration() { + assert_eq!( + build(&BTreeMap::new()), + "\n\n" + ); + } + + #[test] + fn overrides_are_rendered_as_properties() { + let overrides = BTreeMap::from([( + "security.client.protocol.acl".to_string(), + "*".to_string(), + )]); + assert_eq!( + build(&overrides), + "\n\n \ + \n security.client.protocol.acl\n \ + *\n \n" + ); + } +} diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index ef69a4dd..70728f63 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -3,6 +3,22 @@ //! config file; the shared [`crate::config::writer`] module serializes maps to //! the Hadoop-XML / Java-properties on-wire format. +use std::collections::BTreeMap; + +pub mod hadoop_policy; +pub mod security_properties; +pub mod ssl_client; +pub mod ssl_server; + +/// Converts a `key -> value` override map into the `key -> Some(value)` shape the +/// writers consume. +fn optional_values(overrides: &BTreeMap) -> BTreeMap> { + overrides + .iter() + .map(|(k, v)| (k.clone(), Some(v.clone()))) + .collect() +} + /// The names of the HDFS config files assembled into the rolegroup `ConfigMap`. #[derive(Clone, Copy, Debug, strum::Display)] pub enum ConfigFileName { 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..8b0d1dc2 --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/security_properties.rs @@ -0,0 +1,41 @@ +//! Builds the `security.properties` (JVM security) config file. +//! +//! The operator sets no defaults here; the file exists purely so users can +//! supply `configOverrides` (e.g. DNS cache TTLs). + +use std::collections::BTreeMap; + +use crate::{ + config::writer::{PropertiesWriterError, to_java_properties_string}, + controller::build::properties::optional_values, +}; + +/// Renders `security.properties` from the user-provided overrides only. +pub fn build(overrides: &BTreeMap) -> Result { + to_java_properties_string(optional_values(overrides).iter()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn empty_overrides_render_empty_string() { + assert_eq!(build(&BTreeMap::new()).unwrap(), ""); + } + + #[test] + fn overrides_are_rendered_sorted() { + let overrides = BTreeMap::from([ + ( + "networkaddress.cache.negative.ttl".to_string(), + "0".to_string(), + ), + ("networkaddress.cache.ttl".to_string(), "30".to_string()), + ]); + assert_eq!( + build(&overrides).unwrap(), + "networkaddress.cache.negative.ttl=0\nnetworkaddress.cache.ttl=30\n" + ); + } +} diff --git a/rust/operator-binary/src/controller/build/properties/ssl_client.rs b/rust/operator-binary/src/controller/build/properties/ssl_client.rs new file mode 100644 index 00000000..14a8397f --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/ssl_client.rs @@ -0,0 +1,77 @@ +//! Builds the `ssl-client.xml` config file. +//! +//! When HTTPS is enabled the operator injects the truststore location, type and +//! password; user `configOverrides` are applied on top. + +use std::collections::BTreeMap; + +use crate::{ + config::writer::to_hadoop_xml, + container::{TLS_STORE_DIR, TLS_STORE_PASSWORD}, + controller::build::properties::optional_values, +}; + +/// Renders `ssl-client.xml` for the given HTTPS state and user overrides. +pub fn build(https_enabled: bool, overrides: &BTreeMap) -> String { + let mut config: BTreeMap> = BTreeMap::new(); + if https_enabled { + config.extend([ + ( + "ssl.client.truststore.location".to_string(), + Some(format!("{TLS_STORE_DIR}/truststore.p12")), + ), + ( + "ssl.client.truststore.type".to_string(), + Some("pkcs12".to_string()), + ), + ( + "ssl.client.truststore.password".to_string(), + Some(TLS_STORE_PASSWORD.to_string()), + ), + ]); + } + // Overrides applied last so users win. + config.extend(optional_values(overrides)); + to_hadoop_xml(config.iter()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn disabled_https_without_overrides_renders_empty_configuration() { + assert_eq!( + build(false, &BTreeMap::new()), + "\n\n" + ); + } + + #[test] + fn enabled_https_injects_truststore() { + let xml = build(true, &BTreeMap::new()); + assert!( + xml.contains(&format!( + "ssl.client.truststore.location\n {TLS_STORE_DIR}/truststore.p12" + )), + "{xml}" + ); + assert!( + xml.contains(&format!( + "ssl.client.truststore.password\n {TLS_STORE_PASSWORD}" + )), + "{xml}" + ); + } + + #[test] + fn user_overrides_win_over_injected_defaults() { + let overrides = + BTreeMap::from([("ssl.client.truststore.type".to_string(), "jks".to_string())]); + let xml = build(true, &overrides); + assert!( + xml.contains("ssl.client.truststore.type\n jks"), + "{xml}" + ); + } +} diff --git a/rust/operator-binary/src/controller/build/properties/ssl_server.rs b/rust/operator-binary/src/controller/build/properties/ssl_server.rs new file mode 100644 index 00000000..183c4c1a --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/ssl_server.rs @@ -0,0 +1,89 @@ +//! Builds the `ssl-server.xml` config file. +//! +//! When HTTPS is enabled the operator injects the keystore/truststore locations, +//! types and passwords; user `configOverrides` are applied on top. + +use std::collections::BTreeMap; + +use crate::{ + config::writer::to_hadoop_xml, + container::{TLS_STORE_DIR, TLS_STORE_PASSWORD}, + controller::build::properties::optional_values, +}; + +/// Renders `ssl-server.xml` for the given HTTPS state and user overrides. +pub fn build(https_enabled: bool, overrides: &BTreeMap) -> String { + let mut config: BTreeMap> = BTreeMap::new(); + if https_enabled { + config.extend([ + ( + "ssl.server.truststore.location".to_string(), + Some(format!("{TLS_STORE_DIR}/truststore.p12")), + ), + ( + "ssl.server.truststore.type".to_string(), + Some("pkcs12".to_string()), + ), + ( + "ssl.server.truststore.password".to_string(), + Some(TLS_STORE_PASSWORD.to_string()), + ), + ( + "ssl.server.keystore.location".to_string(), + Some(format!("{TLS_STORE_DIR}/keystore.p12")), + ), + ( + "ssl.server.keystore.type".to_string(), + Some("pkcs12".to_string()), + ), + ( + "ssl.server.keystore.password".to_string(), + Some(TLS_STORE_PASSWORD.to_string()), + ), + ]); + } + // Overrides applied last so users win. + config.extend(optional_values(overrides)); + to_hadoop_xml(config.iter()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn disabled_https_without_overrides_renders_empty_configuration() { + assert_eq!( + build(false, &BTreeMap::new()), + "\n\n" + ); + } + + #[test] + fn enabled_https_injects_keystore_and_truststore() { + let xml = build(true, &BTreeMap::new()); + assert!( + xml.contains(&format!( + "ssl.server.keystore.location\n {TLS_STORE_DIR}/keystore.p12" + )), + "{xml}" + ); + assert!( + xml.contains(&format!( + "ssl.server.truststore.password\n {TLS_STORE_PASSWORD}" + )), + "{xml}" + ); + } + + #[test] + fn user_overrides_win_over_injected_defaults() { + let overrides = + BTreeMap::from([("ssl.server.keystore.type".to_string(), "jks".to_string())]); + let xml = build(true, &overrides); + assert!( + xml.contains("ssl.server.keystore.type\n jks"), + "{xml}" + ); + } +} diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index dd2d1001..d7153d3f 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -48,12 +48,11 @@ use strum::{EnumDiscriminants, IntoEnumIterator, IntoStaticStr}; use crate::{ OPERATOR_NAME, build_recommended_labels, - config::{ - CoreSiteConfigBuilder, HdfsSiteConfigBuilder, - writer::{PropertiesWriterError, to_hadoop_xml, to_java_properties_string}, + config::{CoreSiteConfigBuilder, HdfsSiteConfigBuilder, writer::PropertiesWriterError}, + controller::build::properties::{ + ConfigFileName, hadoop_policy, security_properties, ssl_client, ssl_server, }, - controller::build::properties::ConfigFileName, - container::{self, ContainerConfig, TLS_STORE_DIR, TLS_STORE_PASSWORD}, + container::{self, ContainerConfig}, crd::{ AnyNodeConfig, HdfsClusterStatus, HdfsNodeRole, HdfsPodRef, UpgradeState, UpgradeStateError, constants::*, v1alpha1, @@ -700,64 +699,13 @@ fn rolegroup_config_map( core_site_xml = core_site.extend(config).build_as_xml(); } PropertyNameKind::File(file_name) if file_name == HADOOP_POLICY_XML => { - // We don't add any settings here, the main purpose is to have a configOverride for users. - let mut config_opts: BTreeMap> = BTreeMap::new(); - config_opts.extend(config.iter().map(|(k, v)| (k.clone(), Some(v.clone())))); - hadoop_policy_xml = to_hadoop_xml(config_opts.iter()); + hadoop_policy_xml = hadoop_policy::build(config); } PropertyNameKind::File(file_name) if file_name == SSL_SERVER_XML => { - let mut config_opts = BTreeMap::new(); - if hdfs.has_https_enabled() { - config_opts.extend([ - ( - "ssl.server.truststore.location".to_string(), - Some(format!("{TLS_STORE_DIR}/truststore.p12")), - ), - ( - "ssl.server.truststore.type".to_string(), - Some("pkcs12".to_string()), - ), - ( - "ssl.server.truststore.password".to_string(), - Some(TLS_STORE_PASSWORD.to_string()), - ), - ( - "ssl.server.keystore.location".to_string(), - Some(format!("{TLS_STORE_DIR}/keystore.p12")), - ), - ( - "ssl.server.keystore.type".to_string(), - Some("pkcs12".to_string()), - ), - ( - "ssl.server.keystore.password".to_string(), - Some(TLS_STORE_PASSWORD.to_string()), - ), - ]); - } - config_opts.extend(config.iter().map(|(k, v)| (k.clone(), Some(v.clone())))); - ssl_server_xml = to_hadoop_xml(config_opts.iter()); + ssl_server_xml = ssl_server::build(hdfs.has_https_enabled(), config); } PropertyNameKind::File(file_name) if file_name == SSL_CLIENT_XML => { - let mut config_opts = BTreeMap::new(); - if hdfs.has_https_enabled() { - config_opts.extend([ - ( - "ssl.client.truststore.location".to_string(), - Some(format!("{TLS_STORE_DIR}/truststore.p12")), - ), - ( - "ssl.client.truststore.type".to_string(), - Some("pkcs12".to_string()), - ), - ( - "ssl.client.truststore.password".to_string(), - Some(TLS_STORE_PASSWORD.to_string()), - ), - ]); - } - config_opts.extend(config.iter().map(|(k, v)| (k.clone(), Some(v.clone())))); - ssl_client_xml = to_hadoop_xml(config_opts.iter()); + ssl_client_xml = ssl_client::build(hdfs.has_https_enabled(), config); } _ => {} } @@ -765,15 +713,12 @@ fn rolegroup_config_map( let mut builder = ConfigMapBuilder::new(); - let jvm_sec_props: BTreeMap> = rolegroup_config + let security_properties_overrides = rolegroup_config .get(&PropertyNameKind::File( JVM_SECURITY_PROPERTIES_FILE.to_string(), )) .cloned() - .unwrap_or_default() - .into_iter() - .map(|(k, v)| (k, Some(v))) - .collect(); + .unwrap_or_default(); builder .metadata(metadata.build()) @@ -784,7 +729,7 @@ fn rolegroup_config_map( .add_data(ConfigFileName::SslClient.to_string(), ssl_client_xml) .add_data( ConfigFileName::Security.to_string(), - to_java_properties_string(jvm_sec_props.iter()).with_context(|_| { + security_properties::build(&security_properties_overrides).with_context(|_| { JvmSecurityPropertiesSnafu { rolegroup: rolegroup_ref.role_group.clone(), } From c66b45f798a0a3330c82a32bc7de1bf86df42ddd Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 19:23:55 +0200 Subject: [PATCH 05/18] refactor: extract core-site and hdfs-site builders Moves the two large inline config renderings out of rolegroup_config_map into controller/build/properties/{core_site,hdfs_site}, each with unit tests driven by a shared MINIMAL_HDFS_YAML fixture. Logic is copied verbatim (overrides applied last), so the rendered ConfigMap is unchanged. The match arm in rolegroup_config_map is now a thin dispatch. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../controller/build/properties/core_site.rs | 82 +++++++++ .../controller/build/properties/hdfs_site.rs | 171 ++++++++++++++++++ .../src/controller/build/properties/mod.rs | 47 +++++ rust/operator-binary/src/hdfs_controller.rs | 128 +++---------- 4 files changed, 324 insertions(+), 104 deletions(-) create mode 100644 rust/operator-binary/src/controller/build/properties/core_site.rs create mode 100644 rust/operator-binary/src/controller/build/properties/hdfs_site.rs 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..790beafa --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -0,0 +1,82 @@ +//! Builds the `core-site.xml` config file. + +use std::collections::BTreeMap; + +use snafu::{ResultExt, Snafu}; +use stackable_operator::utils::cluster_info::KubernetesClusterInfo; + +use crate::{ + config::CoreSiteConfigBuilder, + crd::v1alpha1, + security::{kerberos, opa::HdfsOpaConfig}, +}; + +#[derive(Debug, Snafu)] +pub enum Error { + #[snafu(display("failed to build security config"))] + BuildSecurityConfig { source: kerberos::Error }, +} + +/// Renders `core-site.xml`: operator defaults + kerberos/OPA security config, +/// with user `configOverrides` applied last. +pub fn build( + hdfs: &v1alpha1::HdfsCluster, + hdfs_name: &str, + cluster_info: &KubernetesClusterInfo, + opa_config: Option<&HdfsOpaConfig>, + overrides: &BTreeMap, +) -> Result { + let mut core_site = CoreSiteConfigBuilder::new(hdfs_name.to_string()); + core_site + .fs_default_fs() + .ha_zookeeper_quorum() + .security_config(hdfs, cluster_info) + .context(BuildSecurityConfigSnafu)? + .enable_prometheus_endpoint() + // The default (4096) hasn't changed since 2009. + // Increase to 128k to allow for faster transfers. + .add("io.file.buffer.size", "131072"); + if let Some(opa_config) = opa_config { + opa_config.add_core_site_config(&mut core_site); + } + // the extend with config must come last in order to have overrides working!!! + Ok(core_site.extend(overrides).build_as_xml()) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::controller::build::properties::test_support::{cluster_info, minimal_hdfs}; + + #[test] + fn renders_operator_defaults() { + let hdfs = minimal_hdfs(); + let xml = build(&hdfs, "hdfs", &cluster_info(), None, &BTreeMap::new()).unwrap(); + assert!( + xml.contains("fs.defaultFS\n hdfs://hdfs/"), + "{xml}" + ); + assert!( + xml.contains( + "hadoop.prometheus.endpoint.enabled\n true" + ), + "{xml}" + ); + assert!( + xml.contains("io.file.buffer.size\n 131072"), + "{xml}" + ); + } + + #[test] + fn user_overrides_win_over_defaults() { + let hdfs = minimal_hdfs(); + let overrides = + BTreeMap::from([("io.file.buffer.size".to_string(), "65536".to_string())]); + let xml = build(&hdfs, "hdfs", &cluster_info(), None, &overrides).unwrap(); + assert!( + xml.contains("io.file.buffer.size\n 65536"), + "{xml}" + ); + } +} diff --git a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs new file mode 100644 index 00000000..710ff0eb --- /dev/null +++ b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs @@ -0,0 +1,171 @@ +//! Builds the `hdfs-site.xml` config file. + +use std::collections::BTreeMap; + +use stackable_operator::utils::cluster_info::KubernetesClusterInfo; + +use crate::{ + config::HdfsSiteConfigBuilder, + crd::{AnyNodeConfig, HdfsPodRef, v1alpha1}, + security::opa::HdfsOpaConfig, +}; + +/// Renders `hdfs-site.xml`: operator defaults, HA wiring derived from the pod +/// refs, kerberos/OPA security config, with user `configOverrides` applied last. +#[allow(clippy::too_many_arguments)] +pub fn build( + hdfs: &v1alpha1::HdfsCluster, + hdfs_name: &str, + cluster_info: &KubernetesClusterInfo, + merged_config: &AnyNodeConfig, + namenode_podrefs: &[HdfsPodRef], + journalnode_podrefs: &[HdfsPodRef], + opa_config: Option<&HdfsOpaConfig>, + overrides: &BTreeMap, +) -> String { + // IMPORTANT: these folders must be under the volume mount point, otherwise they will not + // be formatted by the namenode, or used by the other services. + // See also: https://github.com/apache-spark-on-k8s/kubernetes-HDFS/commit/aef9586ecc8551ca0f0a468c3b917d8c38f494a0 + // + // Notes on configuration choices + // =============================== + // We used to set `dfs.ha.nn.not-become-active-in-safemode` to true here due to + // badly worded HDFS documentation: + // https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithNFS.html + // This caused a deadlock with no namenode becoming active during a startup after + // HDFS was completely down for a while. + let mut hdfs_site = HdfsSiteConfigBuilder::new(hdfs_name.to_string()); + hdfs_site + .dfs_namenode_name_dir() + .dfs_datanode_data_dir( + merged_config + .as_datanode() + .map(|node| node.resources.storage.clone()), + ) + .dfs_journalnode_edits_dir() + .dfs_replication(hdfs.spec.cluster_config.dfs_replication) + .dfs_name_services() + .dfs_ha_namenodes(namenode_podrefs) + .dfs_namenode_shared_edits_dir(cluster_info, journalnode_podrefs) + .dfs_namenode_name_dir_ha(namenode_podrefs) + .dfs_namenode_rpc_address_ha(cluster_info, namenode_podrefs) + .dfs_namenode_http_address_ha(hdfs, cluster_info, namenode_podrefs) + .dfs_client_failover_proxy_provider() + .security_config(hdfs) + .add("dfs.ha.fencing.methods", "shell(/bin/true)") + .add("dfs.ha.automatic-failover.enabled", "true") + .add("dfs.ha.namenode.id", "${env.POD_NAME}") + .add( + "dfs.namenode.datanode.registration.unsafe.allow-address-override", + "true", + ) + .add("dfs.datanode.registered.hostname", "${env.POD_ADDRESS}") + .add("dfs.datanode.registered.port", "${env.DATA_PORT}") + .add("dfs.datanode.registered.ipc.port", "${env.IPC_PORT}") + // The following two properties are set to "true" because there is a minor chance that data + // written to HDFS is not synced to disk even if a block has been closed. + // Users in HBase can control this explicitly for the WAL, but for flushes and compactions + // I believe they can't as easily (if at all). + // In theory, HBase should be able to recover from these failures, but that comes at a cost + // and there's always a risk. + // Enabling this behavior causes HDFS to sync to disk as soon as possible. + .add("dfs.datanode.sync.behind.writes", "true") + .add("dfs.datanode.synconclose", "true") + // Defaults to 10 since at least 2011. + // This controls the concurrent number of client connections (this includes DataNodes) + // to the NameNode. Ideally, we'd scale this with the number of DataNodes but this would + // lead to restarts of the NameNode. + // This should lead to better performance due to more concurrency. + .add("dfs.namenode.handler.count", "50") + // Defaults to 10 since at least 2012. + // This controls the concurrent number of client connections to the DataNodes. + // We have no idea how many clients there may be, so it's hard to assign a good default. + // Increasing to 50 should lead to better performance due to more concurrency, especially + // with use-cases like HBase. + .add("dfs.datanode.handler.count", "50") + // The following two properties default to 2 and 4 respectively since around 2013. + // They control the number of maximum replication "jobs" a NameNode assigns to + // a DataNode in a single heartbeat. + // Increasing this number will increase network usage during replication events + // but can lead to faster recovery. + .add("dfs.namenode.replication.max-streams", "4") + .add("dfs.namenode.replication.max-streams-hard-limit", "8") + // Defaults to 4096 and hasn't changed since at least 2011. + // The number of threads used for actual data transfer, so not very CPU heavy + // but IO bound. This is why the number is relatively high. + // But today's Java and IO should be able to handle more, so bump it to 8192 for + // better performance/concurrency. + .add("dfs.datanode.max.transfer.threads", "8192"); + if hdfs.has_https_enabled() { + hdfs_site.add("dfs.datanode.registered.https.port", "${env.HTTPS_PORT}"); + } else { + hdfs_site.add("dfs.datanode.registered.http.port", "${env.HTTP_PORT}"); + } + if let Some(opa_config) = opa_config { + opa_config.add_hdfs_site_config(&mut hdfs_site); + } + // the extend with config must come last in order to have overrides working!!! + hdfs_site.extend(overrides).build_as_xml() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + controller::build::properties::test_support::{cluster_info, minimal_hdfs}, + crd::HdfsNodeRole, + }; + + fn namenode_merged_config(hdfs: &v1alpha1::HdfsCluster) -> AnyNodeConfig { + HdfsNodeRole::Name + .merged_config(hdfs, "default") + .expect("merged config for the minimal namenode group") + } + + #[test] + fn renders_operator_defaults() { + let hdfs = minimal_hdfs(); + let merged = namenode_merged_config(&hdfs); + let xml = build( + &hdfs, + "hdfs", + &cluster_info(), + &merged, + &[], + &[], + None, + &BTreeMap::new(), + ); + assert!( + xml.contains("dfs.replication\n 3"), + "{xml}" + ); + assert!( + xml.contains( + "dfs.datanode.max.transfer.threads\n 8192" + ), + "{xml}" + ); + } + + #[test] + fn user_overrides_win_over_defaults() { + let hdfs = minimal_hdfs(); + let merged = namenode_merged_config(&hdfs); + let overrides = BTreeMap::from([("dfs.replication".to_string(), "5".to_string())]); + let xml = build( + &hdfs, + "hdfs", + &cluster_info(), + &merged, + &[], + &[], + None, + &overrides, + ); + assert!( + xml.contains("dfs.replication\n 5"), + "{xml}" + ); + } +} diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index 70728f63..7a006c51 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -5,7 +5,9 @@ use std::collections::BTreeMap; +pub mod core_site; pub mod hadoop_policy; +pub mod hdfs_site; pub mod security_properties; pub mod ssl_client; pub mod ssl_server; @@ -50,3 +52,48 @@ mod tests { assert_eq!(ConfigFileName::Security.to_string(), "security.properties"); } } + +#[cfg(test)] +pub(crate) mod test_support { + use stackable_operator::{ + commons::networking::DomainName, utils::cluster_info::KubernetesClusterInfo, + }; + + use crate::crd::v1alpha1; + + /// A minimal three-role HdfsCluster used to drive the per-file builder tests. + pub const MINIMAL_HDFS_YAML: &str = r#" +--- +apiVersion: hdfs.stackable.tech/v1alpha1 +kind: HdfsCluster +metadata: + name: hdfs +spec: + image: + productVersion: 3.4.0 + clusterConfig: + zookeeperConfigMapName: hdfs-zk + nameNodes: + roleGroups: + default: + replicas: 1 + journalNodes: + roleGroups: + default: + replicas: 1 + dataNodes: + roleGroups: + default: + replicas: 1 +"#; + + pub fn minimal_hdfs() -> v1alpha1::HdfsCluster { + serde_yaml::from_str(MINIMAL_HDFS_YAML).expect("invalid test HdfsCluster YAML") + } + + pub fn cluster_info() -> KubernetesClusterInfo { + KubernetesClusterInfo { + cluster_domain: DomainName::try_from("cluster.local").unwrap(), + } + } +} diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index d7153d3f..9d66ca0d 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -48,9 +48,10 @@ use strum::{EnumDiscriminants, IntoEnumIterator, IntoStaticStr}; use crate::{ OPERATOR_NAME, build_recommended_labels, - config::{CoreSiteConfigBuilder, HdfsSiteConfigBuilder, writer::PropertiesWriterError}, + config::writer::PropertiesWriterError, controller::build::properties::{ - ConfigFileName, hadoop_policy, security_properties, ssl_client, ssl_server, + ConfigFileName, core_site, hadoop_policy, hdfs_site, security_properties, ssl_client, + ssl_server, }, container::{self, ContainerConfig}, crd::{ @@ -64,7 +65,7 @@ use crate::{ pdb::add_pdbs, }, product_logging::extend_role_group_config_map, - security::{kerberos, opa::HdfsOpaConfig}, + security::opa::HdfsOpaConfig, service::{self, rolegroup_headless_service, rolegroup_metrics_service}, }; @@ -239,8 +240,8 @@ pub enum Error { source: stackable_operator::builder::meta::Error, }, - #[snafu(display("failed to build security config"))] - BuildSecurityConfig { source: kerberos::Error }, + #[snafu(display("failed to build core-site.xml"))] + BuildCoreSiteXml { source: core_site::Error }, #[snafu(display("HdfsCluster object is invalid"))] InvalidHdfsCluster { @@ -596,107 +597,26 @@ fn rolegroup_config_map( for (property_name_kind, config) in rolegroup_config { match property_name_kind { PropertyNameKind::File(file_name) if file_name == HDFS_SITE_XML => { - // IMPORTANT: these folders must be under the volume mount point, otherwise they will not - // be formatted by the namenode, or used by the other services. - // See also: https://github.com/apache-spark-on-k8s/kubernetes-HDFS/commit/aef9586ecc8551ca0f0a468c3b917d8c38f494a0 - // - // Notes on configuration choices - // =============================== - // We used to set `dfs.ha.nn.not-become-active-in-safemode` to true here due to - // badly worded HDFS documentation: - // https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithNFS.html - // This caused a deadlock with no namenode becoming active during a startup after - // HDFS was completely down for a while. - - let mut hdfs_site = HdfsSiteConfigBuilder::new(hdfs_name.to_string()); - hdfs_site - .dfs_namenode_name_dir() - .dfs_datanode_data_dir( - merged_config - .as_datanode() - .map(|node| node.resources.storage.clone()), - ) - .dfs_journalnode_edits_dir() - .dfs_replication(hdfs.spec.cluster_config.dfs_replication) - .dfs_name_services() - .dfs_ha_namenodes(namenode_podrefs) - .dfs_namenode_shared_edits_dir(cluster_info, journalnode_podrefs) - .dfs_namenode_name_dir_ha(namenode_podrefs) - .dfs_namenode_rpc_address_ha(cluster_info, namenode_podrefs) - .dfs_namenode_http_address_ha(hdfs, cluster_info, namenode_podrefs) - .dfs_client_failover_proxy_provider() - .security_config(hdfs) - .add("dfs.ha.fencing.methods", "shell(/bin/true)") - .add("dfs.ha.automatic-failover.enabled", "true") - .add("dfs.ha.namenode.id", "${env.POD_NAME}") - .add( - "dfs.namenode.datanode.registration.unsafe.allow-address-override", - "true", - ) - .add("dfs.datanode.registered.hostname", "${env.POD_ADDRESS}") - .add("dfs.datanode.registered.port", "${env.DATA_PORT}") - .add("dfs.datanode.registered.ipc.port", "${env.IPC_PORT}") - // The following two properties are set to "true" because there is a minor chance that data - // written to HDFS is not synced to disk even if a block has been closed. - // Users in HBase can control this explicitly for the WAL, but for flushes and compactions - // I believe they can't as easily (if at all). - // In theory, HBase should be able to recover from these failures, but that comes at a cost - // and there's always a risk. - // Enabling this behavior causes HDFS to sync to disk as soon as possible. - .add("dfs.datanode.sync.behind.writes", "true") - .add("dfs.datanode.synconclose", "true") - // Defaults to 10 since at least 2011. - // This controls the concurrent number of client connections (this includes DataNodes) - // to the NameNode. Ideally, we'd scale this with the number of DataNodes but this would - // lead to restarts of the NameNode. - // This should lead to better performance due to more concurrency. - .add("dfs.namenode.handler.count", "50") - // Defaults to 10 since at least 2012. - // This controls the concurrent number of client connections to the DataNodes. - // We have no idea how many clients there may be, so it's hard to assign a good default. - // Increasing to 50 should lead to better performance due to more concurrency, especially - // with use-cases like HBase. - .add("dfs.datanode.handler.count", "50") - // The following two properties default to 2 and 4 respectively since around 2013. - // They control the number of maximum replication "jobs" a NameNode assigns to - // a DataNode in a single heartbeat. - // Increasing this number will increase network usage during replication events - // but can lead to faster recovery. - .add("dfs.namenode.replication.max-streams", "4") - .add("dfs.namenode.replication.max-streams-hard-limit", "8") - // Defaults to 4096 and hasn't changed since at least 2011. - // The number of threads used for actual data transfer, so not very CPU heavy - // but IO bound. This is why the number is relatively high. - // But today's Java and IO should be able to handle more, so bump it to 8192 for - // better performance/concurrency. - .add("dfs.datanode.max.transfer.threads", "8192"); - if hdfs.has_https_enabled() { - hdfs_site.add("dfs.datanode.registered.https.port", "${env.HTTPS_PORT}"); - } else { - hdfs_site.add("dfs.datanode.registered.http.port", "${env.HTTP_PORT}"); - } - if let Some(hdfs_opa_config) = hdfs_opa_config { - hdfs_opa_config.add_hdfs_site_config(&mut hdfs_site); - } - // the extend with config must come last in order to have overrides working!!! - hdfs_site_xml = hdfs_site.extend(config).build_as_xml(); + hdfs_site_xml = hdfs_site::build( + hdfs, + hdfs_name, + cluster_info, + merged_config, + namenode_podrefs, + journalnode_podrefs, + hdfs_opa_config.as_ref(), + config, + ); } PropertyNameKind::File(file_name) if file_name == CORE_SITE_XML => { - let mut core_site = CoreSiteConfigBuilder::new(hdfs_name.to_string()); - core_site - .fs_default_fs() - .ha_zookeeper_quorum() - .security_config(hdfs, cluster_info) - .context(BuildSecurityConfigSnafu)? - .enable_prometheus_endpoint() - // The default (4096) hasn't changed since 2009. - // Increase to 128k to allow for faster transfers. - .add("io.file.buffer.size", "131072"); - if let Some(hdfs_opa_config) = hdfs_opa_config { - hdfs_opa_config.add_core_site_config(&mut core_site); - } - // the extend with config must come last in order to have overrides working!!! - core_site_xml = core_site.extend(config).build_as_xml(); + core_site_xml = core_site::build( + hdfs, + hdfs_name, + cluster_info, + hdfs_opa_config.as_ref(), + config, + ) + .context(BuildCoreSiteXmlSnafu)?; } PropertyNameKind::File(file_name) if file_name == HADOOP_POLICY_XML => { hadoop_policy_xml = hadoop_policy::build(config); From d935057044d25d2b51eedfc18081525e04174854 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 19:30:11 +0200 Subject: [PATCH 06/18] refactor: inject security.properties DNS cache TTLs in builder Moves the recommended networkaddress.cache.ttl=30 and networkaddress.cache.negative.ttl=0 values out of the product-config properties.yaml and into security_properties::build directly. While product-config is still active these arrive identically via the override map applied last, so the rendered file is unchanged; this makes the builder self-sufficient ahead of removing product-config validation. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../build/properties/security_properties.rs | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) 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 8b0d1dc2..7fe01a28 100644 --- a/rust/operator-binary/src/controller/build/properties/security_properties.rs +++ b/rust/operator-binary/src/controller/build/properties/security_properties.rs @@ -1,7 +1,8 @@ //! Builds the `security.properties` (JVM security) config file. //! -//! The operator sets no defaults here; the file exists purely so users can -//! supply `configOverrides` (e.g. DNS cache TTLs). +//! The operator injects recommended JVM DNS cache TTLs (previously supplied via +//! the product-config `properties.yaml`); user `configOverrides` are applied on +//! top. use std::collections::BTreeMap; @@ -10,9 +11,24 @@ use crate::{ controller::build::properties::optional_values, }; -/// Renders `security.properties` from the user-provided overrides only. +/// Renders `security.properties`: recommended DNS cache TTLs plus user overrides. pub fn build(overrides: &BTreeMap) -> Result { - to_java_properties_string(optional_values(overrides).iter()) + // Recommended JVM DNS cache TTLs. Caching forever (the JVM default for + // successful lookups) breaks failover when a NameNode's IP changes, so cap + // both positive and negative caches. + let mut config: BTreeMap> = BTreeMap::from([ + ( + "networkaddress.cache.ttl".to_string(), + Some("30".to_string()), + ), + ( + "networkaddress.cache.negative.ttl".to_string(), + Some("0".to_string()), + ), + ]); + // Overrides applied last so users win. + config.extend(optional_values(overrides)); + to_java_properties_string(config.iter()) } #[cfg(test)] @@ -20,22 +36,29 @@ mod tests { use super::*; #[test] - fn empty_overrides_render_empty_string() { - assert_eq!(build(&BTreeMap::new()).unwrap(), ""); + fn injects_recommended_dns_cache_ttls() { + assert_eq!( + build(&BTreeMap::new()).unwrap(), + "networkaddress.cache.negative.ttl=0\nnetworkaddress.cache.ttl=30\n" + ); } #[test] - fn overrides_are_rendered_sorted() { - let overrides = BTreeMap::from([ - ( - "networkaddress.cache.negative.ttl".to_string(), - "0".to_string(), - ), - ("networkaddress.cache.ttl".to_string(), "30".to_string()), - ]); + fn user_overrides_win_over_injected_defaults() { + let overrides = + BTreeMap::from([("networkaddress.cache.ttl".to_string(), "60".to_string())]); assert_eq!( build(&overrides).unwrap(), - "networkaddress.cache.negative.ttl=0\nnetworkaddress.cache.ttl=30\n" + "networkaddress.cache.negative.ttl=0\nnetworkaddress.cache.ttl=60\n" + ); + } + + #[test] + fn extra_overrides_are_appended() { + let overrides = BTreeMap::from([("foo.bar".to_string(), "baz".to_string())]); + assert_eq!( + build(&overrides).unwrap(), + "foo.bar=baz\nnetworkaddress.cache.negative.ttl=0\nnetworkaddress.cache.ttl=30\n" ); } } From 2fbcace86ae0705d7e568afb2848315cb210a173 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 20:27:53 +0200 Subject: [PATCH 07/18] refactor: remove product-config from validation and config building Replaces the product-config transform/validate steps with native config merging, mirroring trino-operator: - validate_cluster no longer takes a ProductConfigManager; it merges the typed config fragments (HdfsNodeRole::merged_config) and the per-file configOverrides + envOverrides (role <- role group) into the extended ValidatedRoleGroupConfig { merged_config, config_overrides, env_overrides }. - HdfsConfigOverrides now uses typed KeyValueConfigOverrides fields (v2, deriving Merge) instead of Options; the per-file builders pull their overrides via resolved_overrides and apply them last. - Operator-injected values previously provided by properties.yaml / Configuration impls are now set directly in the builders/validate: security.properties DNS cache TTLs, dfs.replication, and the rack-aware net.topology / TOPOLOGY_LABELS (namenode). - Deletes build_role_properties, the Configuration impls, PropertyNameKind usage, and the ProductConfigManager plumbing (Ctx, main); the CLI arg is kept but ignored. - Filenames now come from the ConfigFileName enum everywhere (discovery, kerberos, jvm), dropping the *_XML / *_PROPERTIES_FILE constants. The product-config crate dependency is now unused and removed separately. Co-Authored-By: Claude Opus 4.8 (1M context) --- rust/operator-binary/src/config/jvm.rs | 8 +- rust/operator-binary/src/config/mod.rs | 6 +- .../controller/build/properties/core_site.rs | 47 ++- .../build/properties/hadoop_policy.rs | 20 +- .../controller/build/properties/hdfs_site.rs | 19 +- .../src/controller/build/properties/mod.rs | 35 ++- .../build/properties/security_properties.rs | 18 +- .../controller/build/properties/ssl_client.rs | 17 +- .../controller/build/properties/ssl_server.rs | 17 +- .../src/controller/validate.rs | 113 ++++--- rust/operator-binary/src/crd/constants.rs | 6 - rust/operator-binary/src/crd/mod.rs | 287 ++---------------- rust/operator-binary/src/discovery.rs | 11 +- rust/operator-binary/src/hdfs_controller.rs | 181 ++++------- rust/operator-binary/src/main.rs | 10 +- rust/operator-binary/src/security/kerberos.rs | 16 +- 16 files changed, 309 insertions(+), 502 deletions(-) diff --git a/rust/operator-binary/src/config/jvm.rs b/rust/operator-binary/src/config/jvm.rs index f6edc3ee..95ebcd22 100644 --- a/rust/operator-binary/src/config/jvm.rs +++ b/rust/operator-binary/src/config/jvm.rs @@ -6,7 +6,8 @@ use stackable_operator::{ }; use crate::{ - crd::{HdfsNodeRole, constants::JVM_SECURITY_PROPERTIES_FILE, v1alpha1}, + controller::build::properties::ConfigFileName, + crd::{HdfsNodeRole, v1alpha1}, security::kerberos::KERBEROS_CONTAINER_PATH, }; @@ -78,7 +79,10 @@ pub fn construct_role_specific_jvm_args( } jvm_args.extend([ - format!("-Djava.security.properties={config_dir}/{JVM_SECURITY_PROPERTIES_FILE}"), + format!( + "-Djava.security.properties={config_dir}/{}", + ConfigFileName::Security + ), format!("-javaagent:/stackable/jmx/jmx_prometheus_javaagent.jar={metrics_port}:/stackable/jmx/{hdfs_role}.yaml") ]); if kerberos_enabled { diff --git a/rust/operator-binary/src/config/mod.rs b/rust/operator-binary/src/config/mod.rs index 76fcebfd..b48898ad 100644 --- a/rust/operator-binary/src/config/mod.rs +++ b/rust/operator-binary/src/config/mod.rs @@ -217,7 +217,7 @@ impl HdfsSiteConfigBuilder { } pub fn build_as_xml(&self) -> String { - let transformed_config = transform_for_product_config(&self.config); + let transformed_config = to_optional_values(&self.config); to_hadoop_xml(transformed_config.iter()) } @@ -264,7 +264,7 @@ impl CoreSiteConfigBuilder { } pub fn build_as_xml(&self) -> String { - let transformed_config = transform_for_product_config(&self.config); + let transformed_config = to_optional_values(&self.config); to_hadoop_xml(transformed_config.iter()) } @@ -275,7 +275,7 @@ impl CoreSiteConfigBuilder { } } -fn transform_for_product_config( +fn to_optional_values( config: &BTreeMap, ) -> BTreeMap> { config 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 790beafa..f1aff53a 100644 --- a/rust/operator-binary/src/controller/build/properties/core_site.rs +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -3,11 +3,14 @@ use std::collections::BTreeMap; use snafu::{ResultExt, Snafu}; -use stackable_operator::utils::cluster_info::KubernetesClusterInfo; +use stackable_operator::{ + utils::cluster_info::KubernetesClusterInfo, v2::config_overrides::KeyValueConfigOverrides, +}; use crate::{ config::CoreSiteConfigBuilder, - crd::v1alpha1, + controller::build::properties::resolved_overrides, + crd::{HdfsNodeRole, v1alpha1}, security::{kerberos, opa::HdfsOpaConfig}, }; @@ -22,9 +25,10 @@ pub enum Error { pub fn build( hdfs: &v1alpha1::HdfsCluster, hdfs_name: &str, + role: HdfsNodeRole, cluster_info: &KubernetesClusterInfo, opa_config: Option<&HdfsOpaConfig>, - overrides: &BTreeMap, + overrides: KeyValueConfigOverrides, ) -> Result { let mut core_site = CoreSiteConfigBuilder::new(hdfs_name.to_string()); core_site @@ -36,22 +40,41 @@ pub fn build( // The default (4096) hasn't changed since 2009. // Increase to 128k to allow for faster transfers. .add("io.file.buffer.size", "131072"); + // Rack awareness topology provider, namenode only. Previously injected via + // the product-config `Configuration::compute_files`. + if role == HdfsNodeRole::Name && hdfs.rackawareness_config().is_some() { + core_site.add( + "net.topology.node.switch.mapping.impl", + "tech.stackable.hadoop.StackableTopologyProvider", + ); + } if let Some(opa_config) = opa_config { opa_config.add_core_site_config(&mut core_site); } // the extend with config must come last in order to have overrides working!!! - Ok(core_site.extend(overrides).build_as_xml()) + let overrides: BTreeMap = resolved_overrides(overrides).collect(); + Ok(core_site.extend(&overrides).build_as_xml()) } #[cfg(test)] mod tests { use super::*; - use crate::controller::build::properties::test_support::{cluster_info, minimal_hdfs}; + use crate::controller::build::properties::test_support::{ + cluster_info, config_overrides, minimal_hdfs, + }; #[test] fn renders_operator_defaults() { let hdfs = minimal_hdfs(); - let xml = build(&hdfs, "hdfs", &cluster_info(), None, &BTreeMap::new()).unwrap(); + let xml = build( + &hdfs, + "hdfs", + HdfsNodeRole::Name, + &cluster_info(), + None, + config_overrides(&[]), + ) + .unwrap(); assert!( xml.contains("fs.defaultFS\n hdfs://hdfs/"), "{xml}" @@ -71,9 +94,15 @@ mod tests { #[test] fn user_overrides_win_over_defaults() { let hdfs = minimal_hdfs(); - let overrides = - BTreeMap::from([("io.file.buffer.size".to_string(), "65536".to_string())]); - let xml = build(&hdfs, "hdfs", &cluster_info(), None, &overrides).unwrap(); + let xml = build( + &hdfs, + "hdfs", + HdfsNodeRole::Name, + &cluster_info(), + None, + config_overrides(&[("io.file.buffer.size", "65536")]), + ) + .unwrap(); assert!( xml.contains("io.file.buffer.size\n 65536"), "{xml}" diff --git a/rust/operator-binary/src/controller/build/properties/hadoop_policy.rs b/rust/operator-binary/src/controller/build/properties/hadoop_policy.rs index b43abdc8..6fb0d7e1 100644 --- a/rust/operator-binary/src/controller/build/properties/hadoop_policy.rs +++ b/rust/operator-binary/src/controller/build/properties/hadoop_policy.rs @@ -5,33 +5,35 @@ use std::collections::BTreeMap; -use crate::{config::writer::to_hadoop_xml, controller::build::properties::optional_values}; +use stackable_operator::v2::config_overrides::KeyValueConfigOverrides; + +use crate::{config::writer::to_hadoop_xml, controller::build::properties::resolved_overrides}; /// Renders `hadoop-policy.xml` from the user-provided overrides only. -pub fn build(overrides: &BTreeMap) -> String { - to_hadoop_xml(optional_values(overrides).iter()) +pub fn build(overrides: KeyValueConfigOverrides) -> String { + let config: BTreeMap> = resolved_overrides(overrides) + .map(|(key, value)| (key, Some(value))) + .collect(); + to_hadoop_xml(config.iter()) } #[cfg(test)] mod tests { use super::*; + use crate::controller::build::properties::test_support::config_overrides; #[test] fn empty_overrides_render_empty_configuration() { assert_eq!( - build(&BTreeMap::new()), + build(config_overrides(&[])), "\n\n" ); } #[test] fn overrides_are_rendered_as_properties() { - let overrides = BTreeMap::from([( - "security.client.protocol.acl".to_string(), - "*".to_string(), - )]); assert_eq!( - build(&overrides), + build(config_overrides(&[("security.client.protocol.acl", "*")])), "\n\n \ \n security.client.protocol.acl\n \ *\n \n" diff --git a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs index 710ff0eb..aff683da 100644 --- a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs +++ b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs @@ -2,10 +2,13 @@ use std::collections::BTreeMap; -use stackable_operator::utils::cluster_info::KubernetesClusterInfo; +use stackable_operator::{ + utils::cluster_info::KubernetesClusterInfo, v2::config_overrides::KeyValueConfigOverrides, +}; use crate::{ config::HdfsSiteConfigBuilder, + controller::build::properties::resolved_overrides, crd::{AnyNodeConfig, HdfsPodRef, v1alpha1}, security::opa::HdfsOpaConfig, }; @@ -21,7 +24,7 @@ pub fn build( namenode_podrefs: &[HdfsPodRef], journalnode_podrefs: &[HdfsPodRef], opa_config: Option<&HdfsOpaConfig>, - overrides: &BTreeMap, + overrides: KeyValueConfigOverrides, ) -> String { // IMPORTANT: these folders must be under the volume mount point, otherwise they will not // be formatted by the namenode, or used by the other services. @@ -105,14 +108,17 @@ pub fn build( opa_config.add_hdfs_site_config(&mut hdfs_site); } // the extend with config must come last in order to have overrides working!!! - hdfs_site.extend(overrides).build_as_xml() + let overrides: BTreeMap = resolved_overrides(overrides).collect(); + hdfs_site.extend(&overrides).build_as_xml() } #[cfg(test)] mod tests { use super::*; use crate::{ - controller::build::properties::test_support::{cluster_info, minimal_hdfs}, + controller::build::properties::test_support::{ + cluster_info, config_overrides, minimal_hdfs, + }, crd::HdfsNodeRole, }; @@ -134,7 +140,7 @@ mod tests { &[], &[], None, - &BTreeMap::new(), + config_overrides(&[]), ); assert!( xml.contains("dfs.replication\n 3"), @@ -152,7 +158,6 @@ mod tests { fn user_overrides_win_over_defaults() { let hdfs = minimal_hdfs(); let merged = namenode_merged_config(&hdfs); - let overrides = BTreeMap::from([("dfs.replication".to_string(), "5".to_string())]); let xml = build( &hdfs, "hdfs", @@ -161,7 +166,7 @@ mod tests { &[], &[], None, - &overrides, + config_overrides(&[("dfs.replication", "5")]), ); assert!( xml.contains("dfs.replication\n 5"), diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index 7a006c51..a7f6bc83 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -5,6 +5,8 @@ use std::collections::BTreeMap; +use stackable_operator::v2::config_overrides::KeyValueConfigOverrides; + pub mod core_site; pub mod hadoop_policy; pub mod hdfs_site; @@ -12,13 +14,21 @@ pub mod security_properties; pub mod ssl_client; pub mod ssl_server; -/// Converts a `key -> value` override map into the `key -> Some(value)` shape the -/// writers consume. -fn optional_values(overrides: &BTreeMap) -> BTreeMap> { - overrides - .iter() - .map(|(k, v)| (k.clone(), Some(v.clone()))) - .collect() +/// Keep only the set (`Some`) entries of a `key -> optional value` map, as `(key, value)` pairs. +fn defined_entries( + entries: BTreeMap>, +) -> impl Iterator { + entries + .into_iter() + .filter_map(|(key, value)| value.map(|value| (key, value))) +} + +/// Resolve user-provided [`KeyValueConfigOverrides`] into the key/value pairs to merge +/// into a config file, dropping entries whose value is unset (`None`). +fn resolved_overrides( + overrides: KeyValueConfigOverrides, +) -> impl Iterator { + defined_entries(overrides.overrides) } /// The names of the HDFS config files assembled into the rolegroup `ConfigMap`. @@ -57,10 +67,21 @@ mod tests { pub(crate) mod test_support { use stackable_operator::{ commons::networking::DomainName, utils::cluster_info::KubernetesClusterInfo, + v2::config_overrides::KeyValueConfigOverrides, }; use crate::crd::v1alpha1; + /// Builds a [`KeyValueConfigOverrides`] from `(key, value)` pairs for tests. + pub fn config_overrides(pairs: &[(&str, &str)]) -> KeyValueConfigOverrides { + KeyValueConfigOverrides { + overrides: pairs + .iter() + .map(|(k, v)| (k.to_string(), Some(v.to_string()))) + .collect(), + } + } + /// A minimal three-role HdfsCluster used to drive the per-file builder tests. pub const MINIMAL_HDFS_YAML: &str = r#" --- 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 7fe01a28..bce30cf7 100644 --- a/rust/operator-binary/src/controller/build/properties/security_properties.rs +++ b/rust/operator-binary/src/controller/build/properties/security_properties.rs @@ -6,13 +6,15 @@ use std::collections::BTreeMap; +use stackable_operator::v2::config_overrides::KeyValueConfigOverrides; + use crate::{ config::writer::{PropertiesWriterError, to_java_properties_string}, - controller::build::properties::optional_values, + controller::build::properties::resolved_overrides, }; /// Renders `security.properties`: recommended DNS cache TTLs plus user overrides. -pub fn build(overrides: &BTreeMap) -> Result { +pub fn build(overrides: KeyValueConfigOverrides) -> Result { // Recommended JVM DNS cache TTLs. Caching forever (the JVM default for // successful lookups) breaks failover when a NameNode's IP changes, so cap // both positive and negative caches. @@ -27,37 +29,35 @@ pub fn build(overrides: &BTreeMap) -> Result) -> String { +pub fn build(https_enabled: bool, overrides: KeyValueConfigOverrides) -> String { let mut config: BTreeMap> = BTreeMap::new(); if https_enabled { config.extend([ @@ -31,25 +33,26 @@ pub fn build(https_enabled: bool, overrides: &BTreeMap) -> Strin ]); } // Overrides applied last so users win. - config.extend(optional_values(overrides)); + config.extend(resolved_overrides(overrides).map(|(key, value)| (key, Some(value)))); to_hadoop_xml(config.iter()) } #[cfg(test)] mod tests { use super::*; + use crate::controller::build::properties::test_support::config_overrides; #[test] fn disabled_https_without_overrides_renders_empty_configuration() { assert_eq!( - build(false, &BTreeMap::new()), + build(false, config_overrides(&[])), "\n\n" ); } #[test] fn enabled_https_injects_truststore() { - let xml = build(true, &BTreeMap::new()); + let xml = build(true, config_overrides(&[])); assert!( xml.contains(&format!( "ssl.client.truststore.location\n {TLS_STORE_DIR}/truststore.p12" @@ -66,9 +69,7 @@ mod tests { #[test] fn user_overrides_win_over_injected_defaults() { - let overrides = - BTreeMap::from([("ssl.client.truststore.type".to_string(), "jks".to_string())]); - let xml = build(true, &overrides); + let xml = build(true, config_overrides(&[("ssl.client.truststore.type", "jks")])); assert!( xml.contains("ssl.client.truststore.type\n jks"), "{xml}" diff --git a/rust/operator-binary/src/controller/build/properties/ssl_server.rs b/rust/operator-binary/src/controller/build/properties/ssl_server.rs index 183c4c1a..ea80dcff 100644 --- a/rust/operator-binary/src/controller/build/properties/ssl_server.rs +++ b/rust/operator-binary/src/controller/build/properties/ssl_server.rs @@ -5,14 +5,16 @@ use std::collections::BTreeMap; +use stackable_operator::v2::config_overrides::KeyValueConfigOverrides; + use crate::{ config::writer::to_hadoop_xml, container::{TLS_STORE_DIR, TLS_STORE_PASSWORD}, - controller::build::properties::optional_values, + controller::build::properties::resolved_overrides, }; /// Renders `ssl-server.xml` for the given HTTPS state and user overrides. -pub fn build(https_enabled: bool, overrides: &BTreeMap) -> String { +pub fn build(https_enabled: bool, overrides: KeyValueConfigOverrides) -> String { let mut config: BTreeMap> = BTreeMap::new(); if https_enabled { config.extend([ @@ -43,25 +45,26 @@ pub fn build(https_enabled: bool, overrides: &BTreeMap) -> Strin ]); } // Overrides applied last so users win. - config.extend(optional_values(overrides)); + config.extend(resolved_overrides(overrides).map(|(key, value)| (key, Some(value)))); to_hadoop_xml(config.iter()) } #[cfg(test)] mod tests { use super::*; + use crate::controller::build::properties::test_support::config_overrides; #[test] fn disabled_https_without_overrides_renders_empty_configuration() { assert_eq!( - build(false, &BTreeMap::new()), + build(false, config_overrides(&[])), "\n\n" ); } #[test] fn enabled_https_injects_keystore_and_truststore() { - let xml = build(true, &BTreeMap::new()); + let xml = build(true, config_overrides(&[])); assert!( xml.contains(&format!( "ssl.server.keystore.location\n {TLS_STORE_DIR}/keystore.p12" @@ -78,9 +81,7 @@ mod tests { #[test] fn user_overrides_win_over_injected_defaults() { - let overrides = - BTreeMap::from([("ssl.server.keystore.type".to_string(), "jks".to_string())]); - let xml = build(true, &overrides); + let xml = build(true, config_overrides(&[("ssl.server.keystore.type", "jks")])); assert!( xml.contains("ssl.server.keystore.type\n jks"), "{xml}" diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 7f253c3c..862188cb 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -1,12 +1,21 @@ -use std::{collections::BTreeMap, str::FromStr}; +//! The validate step in the HdfsCluster controller. +//! +//! Synchronously merges and validates the cluster spec into the typed +//! [`ValidatedCluster`], consumed by `controller::build::*`. This replaces the +//! product-config `transform_all_roles_to_config` / +//! `validate_all_roles_and_groups_config` steps: config fragments are merged and +//! validated via [`HdfsNodeRole::merged_config`], and the per-file +//! `configOverrides` / `envOverrides` are merged here (role group wins). + +use std::collections::BTreeMap; -use product_config::ProductConfigManager; use snafu::{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, + config::merge::Merge, + role_utils::{GenericRoleConfig, JavaCommonConfig, Role}, }; +use strum::IntoEnumIterator; use crate::{ crd::{HdfsNodeRole, v1alpha1}, @@ -23,25 +32,6 @@ pub enum Error { source: product_image_selection::Error, }, - #[snafu(display("invalid role properties"))] - RoleProperties { source: crate::crd::Error }, - - #[snafu(display("failed to generate product config"))] - GenerateProductConfig { - source: stackable_operator::product_config_utils::Error, - }, - - #[snafu(display("invalid product configuration"))] - InvalidProductConfig { - source: stackable_operator::product_config_utils::Error, - }, - - #[snafu(display("could not parse HDFS role [{role}]"))] - UnidentifiedHdfsRole { - source: strum::ParseError, - role: String, - }, - #[snafu(display("failed to resolve and merge config for role and role group"))] FailedToResolveConfig { source: crate::crd::Error }, } @@ -49,7 +39,6 @@ pub enum Error { pub fn validate_cluster( hdfs: &v1alpha1::HdfsCluster, image_repository: &str, - product_config_manager: &ProductConfigManager, hdfs_opa_config: Option, ) -> Result { let resolved_product_image = hdfs @@ -62,25 +51,10 @@ pub fn validate_cluster( ) .context(ResolveProductImageSnafu)?; - let roles = hdfs.build_role_properties().context(RolePropertiesSnafu)?; - - let validated_config = validate_all_roles_and_groups_config( - &resolved_product_image.product_version, - &transform_all_roles_to_config(hdfs, &roles).context(GenerateProductConfigSnafu)?, - product_config_manager, - false, - false, - ) - .context(InvalidProductConfigSnafu)?; - let mut role_groups = BTreeMap::new(); let mut role_configs = BTreeMap::new(); - for (role_name, group_config) in validated_config.iter() { - let hdfs_role = HdfsNodeRole::from_str(role_name).context(UnidentifiedHdfsRoleSnafu { - role: role_name.to_string(), - })?; - + for hdfs_role in HdfsNodeRole::iter() { if let Some(GenericRoleConfig { pod_disruption_budget: pdb, }) = hdfs.role_config(&hdfs_role) @@ -88,17 +62,32 @@ pub fn validate_cluster( role_configs.insert(hdfs_role, ValidatedRoleConfig { pdb: pdb.clone() }); } + let role_group_overrides = match hdfs_role { + HdfsNodeRole::Name => collect_role_group_overrides(hdfs.spec.name_nodes.as_ref()), + HdfsNodeRole::Data => collect_role_group_overrides(hdfs.spec.data_nodes.as_ref()), + HdfsNodeRole::Journal => collect_role_group_overrides(hdfs.spec.journal_nodes.as_ref()), + }; + let mut group_configs = BTreeMap::new(); - for (rolegroup_name, rolegroup_config) in group_config.iter() { + for (role_group_name, config_overrides, mut env_overrides) in role_group_overrides { let merged_config = hdfs_role - .merged_config(hdfs, rolegroup_name) + .merged_config(hdfs, &role_group_name) .context(FailedToResolveConfigSnafu)?; + // Rack awareness topology labels, namenode only. Previously injected + // via the product-config `Configuration::compute_env`. + if hdfs_role == HdfsNodeRole::Name { + if let Some(rack_awareness) = hdfs.rackawareness_config() { + env_overrides.insert("TOPOLOGY_LABELS".to_string(), rack_awareness); + } + } + group_configs.insert( - rolegroup_name.clone(), + role_group_name, ValidatedRoleGroupConfig { merged_config, - product_config_properties: rolegroup_config.clone(), + config_overrides, + env_overrides, }, ); } @@ -113,3 +102,39 @@ pub fn validate_cluster( hdfs_opa_config, }) } + +/// Merges the role-level and role-group-level `configOverrides` and `envOverrides` +/// for every role group of a role (the role group wins). Replaces the +/// product-config `transform_all_roles_to_config` step. +fn collect_role_group_overrides( + role: Option<&Role>, +) -> Vec<(String, v1alpha1::HdfsConfigOverrides, BTreeMap)> { + let Some(role) = role else { + return Vec::new(); + }; + + role.role_groups + .iter() + .map(|(role_group_name, role_group)| { + let mut config_overrides = role_group.config.config_overrides.clone(); + config_overrides.merge(&role.config.config_overrides); + + let mut env_overrides = BTreeMap::new(); + env_overrides.extend( + role.config + .env_overrides + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); + env_overrides.extend( + role_group + .config + .env_overrides + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); + + (role_group_name.clone(), config_overrides, env_overrides) + }) + .collect() +} diff --git a/rust/operator-binary/src/crd/constants.rs b/rust/operator-binary/src/crd/constants.rs index 43676166..4f6df3ff 100644 --- a/rust/operator-binary/src/crd/constants.rs +++ b/rust/operator-binary/src/crd/constants.rs @@ -7,13 +7,7 @@ pub const FIELD_MANAGER_SCOPE: &str = "hdfscluster"; pub const APP_NAME: &str = "hdfs"; pub const FIELD_MANAGER: &str = "hdfs-operator"; -pub const HDFS_SITE_XML: &str = "hdfs-site.xml"; -pub const CORE_SITE_XML: &str = "core-site.xml"; -pub const HADOOP_POLICY_XML: &str = "hadoop-policy.xml"; -pub const SSL_SERVER_XML: &str = "ssl-server.xml"; -pub const SSL_CLIENT_XML: &str = "ssl-client.xml"; pub const LOG4J_PROPERTIES: &str = "log4j.properties"; -pub const JVM_SECURITY_PROPERTIES_FILE: &str = "security.properties"; pub const SERVICE_PORT_NAME_RPC: &str = "rpc"; pub const SERVICE_PORT_NAME_IPC: &str = "ipc"; diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index ecd78b86..f568e9d2 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -6,7 +6,6 @@ use std::{ }; use futures::future::try_join_all; -use product_config::types::PropertyNameKind; use security::AuthorizationConfig; use serde::{Deserialize, Serialize}; use snafu::{OptionExt, ResultExt, Snafu}; @@ -24,7 +23,6 @@ use stackable_operator::{ fragment::{self, Fragment, ValidationError}, merge::Merge, }, - config_overrides::{KeyValueConfigOverrides, KeyValueOverridesProvider}, crd::listener, deep_merger::ObjectOverrides, k8s_openapi::{ @@ -33,7 +31,6 @@ use stackable_operator::{ }, kube::{CustomResource, ResourceExt, runtime::reflector::ObjectRef}, kvp::{LabelError, Labels}, - product_config_utils::{Configuration, Error as ConfigError}, product_logging::{ self, spec::{ContainerLogConfig, Logging}, @@ -46,6 +43,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, IntoStaticStr}; @@ -53,22 +51,20 @@ use strum::{Display, EnumIter, EnumString, IntoStaticStr}; use crate::crd::{ affinity::get_affinity, constants::{ - APP_NAME, CORE_SITE_XML, DEFAULT_DATA_NODE_DATA_PORT, - DEFAULT_DATA_NODE_GRACEFUL_SHUTDOWN_TIMEOUT, DEFAULT_DATA_NODE_HTTP_PORT, - DEFAULT_DATA_NODE_HTTPS_PORT, DEFAULT_DATA_NODE_IPC_PORT, DEFAULT_DATA_NODE_METRICS_PORT, - DEFAULT_DATA_NODE_NATIVE_METRICS_HTTP_PORT, DEFAULT_DATA_NODE_NATIVE_METRICS_HTTPS_PORT, - DEFAULT_DFS_REPLICATION_FACTOR, DEFAULT_JOURNAL_NODE_GRACEFUL_SHUTDOWN_TIMEOUT, - DEFAULT_JOURNAL_NODE_HTTP_PORT, DEFAULT_JOURNAL_NODE_HTTPS_PORT, - DEFAULT_JOURNAL_NODE_METRICS_PORT, DEFAULT_JOURNAL_NODE_NATIVE_METRICS_HTTP_PORT, + APP_NAME, DEFAULT_DATA_NODE_DATA_PORT, DEFAULT_DATA_NODE_GRACEFUL_SHUTDOWN_TIMEOUT, + DEFAULT_DATA_NODE_HTTP_PORT, DEFAULT_DATA_NODE_HTTPS_PORT, DEFAULT_DATA_NODE_IPC_PORT, + DEFAULT_DATA_NODE_METRICS_PORT, DEFAULT_DATA_NODE_NATIVE_METRICS_HTTP_PORT, + DEFAULT_DATA_NODE_NATIVE_METRICS_HTTPS_PORT, DEFAULT_DFS_REPLICATION_FACTOR, + DEFAULT_JOURNAL_NODE_GRACEFUL_SHUTDOWN_TIMEOUT, DEFAULT_JOURNAL_NODE_HTTP_PORT, + DEFAULT_JOURNAL_NODE_HTTPS_PORT, DEFAULT_JOURNAL_NODE_METRICS_PORT, + DEFAULT_JOURNAL_NODE_NATIVE_METRICS_HTTP_PORT, DEFAULT_JOURNAL_NODE_NATIVE_METRICS_HTTPS_PORT, DEFAULT_JOURNAL_NODE_RPC_PORT, DEFAULT_LISTENER_CLASS, DEFAULT_NAME_NODE_GRACEFUL_SHUTDOWN_TIMEOUT, DEFAULT_NAME_NODE_HTTP_PORT, DEFAULT_NAME_NODE_HTTPS_PORT, DEFAULT_NAME_NODE_METRICS_PORT, DEFAULT_NAME_NODE_NATIVE_METRICS_HTTP_PORT, DEFAULT_NAME_NODE_NATIVE_METRICS_HTTPS_PORT, - DEFAULT_NAME_NODE_RPC_PORT, DFS_REPLICATION, HADOOP_POLICY_XML, HDFS_SITE_XML, - JVM_SECURITY_PROPERTIES_FILE, LISTENER_VOLUME_NAME, SERVICE_PORT_NAME_DATA, + DEFAULT_NAME_NODE_RPC_PORT, LISTENER_VOLUME_NAME, SERVICE_PORT_NAME_DATA, SERVICE_PORT_NAME_HTTP, SERVICE_PORT_NAME_HTTPS, SERVICE_PORT_NAME_IPC, SERVICE_PORT_NAME_JMX_METRICS, SERVICE_PORT_NAME_METRICS, SERVICE_PORT_NAME_RPC, - SSL_CLIENT_XML, SSL_SERVER_XML, }, security::{AuthenticationConfig, KerberosConfig}, storage::{ @@ -238,67 +234,32 @@ pub mod versioned { pub rack_awareness: Option>, } - #[derive(Clone, Debug, Default, Deserialize, JsonSchema, PartialEq, Serialize)] + #[derive(Clone, Debug, Default, Deserialize, Eq, JsonSchema, Merge, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct HdfsConfigOverrides { - #[serde( - default, - rename = "hdfs-site.xml", - skip_serializing_if = "Option::is_none" - )] - pub hdfs_site_xml: Option, - - #[serde( - default, - rename = "core-site.xml", - skip_serializing_if = "Option::is_none" - )] - pub core_site_xml: Option, - - #[serde( - default, - rename = "hadoop-policy.xml", - skip_serializing_if = "Option::is_none" - )] - pub hadoop_policy_xml: Option, - - #[serde( - default, - rename = "ssl-server.xml", - skip_serializing_if = "Option::is_none" - )] - pub ssl_server_xml: Option, - - #[serde( - default, - rename = "ssl-client.xml", - skip_serializing_if = "Option::is_none" - )] - pub ssl_client_xml: Option, - - #[serde( - default, - rename = "security.properties", - skip_serializing_if = "Option::is_none" - )] - pub security_properties: Option, - } -} + // File name defined in [`crate::controller::build::properties::ConfigFileName`] + #[serde(default, rename = "hdfs-site.xml")] + pub hdfs_site_xml: KeyValueConfigOverrides, -impl KeyValueOverridesProvider for v1alpha1::HdfsConfigOverrides { - fn get_key_value_overrides(&self, file: &str) -> BTreeMap> { - let field = match file { - HDFS_SITE_XML => self.hdfs_site_xml.as_ref(), - CORE_SITE_XML => self.core_site_xml.as_ref(), - HADOOP_POLICY_XML => self.hadoop_policy_xml.as_ref(), - SSL_SERVER_XML => self.ssl_server_xml.as_ref(), - SSL_CLIENT_XML => self.ssl_client_xml.as_ref(), - JVM_SECURITY_PROPERTIES_FILE => self.security_properties.as_ref(), - _ => None, - }; - field - .map(KeyValueConfigOverrides::as_product_config_overrides) - .unwrap_or_default() + // File name defined in [`crate::controller::build::properties::ConfigFileName`] + #[serde(default, rename = "core-site.xml")] + pub core_site_xml: KeyValueConfigOverrides, + + // File name defined in [`crate::controller::build::properties::ConfigFileName`] + #[serde(default, rename = "hadoop-policy.xml")] + pub hadoop_policy_xml: KeyValueConfigOverrides, + + // File name defined in [`crate::controller::build::properties::ConfigFileName`] + #[serde(default, rename = "ssl-server.xml")] + pub ssl_server_xml: KeyValueConfigOverrides, + + // File name defined in [`crate::controller::build::properties::ConfigFileName`] + #[serde(default, rename = "ssl-client.xml")] + pub ssl_client_xml: KeyValueConfigOverrides, + + // File name defined in [`crate::controller::build::properties::ConfigFileName`] + #[serde(default, rename = "security.properties")] + pub security_properties: KeyValueConfigOverrides, } } @@ -608,70 +569,6 @@ impl v1alpha1::HdfsCluster { } } - #[allow(clippy::type_complexity)] - pub fn build_role_properties( - &self, - ) -> Result< - HashMap< - String, - ( - Vec, - Role< - impl Configuration, - v1alpha1::HdfsConfigOverrides, - GenericRoleConfig, - JavaCommonConfig, - >, - ), - >, - Error, - > { - let mut result = HashMap::new(); - let pnk = vec![ - PropertyNameKind::File(HDFS_SITE_XML.to_string()), - PropertyNameKind::File(CORE_SITE_XML.to_string()), - PropertyNameKind::File(HADOOP_POLICY_XML.to_string()), - PropertyNameKind::File(SSL_SERVER_XML.to_string()), - PropertyNameKind::File(SSL_CLIENT_XML.to_string()), - PropertyNameKind::File(JVM_SECURITY_PROPERTIES_FILE.to_string()), - PropertyNameKind::Env, - ]; - - if let Some(name_nodes) = &self.spec.name_nodes { - result.insert( - HdfsNodeRole::Name.to_string(), - (pnk.clone(), name_nodes.clone().erase()), - ); - } else { - return Err(Error::MissingRole { - role: HdfsNodeRole::Name.to_string(), - }); - } - - if let Some(data_nodes) = &self.spec.data_nodes { - result.insert( - HdfsNodeRole::Data.to_string(), - (pnk.clone(), data_nodes.clone().erase()), - ); - } else { - return Err(Error::MissingRole { - role: HdfsNodeRole::Data.to_string(), - }); - } - - if let Some(journal_nodes) = &self.spec.journal_nodes { - result.insert( - HdfsNodeRole::Journal.to_string(), - (pnk, journal_nodes.clone().erase()), - ); - } else { - return Err(Error::MissingRole { - role: HdfsNodeRole::Journal.to_string(), - }); - } - - Ok(result) - } pub fn upgrade_state(&self) -> Result, UpgradeStateError> { use upgrade_state_error::*; @@ -1399,60 +1296,6 @@ impl NameNodeConfigFragment { } } -impl Configuration for NameNodeConfigFragment { - type Configurable = v1alpha1::HdfsCluster; - - fn compute_env( - &self, - resource: &Self::Configurable, - role_name: &str, - ) -> Result>, ConfigError> { - let mut result = BTreeMap::new(); - - // If rack awareness is configured, insert the labels into an env var to configure - // the topology-provider and add the artifact to the classpath. - // This is only needed on namenodes. - if role_name == HdfsNodeRole::Name.to_string() { - if let Some(awareness_config) = resource.rackawareness_config() { - result.insert("TOPOLOGY_LABELS".to_string(), Some(awareness_config)); - } - } - Ok(result) - } - - fn compute_cli( - &self, - _resource: &Self::Configurable, - _role_name: &str, - ) -> Result>, ConfigError> { - Ok(BTreeMap::new()) - } - - fn compute_files( - &self, - resource: &Self::Configurable, - role_name: &str, - file: &str, - ) -> Result>, ConfigError> { - let mut config = BTreeMap::new(); - if file == HDFS_SITE_XML { - config.insert( - DFS_REPLICATION.to_string(), - Some(resource.spec.cluster_config.dfs_replication.to_string()), - ); - } else if file == CORE_SITE_XML && role_name == HdfsNodeRole::Name.to_string() { - if let Some(_awareness_config) = resource.rackawareness_config() { - config.insert( - "net.topology.node.switch.mapping.impl".to_string(), - Some("tech.stackable.hadoop.StackableTopologyProvider".to_string()), - ); - } - } - - Ok(config) - } -} - #[derive( Clone, Debug, @@ -1541,43 +1384,6 @@ impl DataNodeConfigFragment { } } -impl Configuration for DataNodeConfigFragment { - type Configurable = v1alpha1::HdfsCluster; - - fn compute_env( - &self, - _resource: &Self::Configurable, - _role_name: &str, - ) -> Result>, ConfigError> { - Ok(BTreeMap::new()) - } - - fn compute_cli( - &self, - _resource: &Self::Configurable, - _role_name: &str, - ) -> Result>, ConfigError> { - Ok(BTreeMap::new()) - } - - fn compute_files( - &self, - resource: &Self::Configurable, - _role_name: &str, - file: &str, - ) -> Result>, ConfigError> { - let mut config = BTreeMap::new(); - if file == HDFS_SITE_XML { - config.insert( - DFS_REPLICATION.to_string(), - Some(resource.spec.cluster_config.dfs_replication.to_string()), - ); - } - - Ok(config) - } -} - #[derive( Clone, Debug, @@ -1654,35 +1460,6 @@ impl JournalNodeConfigFragment { } } -impl Configuration for JournalNodeConfigFragment { - type Configurable = v1alpha1::HdfsCluster; - - fn compute_env( - &self, - _resource: &Self::Configurable, - _role_name: &str, - ) -> Result>, ConfigError> { - Ok(BTreeMap::new()) - } - - fn compute_cli( - &self, - _resource: &Self::Configurable, - _role_name: &str, - ) -> Result>, ConfigError> { - Ok(BTreeMap::new()) - } - - fn compute_files( - &self, - _resource: &Self::Configurable, - _role_name: &str, - _file: &str, - ) -> Result>, ConfigError> { - Ok(BTreeMap::new()) - } -} - #[derive(Clone, Default, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct HdfsClusterStatus { diff --git a/rust/operator-binary/src/discovery.rs b/rust/operator-binary/src/discovery.rs index 71acdd67..47942a3d 100644 --- a/rust/operator-binary/src/discovery.rs +++ b/rust/operator-binary/src/discovery.rs @@ -10,11 +10,8 @@ use stackable_operator::{ use crate::{ build_recommended_labels, config::{CoreSiteConfigBuilder, HdfsSiteConfigBuilder}, - crd::{ - HdfsNodeRole, HdfsPodRef, - constants::{CORE_SITE_XML, HDFS_SITE_XML}, - v1alpha1, - }, + controller::build::properties::ConfigFileName, + crd::{HdfsNodeRole, HdfsPodRef, v1alpha1}, security::kerberos, }; @@ -71,11 +68,11 @@ pub fn build_discovery_configmap( ConfigMapBuilder::new() .metadata(metadata) .add_data( - HDFS_SITE_XML, + ConfigFileName::HdfsSite.to_string(), build_discovery_hdfs_site_xml(hdfs, cluster_info, hdfs.name_any(), namenode_podrefs), ) .add_data( - CORE_SITE_XML, + ConfigFileName::CoreSite.to_string(), build_discovery_core_site_xml(hdfs, cluster_info, hdfs.name_any())?, ) .build() diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index 9d66ca0d..e285d29f 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -1,10 +1,6 @@ -use std::{ - collections::{BTreeMap, HashMap}, - sync::Arc, -}; +use std::{collections::BTreeMap, str::FromStr, sync::Arc}; use const_format::concatcp; -use product_config::{ProductConfigManager, types::PropertyNameKind}; use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ builder::{ @@ -75,10 +71,10 @@ pub const HDFS_FULL_CONTROLLER_NAME: &str = concatcp!(HDFS_CONTROLLER_NAME, '.', pub const CONTAINER_IMAGE_BASE_NAME: &str = "hadoop"; -/// 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. +/// The validated cluster: proves that config merging and validation 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. #[derive(Clone, Debug)] pub struct ValidatedCluster { pub image: ResolvedProductImage, @@ -93,11 +89,13 @@ pub struct ValidatedRoleConfig { pub pdb: stackable_operator::commons::pdb::PdbConfig, } -/// Per-rolegroup configuration: the merged CRD config plus the product-config properties. +/// Per-rolegroup configuration: the merged CRD config plus the merged +/// (role <- role group) `configOverrides` and `envOverrides`. #[derive(Clone, Debug)] pub struct ValidatedRoleGroupConfig { pub merged_config: AnyNodeConfig, - pub product_config_properties: HashMap>, + pub config_overrides: v1alpha1::HdfsConfigOverrides, + pub env_overrides: BTreeMap, } #[derive(Snafu, Debug, EnumDiscriminants)] @@ -214,15 +212,18 @@ pub enum Error { source: stackable_operator::commons::rbac::Error, }, - #[snafu(display( - "failed to serialize {JVM_SECURITY_PROPERTIES_FILE:?} for {}", - rolegroup - ))] + #[snafu(display("failed to serialize {} for {rolegroup}", ConfigFileName::Security))] JvmSecurityProperties { source: PropertiesWriterError, rolegroup: String, }, + #[snafu(display("could not parse HDFS role [{role}]"))] + UnidentifiedHdfsRole { + source: strum::ParseError, + role: String, + }, + #[snafu(display("failed to configure graceful shutdown"))] GracefulShutdown { source: graceful_shutdown::Error }, @@ -262,7 +263,6 @@ pub type HdfsOperatorResult = Result; pub struct Ctx { pub client: Client, - pub product_config: ProductConfigManager, pub event_recorder: Arc, pub operator_environment: OperatorEnvironmentOptions, } @@ -287,7 +287,6 @@ pub async fn reconcile_hdfs( let validated = crate::controller::validate::validate_cluster( hdfs, &ctx.operator_environment.image_repository, - &ctx.product_config, dereferenced.hdfs_opa_config, ) .context(ValidateSnafu)?; @@ -373,9 +372,7 @@ pub async fn reconcile_hdfs( for (rolegroup_name, validated_rg_config) in group_config.iter() { let merged_config = &validated_rg_config.merged_config; - let env_overrides = validated_rg_config - .product_config_properties - .get(&PropertyNameKind::Env); + let env_overrides = &validated_rg_config.env_overrides; let rolegroup_ref = hdfs.rolegroup_ref(role_name, rolegroup_name); @@ -410,7 +407,7 @@ pub async fn reconcile_hdfs( &client.kubernetes_cluster_info, metadata, &rolegroup_ref, - &validated_rg_config.product_config_properties, + &validated_rg_config.config_overrides, &namenode_podrefs, &journalnode_podrefs, merged_config, @@ -424,7 +421,7 @@ pub async fn reconcile_hdfs( &role, &rolegroup_ref, resolved_product_image, - env_overrides, + Some(env_overrides), merged_config, &namenode_podrefs, &rbac_sa, @@ -573,13 +570,19 @@ fn rolegroup_config_map( cluster_info: &KubernetesClusterInfo, metadata: &ObjectMetaBuilder, rolegroup_ref: &RoleGroupRef, - rolegroup_config: &HashMap>, + config_overrides: &v1alpha1::HdfsConfigOverrides, namenode_podrefs: &[HdfsPodRef], journalnode_podrefs: &[HdfsPodRef], merged_config: &AnyNodeConfig, hdfs_opa_config: &Option, ) -> HdfsOperatorResult { tracing::info!("Setting up ConfigMap for {:?}", rolegroup_ref); + + let role = HdfsNodeRole::from_str(&rolegroup_ref.role).with_context(|_| { + UnidentifiedHdfsRoleSnafu { + role: rolegroup_ref.role.clone(), + } + })?; let hdfs_name = hdfs .metadata .name @@ -588,58 +591,32 @@ fn rolegroup_config_map( obj_ref: ObjectRef::from_obj(hdfs), })?; - let mut hdfs_site_xml = String::new(); - let mut core_site_xml = String::new(); - let mut hadoop_policy_xml = String::new(); - let mut ssl_server_xml = String::new(); - let mut ssl_client_xml = String::new(); - - for (property_name_kind, config) in rolegroup_config { - match property_name_kind { - PropertyNameKind::File(file_name) if file_name == HDFS_SITE_XML => { - hdfs_site_xml = hdfs_site::build( - hdfs, - hdfs_name, - cluster_info, - merged_config, - namenode_podrefs, - journalnode_podrefs, - hdfs_opa_config.as_ref(), - config, - ); - } - PropertyNameKind::File(file_name) if file_name == CORE_SITE_XML => { - core_site_xml = core_site::build( - hdfs, - hdfs_name, - cluster_info, - hdfs_opa_config.as_ref(), - config, - ) - .context(BuildCoreSiteXmlSnafu)?; - } - PropertyNameKind::File(file_name) if file_name == HADOOP_POLICY_XML => { - hadoop_policy_xml = hadoop_policy::build(config); - } - PropertyNameKind::File(file_name) if file_name == SSL_SERVER_XML => { - ssl_server_xml = ssl_server::build(hdfs.has_https_enabled(), config); - } - PropertyNameKind::File(file_name) if file_name == SSL_CLIENT_XML => { - ssl_client_xml = ssl_client::build(hdfs.has_https_enabled(), config); - } - _ => {} - } - } + let hdfs_site_xml = hdfs_site::build( + hdfs, + hdfs_name, + cluster_info, + merged_config, + namenode_podrefs, + journalnode_podrefs, + hdfs_opa_config.as_ref(), + config_overrides.hdfs_site_xml.clone(), + ); + let core_site_xml = core_site::build( + hdfs, + hdfs_name, + role, + cluster_info, + hdfs_opa_config.as_ref(), + config_overrides.core_site_xml.clone(), + ) + .context(BuildCoreSiteXmlSnafu)?; + let hadoop_policy_xml = hadoop_policy::build(config_overrides.hadoop_policy_xml.clone()); + let ssl_server_xml = + ssl_server::build(hdfs.has_https_enabled(), config_overrides.ssl_server_xml.clone()); + let ssl_client_xml = + ssl_client::build(hdfs.has_https_enabled(), config_overrides.ssl_client_xml.clone()); let mut builder = ConfigMapBuilder::new(); - - let security_properties_overrides = rolegroup_config - .get(&PropertyNameKind::File( - JVM_SECURITY_PROPERTIES_FILE.to_string(), - )) - .cloned() - .unwrap_or_default(); - builder .metadata(metadata.build()) .add_data(ConfigFileName::CoreSite.to_string(), core_site_xml) @@ -649,11 +626,11 @@ fn rolegroup_config_map( .add_data(ConfigFileName::SslClient.to_string(), ssl_client_xml) .add_data( ConfigFileName::Security.to_string(), - security_properties::build(&security_properties_overrides).with_context(|_| { - JvmSecurityPropertiesSnafu { + security_properties::build(config_overrides.security_properties.clone()).with_context( + |_| JvmSecurityPropertiesSnafu { rolegroup: rolegroup_ref.role_group.clone(), - } - })?, + }, + )?, ); extend_role_group_config_map(rolegroup_ref, merged_config, &mut builder).context( @@ -779,14 +756,10 @@ pub fn error_policy( #[cfg(test)] mod test { - use stackable_operator::{ - commons::networking::DomainName, - product_config_utils::{ - transform_all_roles_to_config, validate_all_roles_and_groups_config, - }, - }; + use stackable_operator::commons::networking::DomainName; use super::*; + use crate::controller::validate::validate_cluster; #[test] pub fn test_env_overrides() { @@ -820,43 +793,21 @@ spec: GROUP_VAR: group-value # only defined here at group level replicas: 1 "; - let product_config = " ---- -version: 0.1.0 -spec: - units: [] -properties: [] -"; - let hdfs: v1alpha1::HdfsCluster = serde_yaml::from_str(cr).unwrap(); - let roles = hdfs.build_role_properties().unwrap(); - let config = transform_all_roles_to_config(&hdfs, &roles).unwrap(); - - let validated_config = validate_all_roles_and_groups_config( - "3.4.0", - &config, - &product_config.parse::().unwrap(), - false, - false, - ) - .unwrap(); + let validated = validate_cluster(&hdfs, "oci.example.org", None).unwrap(); let role = HdfsNodeRole::Data; - let rolegroup_config = validated_config - .get(&role.to_string()) + let validated_rg_config = validated + .role_groups + .get(&role) .unwrap() .get("default") .unwrap(); let rolegroup_ref = hdfs.rolegroup_ref(role.to_string(), "default"); - let env_overrides = rolegroup_config.get(&PropertyNameKind::Env); - - let merged_config = role.merged_config(&hdfs, "default").unwrap(); - let resolved_product_image = hdfs - .spec - .image - .resolve(CONTAINER_IMAGE_BASE_NAME, "oci.example.org", "0.0.0-dev") - .expect("test resolved product image is always valid"); + let env_overrides = &validated_rg_config.env_overrides; + let merged_config = &validated_rg_config.merged_config; + let resolved_product_image = &validated.image; let mut pb = PodBuilder::new(); pb.metadata(ObjectMeta::default()); @@ -868,9 +819,9 @@ properties: [] }, &role, &rolegroup_ref, - &resolved_product_image, - &merged_config, - env_overrides, + resolved_product_image, + merged_config, + Some(env_overrides), &hdfs.spec.cluster_config.zookeeper_config_map_name, &[], &Labels::new(), diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 074059ee..8385e61c 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -77,7 +77,9 @@ async fn main() -> anyhow::Result<()> { Command::Run(RunArguments { operator_environment, watch_namespace, - product_config, + // product-config has been removed; the CLI argument is kept for + // backwards compatibility but ignored. + product_config: _, maintenance, common, }) => { @@ -122,11 +124,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/hdfs-operator/config-spec/properties.yaml", - ])?; - let (store, store_w) = reflector::store(); let hdfs_event_recorder = Arc::new(Recorder::new( @@ -194,7 +191,6 @@ async fn main() -> anyhow::Result<()> { event_recorder: hdfs_event_recorder.clone(), client: client.clone(), operator_environment, - product_config, }), ) // We can let the reporting happen in the background diff --git a/rust/operator-binary/src/security/kerberos.rs b/rust/operator-binary/src/security/kerberos.rs index 0b03280a..989f7af3 100644 --- a/rust/operator-binary/src/security/kerberos.rs +++ b/rust/operator-binary/src/security/kerberos.rs @@ -6,10 +6,8 @@ use stackable_operator::{ use crate::{ config::{CoreSiteConfigBuilder, HdfsSiteConfigBuilder}, - crd::{ - constants::{SSL_CLIENT_XML, SSL_SERVER_XML}, - v1alpha1, - }, + controller::build::properties::ConfigFileName, + crd::v1alpha1, }; pub const KERBEROS_CONTAINER_PATH: &str = "/stackable/kerberos"; @@ -32,8 +30,14 @@ impl HdfsSiteConfigBuilder { self.add("dfs.block.access.token.enable", "true") .add("dfs.http.policy", "HTTPS_ONLY") .add("hadoop.kerberos.keytab.login.autorenewal.enabled", "true") - .add("dfs.https.server.keystore.resource", SSL_SERVER_XML) - .add("dfs.https.client.keystore.resource", SSL_CLIENT_XML); + .add( + "dfs.https.server.keystore.resource", + ConfigFileName::SslServer.to_string(), + ) + .add( + "dfs.https.client.keystore.resource", + ConfigFileName::SslClient.to_string(), + ); self.add_wire_encryption_settings(); } self From 18d5d9f4d0185d9b7d0aecdf73ea86f995cf5eb5 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 20:34:43 +0200 Subject: [PATCH 08/18] chore: remove the product-config dependency The product-config crate is no longer used by the operator. Removes it from the workspace and operator-binary manifests and empties the config-spec properties.yaml (the schema now lives in the typed CRD and the per-file builders), mirroring trino-operator. product-config remains only as a transitive dependency of stackable-operator. Co-Authored-By: Claude Opus 4.8 (1M context) --- Cargo.lock | 1 - Cargo.nix | 4 - Cargo.toml | 1 - deploy/config-spec/properties.yaml | 281 +----------------- .../hdfs-operator/configs/properties.yaml | 281 +----------------- .../reference/commandline-parameters.adoc | 13 - rust/operator-binary/Cargo.toml | 1 - 7 files changed, 6 insertions(+), 576 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8749e1e..a3731e5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2913,7 +2913,6 @@ dependencies = [ "futures 0.3.32", "indoc", "java-properties", - "product-config", "rstest", "serde", "serde_json", diff --git a/Cargo.nix b/Cargo.nix index f97b0ac5..214ae2c8 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -9614,10 +9614,6 @@ rec { name = "java-properties"; packageId = "java-properties"; } - { - name = "product-config"; - packageId = "product-config"; - } { name = "serde"; packageId = "serde"; diff --git a/Cargo.toml b/Cargo.toml index 31052d9f..94904783 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ edition = "2021" repository = "https://github.com/stackabletech/hdfs-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.1", features = ["crds", "webhook"] } anyhow = "1.0" diff --git a/deploy/config-spec/properties.yaml b/deploy/config-spec/properties.yaml index 138cb22a..9bd8c3b2 100644 --- a/deploy/config-spec/properties.yaml +++ b/deploy/config-spec/properties.yaml @@ -1,280 +1,5 @@ +--- version: 0.1.0 spec: - units: - - unit: &unitUri - name: "uri" - regex: "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?" - examples: - - "ldap://[2001:db8::7]/c=GB?objectClass?one" - comment: "Specified in https://tools.ietf.org/html/rfc3986#appendix-B" - -properties: - - property: - propertyNames: - - name: "networkaddress.cache.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "30" - roles: - - name: "namenode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for successfully resolved domain names." - description: "TTL for successfully resolved domain names." - - - property: - propertyNames: - - name: "networkaddress.cache.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "30" - roles: - - name: "datanode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for successfully resolved domain names." - description: "TTL for successfully resolved domain names." - - - property: - propertyNames: - - name: "networkaddress.cache.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "30" - roles: - - name: "journalnode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for successfully resolved domain names." - description: "TTL for successfully resolved domain names." - - - property: - propertyNames: - - name: "networkaddress.cache.negative.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "0" - roles: - - name: "namenode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for domain names that cannot be resolved." - description: "TTL for domain names that cannot be resolved." - - - property: - propertyNames: - - name: "networkaddress.cache.negative.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "0" - roles: - - name: "datanode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for domain names that cannot be resolved." - description: "TTL for domain names that cannot be resolved." - - - property: - propertyNames: - - name: "networkaddress.cache.negative.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "0" - roles: - - name: "journalnode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for domain names that cannot be resolved." - description: "TTL for domain names that cannot be resolved." - - - property: - propertyNames: - - name: "dfs.namenode.name.dir" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - unit: *unitUri - roles: - - name: "namenode" - required: false - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "Determines where on the local filesystem the DFS name node should store the name table(fsimage). If this is a comma-delimited list of directories then the name table is replicated in all of the directories, for redundancy." - - - property: - propertyNames: - - name: "dfs.datanode.data.dir" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - unit: *unitUri - roles: - - name: "namenode" - required: false - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "Determines where on the local filesystem an DFS data node should store its blocks. If this is a comma-delimited list of directories, then data will be stored in all named directories, typically on different devices. Directories that do not exist are ignored." - - - property: - propertyNames: - - name: "dfs.replication" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "integer" - min: "1" - max: "512" - defaultValues: - - fromVersion: "0.0.0" - value: "3" - roles: - - name: "namenode" - required: true - - name: "datanode" - required: true - asOfVersion: "0.0.0" - description: "Default block replication. The actual number of replications can be specified when the file is created. The default is used if replication is not specified in create time." - - - property: - propertyNames: - - name: "fs.defaultFS" - kind: - type: "file" - file: "core-site.xml" - datatype: - type: "string" - unit: *unitUri - roles: - - name: "namenode" - required: false - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "The name of the default file system. A URI whose scheme and authority determine the FileSystem implementation. The uri's scheme determines the config property (fs.SCHEME.impl) naming the FileSystem implementation class. The uri's authority is used to determine the host, port, etc. for a filesystem." - - - property: - propertyNames: - - name: "dfs.namenode.http-address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "namenode" - required: false - asOfVersion: "0.0.0" - description: "The address and the base port where the dfs namenode web ui will listen on." - - - property: - propertyNames: - - name: "dfs.datanode.ipc.address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "The datanode ipc server address and port." - - - property: - propertyNames: - - name: "dfs.datanode.address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "The datanode server address and port for data transfer." - - - property: - propertyNames: - - name: "dfs.datanode.http.address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "The datanode http server address and port." - - - property: - propertyNames: - - name: "dfs.journalnode.http-address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "journalnode" - required: false - asOfVersion: "0.0.0" - description: "The address and port the JournalNode HTTP server listens on. If the port is 0 then the server will start on a free port." - - - property: - propertyNames: - - name: "dfs.journalnode.https-address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "journalnode" - required: false - asOfVersion: "0.0.0" - description: "The address and port the JournalNode HTTPS server listens on. If the port is 0 then the server will start on a free port." + units: [] +properties: [] diff --git a/deploy/helm/hdfs-operator/configs/properties.yaml b/deploy/helm/hdfs-operator/configs/properties.yaml index 138cb22a..9bd8c3b2 100644 --- a/deploy/helm/hdfs-operator/configs/properties.yaml +++ b/deploy/helm/hdfs-operator/configs/properties.yaml @@ -1,280 +1,5 @@ +--- version: 0.1.0 spec: - units: - - unit: &unitUri - name: "uri" - regex: "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?" - examples: - - "ldap://[2001:db8::7]/c=GB?objectClass?one" - comment: "Specified in https://tools.ietf.org/html/rfc3986#appendix-B" - -properties: - - property: - propertyNames: - - name: "networkaddress.cache.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "30" - roles: - - name: "namenode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for successfully resolved domain names." - description: "TTL for successfully resolved domain names." - - - property: - propertyNames: - - name: "networkaddress.cache.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "30" - roles: - - name: "datanode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for successfully resolved domain names." - description: "TTL for successfully resolved domain names." - - - property: - propertyNames: - - name: "networkaddress.cache.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "30" - roles: - - name: "journalnode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for successfully resolved domain names." - description: "TTL for successfully resolved domain names." - - - property: - propertyNames: - - name: "networkaddress.cache.negative.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "0" - roles: - - name: "namenode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for domain names that cannot be resolved." - description: "TTL for domain names that cannot be resolved." - - - property: - propertyNames: - - name: "networkaddress.cache.negative.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "0" - roles: - - name: "datanode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for domain names that cannot be resolved." - description: "TTL for domain names that cannot be resolved." - - - property: - propertyNames: - - name: "networkaddress.cache.negative.ttl" - kind: - type: "file" - file: "security.properties" - datatype: - type: "integer" - min: "0" - recommendedValues: - - fromVersion: "0.0.0" - value: "0" - roles: - - name: "journalnode" - required: true - asOfVersion: "0.0.0" - comment: "TTL for domain names that cannot be resolved." - description: "TTL for domain names that cannot be resolved." - - - property: - propertyNames: - - name: "dfs.namenode.name.dir" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - unit: *unitUri - roles: - - name: "namenode" - required: false - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "Determines where on the local filesystem the DFS name node should store the name table(fsimage). If this is a comma-delimited list of directories then the name table is replicated in all of the directories, for redundancy." - - - property: - propertyNames: - - name: "dfs.datanode.data.dir" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - unit: *unitUri - roles: - - name: "namenode" - required: false - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "Determines where on the local filesystem an DFS data node should store its blocks. If this is a comma-delimited list of directories, then data will be stored in all named directories, typically on different devices. Directories that do not exist are ignored." - - - property: - propertyNames: - - name: "dfs.replication" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "integer" - min: "1" - max: "512" - defaultValues: - - fromVersion: "0.0.0" - value: "3" - roles: - - name: "namenode" - required: true - - name: "datanode" - required: true - asOfVersion: "0.0.0" - description: "Default block replication. The actual number of replications can be specified when the file is created. The default is used if replication is not specified in create time." - - - property: - propertyNames: - - name: "fs.defaultFS" - kind: - type: "file" - file: "core-site.xml" - datatype: - type: "string" - unit: *unitUri - roles: - - name: "namenode" - required: false - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "The name of the default file system. A URI whose scheme and authority determine the FileSystem implementation. The uri's scheme determines the config property (fs.SCHEME.impl) naming the FileSystem implementation class. The uri's authority is used to determine the host, port, etc. for a filesystem." - - - property: - propertyNames: - - name: "dfs.namenode.http-address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "namenode" - required: false - asOfVersion: "0.0.0" - description: "The address and the base port where the dfs namenode web ui will listen on." - - - property: - propertyNames: - - name: "dfs.datanode.ipc.address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "The datanode ipc server address and port." - - - property: - propertyNames: - - name: "dfs.datanode.address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "The datanode server address and port for data transfer." - - - property: - propertyNames: - - name: "dfs.datanode.http.address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "datanode" - required: false - asOfVersion: "0.0.0" - description: "The datanode http server address and port." - - - property: - propertyNames: - - name: "dfs.journalnode.http-address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "journalnode" - required: false - asOfVersion: "0.0.0" - description: "The address and port the JournalNode HTTP server listens on. If the port is 0 then the server will start on a free port." - - - property: - propertyNames: - - name: "dfs.journalnode.https-address" - kind: - type: "file" - file: "hdfs-site.xml" - datatype: - type: "string" - roles: - - name: "journalnode" - required: false - asOfVersion: "0.0.0" - description: "The address and port the JournalNode HTTPS server listens on. If the port is 0 then the server will start on a free port." + units: [] +properties: [] diff --git a/docs/modules/hdfs/pages/reference/commandline-parameters.adoc b/docs/modules/hdfs/pages/reference/commandline-parameters.adoc index c3f62f6d..7e0831f7 100644 --- a/docs/modules/hdfs/pages/reference/commandline-parameters.adoc +++ b/docs/modules/hdfs/pages/reference/commandline-parameters.adoc @@ -2,19 +2,6 @@ This operator accepts the following command line parameters: -== product-config - -*Default value*: `/etc/stackable/hdfs-operator/config-spec/properties.yaml` - -*Required*: false - -*Multiple values:* false - -[source] ----- -stackable-hdfs-operator run --product-config /foo/bar/properties.yaml ----- - == watch-namespace *Default value*: All namespaces diff --git a/rust/operator-binary/Cargo.toml b/rust/operator-binary/Cargo.toml index 4e535267..4bbbd53f 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 From 34263a99c3b4d28625ce50adc6a4a2bdf8599045 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 20:40:31 +0200 Subject: [PATCH 09/18] chore: run linters, regenerate charts, update dependencies --- Cargo.lock | 607 ++++---- Cargo.nix | 1272 ++++++----------- Cargo.toml | 4 +- extra/crds.yaml | 108 +- rust/operator-binary/src/config/mod.rs | 35 +- rust/operator-binary/src/config/writer.rs | 5 +- .../controller/build/properties/hdfs_site.rs | 4 +- .../src/controller/build/properties/mod.rs | 5 +- .../controller/build/properties/ssl_client.rs | 5 +- .../controller/build/properties/ssl_server.rs | 5 +- .../src/controller/validate.rs | 6 +- rust/operator-binary/src/crd/mod.rs | 1 - rust/operator-binary/src/hdfs_controller.rs | 14 +- 13 files changed, 855 insertions(+), 1216 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3731e5c..d95e8bb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -47,9 +47,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -62,15 +62,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -103,9 +103,9 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arc-swap" -version = "1.8.2" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f3647c145568cec02c42054e07bdf9a5a698e15b466fb2341bfc393cd24aa5" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", ] @@ -163,15 +163,15 @@ 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" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", "bytes", @@ -265,9 +265,9 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +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.56" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "jobserver", @@ -331,9 +331,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.60" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -341,9 +341,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -353,9 +353,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.55" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -365,15 +365,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "concurrent-queue" @@ -392,11 +392,12 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" dependencies = [ "const_format_proc_macros", + "konst", ] [[package]] @@ -612,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", @@ -675,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" @@ -787,9 +788,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "ff" @@ -923,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" @@ -982,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]] @@ -1024,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", @@ -1052,6 +1052,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + [[package]] name = "heck" version = "0.5.0" @@ -1080,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", @@ -1131,9 +1137,9 @@ checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" -version = "1.8.1" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -1146,7 +1152,6 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -1154,9 +1159,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.7" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http", "hyper", @@ -1164,7 +1169,6 @@ dependencies = [ "log", "rustls", "rustls-native-certs", - "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", @@ -1232,12 +1236,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1245,9 +1250,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -1258,9 +1263,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1272,15 +1277,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -1292,15 +1297,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -1330,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", @@ -1340,12 +1345,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.17.1", ] [[package]] @@ -1359,19 +1364,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" -dependencies = [ - "memchr", - "serde", -] +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "is_terminal_polyfill" @@ -1390,9 +1385,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "java-properties" @@ -1407,9 +1402,9 @@ dependencies = [ [[package]] name = "jiff" -version = "0.2.21" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e3d65f018c6ae946ab16e80944b97096ed73c35b221d1c478a6c81d8f57940" +checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" dependencies = [ "jiff-static", "jiff-tzdb-platform", @@ -1417,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.21" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17c2b211d863c7fde02cbea8a3c1a439b98e109286554f2860bdded7ff83818" +checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" dependencies = [ "proc-macro2", "quote", @@ -1433,9 +1428,9 @@ dependencies = [ [[package]] name = "jiff-tzdb" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68971ebff725b9e2ca27a601c5eb38a4c5d64422c4cbab0c535f248087eda5c2" +checksum = "c900ef84826f1338a557697dc8fc601df9ca9af4ac137c7fb61d4c6f2dfd3076" [[package]] name = "jiff-tzdb-platform" @@ -1458,25 +1453,27 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.90" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dc6f6450b3f6d4ed5b16327f38fed626d375a886159ca555bd7822c0c3a5a6" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] [[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]] @@ -1504,9 +1501,9 @@ dependencies = [ [[package]] name = "k8s-openapi" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05a6d6f3611ad1d21732adbd7a2e921f598af6c92d71ae6e2620da4b67ee1f0d" +checksum = "51b326f5219dd55872a72c1b6ddd1b830b8334996c667449c29391d657d78d5e" dependencies = [ "base64", "jiff", @@ -1522,9 +1519,24 @@ source = "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-op dependencies = [ "darling", "regex", - "snafu 0.9.0", + "snafu 0.9.1", +] + +[[package]] +name = "konst" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" +dependencies = [ + "konst_macro_rules", ] +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "kube" version = "3.1.0" @@ -1618,7 +1630,7 @@ dependencies = [ "backon", "educe", "futures 0.3.32", - "hashbrown", + "hashbrown 0.16.1", "hostname", "json-patch", "k8s-openapi", @@ -1644,15 +1656,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.182" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +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", @@ -1668,9 +1680,9 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libz-sys" -version = "1.1.24" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4735e9cbde5aac84a5ce588f6b23a90b9b0b528f6c5a8db8a4aff300463a0839" +checksum = "85bc9657773828b90eeb625adff10eeac83cc21bbfd8e23a03eaa8a33c9e28d9" dependencies = [ "cc", "libc", @@ -1680,9 +1692,9 @@ dependencies = [ [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" @@ -1695,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" @@ -1716,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" @@ -1738,9 +1750,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -1767,16 +1779,16 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "smallvec", "zeroize", ] [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -1810,9 +1822,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -1867,9 +1879,9 @@ dependencies = [ [[package]] name = "opentelemetry-otlp" -version = "0.31.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" +checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" dependencies = [ "http", "opentelemetry", @@ -1914,7 +1926,7 @@ dependencies = [ "futures-util", "opentelemetry", "percent-encoding", - "rand 0.9.2", + "rand 0.9.4", "thiserror 2.0.18", "tokio", "tokio-stream", @@ -2040,18 +2052,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -2060,15 +2072,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs1" @@ -2093,9 +2099,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "portable-atomic" @@ -2105,18 +2111,18 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -2147,9 +2153,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ "toml_edit", ] @@ -2204,9 +2210,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -2219,9 +2225,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "rand_chacha 0.3.1", "rand_core 0.6.4", @@ -2229,9 +2235,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.5", @@ -2458,9 +2464,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.37" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "log", "once_cell", @@ -2473,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", @@ -2485,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", ] @@ -2517,9 +2523,9 @@ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -2604,9 +2610,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" @@ -2661,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", @@ -2741,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" @@ -2767,9 +2773,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "slab" @@ -2804,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]] @@ -2836,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", @@ -2848,12 +2854,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2888,12 +2894,12 @@ dependencies = [ "k8s-openapi", "kube", "p256", - "rand 0.9.2", + "rand 0.9.4", "rand_core 0.6.4", "rsa", "sha2", "signature", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-shared", "tokio", "tokio-rustls", @@ -2917,7 +2923,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-operator", "strum", "tokio", @@ -2946,14 +2952,14 @@ dependencies = [ "k8s-openapi", "kube", "product-config", - "rand 0.9.2", + "rand 0.9.4", "regex", "schemars", "semver", "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-operator-derive", "stackable-shared", "stackable-telemetry", @@ -2991,7 +2997,7 @@ dependencies = [ "semver", "serde", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "strum", "time", ] @@ -3010,7 +3016,7 @@ dependencies = [ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "pin-project", - "snafu 0.9.0", + "snafu 0.9.1", "strum", "tokio", "tower", @@ -3030,7 +3036,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-versioned-macros", ] @@ -3068,10 +3074,10 @@ dependencies = [ "kube", "opentelemetry", "opentelemetry-semantic-conventions", - "rand 0.9.2", + "rand 0.9.4", "serde", "serde_json", - "snafu 0.9.0", + "snafu 0.9.1", "stackable-certs", "stackable-shared", "stackable-telemetry", @@ -3117,6 +3123,12 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "symlink" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" + [[package]] name = "syn" version = "1.0.109" @@ -3241,9 +3253,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -3272,9 +3284,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.49.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -3289,9 +3301,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -3335,18 +3347,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", "toml_datetime", @@ -3356,18 +3368,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ "winnow", ] [[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", @@ -3392,9 +3404,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", @@ -3422,9 +3434,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", @@ -3432,13 +3444,13 @@ dependencies = [ "futures-util", "http", "http-body", - "iri-string", "mime", "pin-project-lite", "tower", "tower-layer", "tower-service", "tracing", + "url", ] [[package]] @@ -3467,11 +3479,12 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c" dependencies = [ "crossbeam-channel", + "symlink", "thiserror 2.0.18", "time", "tracing-subscriber", @@ -3549,9 +3562,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -3576,9 +3589,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "ucd-trie" @@ -3594,9 +3607,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-xid" @@ -3686,18 +3699,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.113" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60722a937f594b7fde9adb894d7c092fc1bb6612897c46368d18e7a20208eff2" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -3708,23 +3721,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.63" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a89f4650b770e4521aa6573724e2aed4704372151bd0de9d16a3bbabb87441a" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ - "cfg-if", - "futures-util", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.113" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac8c6395094b6b91c4af293f4c79371c163f9a6f56184d2c9a85f5a95f3950" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3732,9 +3741,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.113" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3fabce6159dc20728033842636887e4877688ae94382766e00b180abac9d60" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -3745,18 +3754,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.113" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0e091bdb824da87dc01d967388880d017a0a9bc4f3bdc0d86ee9f9336e3bb5" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.90" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705eceb4ce901230f8625bd1d665128056ccbe4b7408faa625eec1ba80f59a97" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -3837,16 +3846,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -3864,31 +3864,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -3897,116 +3880,68 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" -version = "0.7.14" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "x509-cert" @@ -4030,9 +3965,9 @@ checksum = "636f85e5ca6488e96401b61eb7de54f4e44755c988af0f52cf90230c312a1a89" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -4041,9 +3976,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -4053,18 +3988,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.40" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a789c6e490b576db9f7e6b6d661bcc9799f7c0ac8352f56ea20193b2681532e5" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.40" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f65c489a7071a749c849713807783f70672b28094011623e200cb86dcb835953" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" dependencies = [ "proc-macro2", "quote", @@ -4073,18 +4008,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -4114,9 +4049,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -4125,9 +4060,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -4136,9 +4071,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.nix b/Cargo.nix index 214ae2c8..7c3a2886 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -216,9 +216,9 @@ rec { }; "anstream" = rec { crateName = "anstream"; - version = "0.6.21"; + version = "1.0.0"; edition = "2021"; - sha256 = "0jjgixms4qjj58dzr846h2s29p8w7ynwr9b9x6246m1pwy0v5ma3"; + sha256 = "13d2bj0xfg012s4rmq44zc8zgy1q8k9yp7yhvfnarscnmwpj2jl2"; dependencies = [ { name = "anstyle"; @@ -261,9 +261,9 @@ rec { }; "anstyle" = rec { crateName = "anstyle"; - version = "1.0.13"; + version = "1.0.14"; edition = "2021"; - sha256 = "0y2ynjqajpny6q0amvfzzgw0gfw3l47z85km4gvx87vg02lcr4ji"; + sha256 = "0030szmgj51fxkic1hpakxxgappxzwm6m154a3gfml83lq63l2wl"; features = { "default" = [ "std" ]; }; @@ -271,9 +271,9 @@ rec { }; "anstyle-parse" = rec { crateName = "anstyle-parse"; - version = "0.2.7"; + version = "1.0.0"; edition = "2021"; - sha256 = "1hhmkkfr95d462b3zf6yl2vfzdqfy5726ya572wwg8ha9y148xjf"; + sha256 = "03hkv2690s0crssbnmfkr76kw1k7ah2i6s5amdy9yca2n8w7zkjj"; libName = "anstyle_parse"; dependencies = [ { @@ -345,9 +345,9 @@ rec { }; "arc-swap" = rec { crateName = "arc-swap"; - version = "1.8.2"; + version = "1.9.1"; edition = "2018"; - sha256 = "19aas8y3kz0v6jr6yijvw6cad9grpl3lw1a25k0cws2m2iy69wzr"; + sha256 = "01xjlahcya8igdalxmda375lnlhjqwjz0cdqhy0bc1jkyzb1yfka"; libName = "arc_swap"; authors = [ "Michal 'vorner' Vaner " @@ -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 " ]; @@ -499,9 +499,9 @@ rec { }; "axum" = rec { crateName = "axum"; - version = "0.8.8"; + version = "0.8.9"; edition = "2021"; - sha256 = "1f4p0m04mgwpn8b40i9r5mgqxk6w11sv4yri6xfqk305nhyayllb"; + sha256 = "146df5x8dhczm1sp939gr3839220wl6rxc1k65bzc450z72ridii"; dependencies = [ { name = "axum-core"; @@ -866,9 +866,9 @@ rec { }; "bitflags" = rec { crateName = "bitflags"; - version = "2.11.0"; + version = "2.12.1"; edition = "2021"; - sha256 = "1bwjibwry5nfwsfm9kjg2dqx5n5nja9xymwbfl6svnn8jsz6ff44"; + 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.56"; + version = "1.2.63"; edition = "2018"; - sha256 = "1chvh9g2izhqad7vzy4cc7xpdljdvqpsr6x6hv1hmyqv3mlkbgxf"; + sha256 = "0zy2bqc4nvj6bv2cipx4h4bn65wf1zqf1fw1hsh64mmvg1hh2vjm"; authors = [ "Alex Crichton " ]; @@ -1060,10 +1061,10 @@ rec { }; "clap" = rec { crateName = "clap"; - version = "4.5.60"; - edition = "2021"; + version = "4.6.1"; + edition = "2024"; crateBin = []; - sha256 = "02h3nzznssjgp815nnbzk0r62y2iw03kdli75c233kirld6z75r7"; + sha256 = "0lcf88l7vlg796rrqr7wipbbmfa5sgsgx4211b7xmxxv8dz13nqx"; dependencies = [ { name = "clap_builder"; @@ -1102,9 +1103,9 @@ rec { }; "clap_builder" = rec { crateName = "clap_builder"; - version = "4.5.60"; - edition = "2021"; - sha256 = "0xk8mdizvmmn6w5ij5cwhy5pbgyac4w9pfvl6nqmjl7a5hql38i4"; + version = "4.6.0"; + edition = "2024"; + sha256 = "17q6np22yxhh5y5v53y4l31ps3hlaz45mvz2n2nicr7n3c056jki"; dependencies = [ { name = "anstream"; @@ -1141,9 +1142,9 @@ rec { }; "clap_derive" = rec { crateName = "clap_derive"; - version = "4.5.55"; - edition = "2021"; - sha256 = "1r949xis3jmhzh387smd70vc8a3b9734ck3g5ahg59a63bd969x9"; + version = "4.6.1"; + edition = "2024"; + sha256 = "1acpz49hi00iv9jkapixjzcv7s51x8qkfaqscjm36rqgf428dkpj"; procMacro = true; dependencies = [ { @@ -1173,16 +1174,16 @@ rec { }; "clap_lex" = rec { crateName = "clap_lex"; - version = "1.0.0"; - edition = "2021"; - sha256 = "0c8888qi1l9sayqlv666h8s0yxn2qc6jr88v1zagk43mpjjjx0is"; + version = "1.1.0"; + edition = "2024"; + sha256 = "1ycqkpygnlqnndghhcxjb44lzl0nmgsia64x9581030yifxs7m68"; }; "colorchoice" = rec { crateName = "colorchoice"; - version = "1.0.4"; + version = "1.0.5"; edition = "2021"; - sha256 = "0x8ymkz1xr77rcj1cfanhf416pc4v681gmkc9dzb3jqja7f62nxh"; + sha256 = "0w75k89hw39p0mnnhlrwr23q50rza1yjki44qvh2mgrnj065a1qx"; }; "concurrent-queue" = rec { @@ -1226,9 +1227,9 @@ rec { }; "const_format" = rec { crateName = "const_format"; - version = "0.2.35"; + version = "0.2.36"; edition = "2021"; - sha256 = "1b9h03z3k76ail1ldqxcqmsc4raa7dwgwwqwrjf6wmism5lp9akz"; + sha256 = "07ncczs8yndga2f8p4386c827l4fxwzl0pbwp7ijnhcsmlbsd0a4"; authors = [ "rodrimati1992 " ]; @@ -1237,6 +1238,12 @@ rec { name = "const_format_proc_macros"; packageId = "const_format_proc_macros"; } + { + name = "konst"; + packageId = "konst"; + usesDefaultFeatures = false; + features = [ "rust_1_64" ]; + } ]; features = { "__debug" = [ "const_format_proc_macros/debug" ]; @@ -1250,10 +1257,9 @@ rec { "constant_time_as_str" = [ "fmt" ]; "derive" = [ "fmt" "const_format_proc_macros/derive" ]; "fmt" = [ "rust_1_83" ]; - "konst" = [ "dep:konst" ]; "more_str_macros" = [ "rust_1_64" ]; "nightly_const_generics" = [ "const_generics" ]; - "rust_1_64" = [ "rust_1_51" "konst" "konst/rust_1_64" ]; + "rust_1_64" = [ "rust_1_51" ]; "rust_1_83" = [ "rust_1_64" ]; }; resolvedDefaultFeatures = [ "default" ]; @@ -1901,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 " @@ -2103,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" ]; @@ -2452,9 +2455,9 @@ rec { }; "fastrand" = rec { crateName = "fastrand"; - version = "2.3.0"; + version = "2.4.1"; edition = "2018"; - sha256 = "1ghiahsw1jd68df895cy5h3gzwk30hndidn3b682zmshpgmrx41p"; + sha256 = "1mnqxxnxvd69ma9mczabpbbsgwlhd6l78yv3vd681453a9s247wz"; authors = [ "Stjepan Glavina " ]; @@ -2825,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 " @@ -3085,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 " @@ -3109,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" ]; @@ -3209,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 " @@ -3279,7 +3279,7 @@ rec { features = { }; }; - "hashbrown" = rec { + "hashbrown 0.16.1" = rec { crateName = "hashbrown"; version = "0.16.1"; edition = "2021"; @@ -3322,6 +3322,24 @@ rec { }; resolvedDefaultFeatures = [ "allocator-api2" "default" "default-hasher" "equivalent" "inline-more" "raw-entry" ]; }; + "hashbrown 0.17.1" = rec { + crateName = "hashbrown"; + version = "0.17.1"; + edition = "2024"; + sha256 = "0jmqz7i4yl6cm7rbn0i2ffkfrmwi6xkmzkaldr2v8bcsx2v0jngd"; + features = { + "alloc" = [ "dep:alloc" ]; + "allocator-api2" = [ "dep:allocator-api2" ]; + "core" = [ "dep:core" ]; + "default" = [ "default-hasher" "inline-more" "allocator-api2" "equivalent" "raw-entry" ]; + "default-hasher" = [ "dep:foldhash" ]; + "equivalent" = [ "dep:equivalent" ]; + "nightly" = [ "foldhash?/nightly" "bumpalo/allocator_api" ]; + "rayon" = [ "dep:rayon" ]; + "rustc-dep-of-std" = [ "nightly" "core" "alloc" "rustc-internal-api" ]; + "serde" = [ "dep:serde_core" "dep:serde" ]; + }; + }; "heck" = rec { crateName = "heck"; version = "0.5.0"; @@ -3383,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 " @@ -3502,9 +3520,9 @@ rec { }; "hyper" = rec { crateName = "hyper"; - version = "1.8.1"; + version = "1.10.1"; edition = "2021"; - sha256 = "04cxr8j5y86bhxxlyqb8xkxjskpajk7cxwfzzk4v3my3a3rd9cia"; + sha256 = "1624nwrh1ci34psqcl3q8q266kha8kd6fmqjj14qck49l59iqa2m"; authors = [ "Sean McArthur " ]; @@ -3561,11 +3579,6 @@ rec { packageId = "pin-project-lite"; optional = true; } - { - name = "pin-utils"; - packageId = "pin-utils"; - optional = true; - } { name = "smallvec"; packageId = "smallvec"; @@ -3603,7 +3616,7 @@ rec { "client" = [ "dep:want" "dep:pin-project-lite" "dep:smallvec" ]; "ffi" = [ "dep:http-body-util" "dep:futures-util" ]; "full" = [ "client" "http1" "http2" "server" ]; - "http1" = [ "dep:atomic-waker" "dep:futures-channel" "dep:futures-core" "dep:httparse" "dep:itoa" "dep:pin-utils" ]; + "http1" = [ "dep:atomic-waker" "dep:futures-channel" "dep:futures-core" "dep:httparse" "dep:itoa" ]; "http2" = [ "dep:futures-channel" "dep:futures-core" "dep:h2" ]; "server" = [ "dep:httpdate" "dep:pin-project-lite" "dep:smallvec" ]; "tracing" = [ "dep:tracing" ]; @@ -3612,9 +3625,9 @@ rec { }; "hyper-rustls" = rec { crateName = "hyper-rustls"; - version = "0.27.7"; + version = "0.27.9"; edition = "2021"; - sha256 = "0n6g8998szbzhnvcs1b7ibn745grxiqmlpg53xz206v826v3xjg3"; + sha256 = "03vfnsm873wsp1dk0q85nxvk7w6syp8c2m5bcdjcyfgg4786ijik"; libName = "hyper_rustls"; dependencies = [ { @@ -3647,11 +3660,6 @@ rec { packageId = "rustls-native-certs"; optional = true; } - { - name = "rustls-pki-types"; - packageId = "rustls-pki-types"; - rename = "pki-types"; - } { name = "tokio"; packageId = "tokio"; @@ -3951,9 +3959,9 @@ rec { }; "icu_collections" = rec { crateName = "icu_collections"; - version = "2.1.1"; + version = "2.2.0"; edition = "2021"; - sha256 = "0hsblchsdl64q21qwrs4hvc2672jrf466zivbj1bwyv606bn8ssc"; + sha256 = "070r7xd0pynm0hnc1v2jzlbxka6wf50f81wybf9xg0y82v6x3119"; authors = [ "The ICU4X Project Developers" ]; @@ -3969,6 +3977,11 @@ rec { usesDefaultFeatures = false; features = [ "zerovec" ]; } + { + name = "utf8_iter"; + packageId = "utf8_iter"; + usesDefaultFeatures = false; + } { name = "yoke"; packageId = "yoke"; @@ -3996,9 +4009,9 @@ rec { }; "icu_locale_core" = rec { crateName = "icu_locale_core"; - version = "2.1.1"; + version = "2.2.0"; edition = "2021"; - sha256 = "1djvdc2f5ylmp1ymzv4gcnmq1s4hqfim9nxlcm173lsd01hpifpd"; + sha256 = "0a9cmin5w1x3bg941dlmgszn33qgq428k7qiqn5did72ndi9n8cj"; authors = [ "The ICU4X Project Developers" ]; @@ -4030,6 +4043,14 @@ rec { usesDefaultFeatures = false; } ]; + devDependencies = [ + { + name = "litemap"; + packageId = "litemap"; + usesDefaultFeatures = false; + features = [ "testing" ]; + } + ]; features = { "alloc" = [ "litemap/alloc" "tinystr/alloc" "writeable/alloc" "serde?/alloc" ]; "databake" = [ "dep:databake" "alloc" ]; @@ -4040,9 +4061,9 @@ rec { }; "icu_normalizer" = rec { crateName = "icu_normalizer"; - version = "2.1.1"; + version = "2.2.0"; edition = "2021"; - sha256 = "16dmn5596la2qm0r3vih0bzjfi0vx9a20yqjha6r1y3vnql8hv2z"; + sha256 = "1d7krxr0xpc4x9635k1100a24nh0nrc59n65j6yk6gbfkplmwvn5"; authors = [ "The ICU4X Project Developers" ]; @@ -4084,6 +4105,7 @@ rec { "compiled_data" = [ "dep:icu_normalizer_data" "icu_properties?/compiled_data" "icu_provider/baked" ]; "datagen" = [ "serde" "dep:databake" "icu_properties" "icu_collections/databake" "zerovec/databake" "icu_properties?/datagen" "icu_provider/export" ]; "default" = [ "compiled_data" "utf8_iter" "utf16_iter" ]; + "harfbuzz_traits" = [ "dep:harfbuzz-traits" ]; "icu_properties" = [ "dep:icu_properties" ]; "serde" = [ "dep:serde" "icu_collections/serde" "zerovec/serde" "icu_properties?/serde" "icu_provider/serde" ]; "utf16_iter" = [ "dep:utf16_iter" "dep:write16" ]; @@ -4093,9 +4115,9 @@ rec { }; "icu_normalizer_data" = rec { crateName = "icu_normalizer_data"; - version = "2.1.1"; + version = "2.2.0"; edition = "2021"; - sha256 = "02jnzizg6q75m41l6c13xc7nkc5q8yr1b728dcgfhpzw076wrvbs"; + sha256 = "0f5d5d5fhhr9937m2z6z38fzh6agf14z24kwlr6lyczafypf0fys"; authors = [ "The ICU4X Project Developers" ]; @@ -4103,9 +4125,9 @@ rec { }; "icu_properties" = rec { crateName = "icu_properties"; - version = "2.1.2"; + version = "2.2.0"; edition = "2021"; - sha256 = "1v3lbmhhi7i6jgw51ikjb1p50qh5rb67grlkdnkc63l7zq1gq2q2"; + sha256 = "1pkh3s837808cbwxvfagwc28cvwrz2d9h5rl02jwrhm51ryvdqxy"; authors = [ "The ICU4X Project Developers" ]; @@ -4150,6 +4172,7 @@ rec { "compiled_data" = [ "dep:icu_properties_data" "icu_provider/baked" ]; "datagen" = [ "serde" "dep:databake" "zerovec/databake" "icu_collections/databake" "icu_locale_core/databake" "zerotrie/databake" "icu_provider/export" ]; "default" = [ "compiled_data" ]; + "harfbuzz_traits" = [ "dep:harfbuzz-traits" ]; "serde" = [ "dep:serde" "icu_locale_core/serde" "zerovec/serde" "icu_collections/serde" "icu_provider/serde" "zerotrie/serde" ]; "unicode_bidi" = [ "dep:unicode-bidi" ]; }; @@ -4157,9 +4180,9 @@ rec { }; "icu_properties_data" = rec { crateName = "icu_properties_data"; - version = "2.1.2"; + version = "2.2.0"; edition = "2021"; - sha256 = "1bvpkh939rgzrjfdb7hz47v4wijngk0snmcgrnpwc9fpz162jv31"; + sha256 = "052awny0qwkbcbpd5jg2cd7vl5ry26pq4hz1nfsgf10c3qhbnawf"; authors = [ "The ICU4X Project Developers" ]; @@ -4167,9 +4190,9 @@ rec { }; "icu_provider" = rec { crateName = "icu_provider"; - version = "2.1.1"; + version = "2.2.0"; edition = "2021"; - sha256 = "0576b7dizgyhpfa74kacv86y4g1p7v5ffd6c56kf1q82rvq2r5l5"; + sha256 = "08dl8pxbwr8zsz4c5vphqb7xw0hykkznwi4rw7bk6pwb3krlr70k"; authors = [ "The ICU4X Project Developers" ]; @@ -4270,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" ]; @@ -4295,9 +4318,9 @@ rec { }; "indexmap" = rec { crateName = "indexmap"; - version = "2.13.0"; - edition = "2021"; - sha256 = "05qh5c4h2hrnyypphxpwflk45syqbzvqsvvyxg43mp576w2ff53p"; + version = "2.14.0"; + edition = "2024"; + sha256 = "1na9z6f0d5pkjr1lgsni470v98gv2r7c41j8w48skr089x2yjrnl"; dependencies = [ { name = "equivalent"; @@ -4306,7 +4329,7 @@ rec { } { name = "hashbrown"; - packageId = "hashbrown"; + packageId = "hashbrown 0.17.1"; usesDefaultFeatures = false; } ]; @@ -4346,55 +4369,24 @@ rec { }; "ipnet" = rec { crateName = "ipnet"; - version = "2.11.0"; + version = "2.12.0"; edition = "2018"; - sha256 = "0c5i9sfi2asai28m8xp48k5gvwkqrg5ffpi767py6mzsrswv17s6"; + sha256 = "1qpq2y0asyv0jppw7zww9y96fpnpinwap8a0phhqqgyy3znnz3yr"; authors = [ "Kris Price " ]; features = { "default" = [ "std" ]; - "heapless" = [ "dep:heapless" ]; - "json" = [ "serde" "schemars" ]; - "schemars" = [ "dep:schemars" ]; - "ser_as_str" = [ "heapless" ]; + "heapless" = [ "dep:heapless" "serde" ]; + "json" = [ "schemars08" "serde" ]; + "schemars" = [ "schemars08" ]; + "schemars08" = [ "dep:schemars08" ]; + "schemars1" = [ "dep:schemars1" ]; + "ser_as_str" = [ "dep:heapless" ]; "serde" = [ "dep:serde" ]; }; resolvedDefaultFeatures = [ "default" "std" ]; }; - "iri-string" = rec { - crateName = "iri-string"; - version = "0.7.10"; - edition = "2021"; - sha256 = "06kk3a5jz576p7vrpf7zz9jv3lrgcyp7pczcblcxdnryg3q3h4y9"; - 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"; @@ -4427,9 +4419,9 @@ rec { }; "itoa" = rec { crateName = "itoa"; - version = "1.0.17"; + version = "1.0.18"; edition = "2021"; - sha256 = "1lh93xydrdn1g9x547bd05g0d3hra7pd1k4jfd2z1pl1h5hwdv4j"; + sha256 = "10jnd1vpfkb8kj38rlkn2a6k02afvj3qmw054dfpzagrpl6achlg"; authors = [ "David Tolnay " ]; @@ -4464,9 +4456,9 @@ rec { }; "jiff" = rec { crateName = "jiff"; - version = "0.2.21"; + version = "0.2.28"; edition = "2021"; - sha256 = "0h3rypc82v4a8wf1s8jvqdryv5khp520ks0nmd3fjslc05gxdqxk"; + sha256 = "00lixngcc7amh2fcsxfr0z38j06lllhapz192biv1qj97q1x60s6"; authors = [ "Andrew Gallant " ]; @@ -4512,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 = [ @@ -4536,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" ]; @@ -4546,9 +4536,9 @@ rec { }; "jiff-static" = rec { crateName = "jiff-static"; - version = "0.2.21"; + version = "0.2.28"; edition = "2021"; - sha256 = "061qz1zyvp8bhvr58r9817hri6s338y8msnb0bg7yg463lhjnz51"; + sha256 = "0irbhfh2f4i9w5l53jcmh6ssnhdd92wfy76978chgwnxilvk4bbq"; procMacro = true; libName = "jiff_static"; authors = [ @@ -4575,9 +4565,9 @@ rec { }; "jiff-tzdb" = rec { crateName = "jiff-tzdb"; - version = "0.1.5"; + version = "0.1.6"; edition = "2021"; - sha256 = "1hm5xn3q092zac6apjy4492ddid473mwa0d64z5f5f95yyzix5v8"; + sha256 = "0xihzlnnyk0xnrzpq4xcyjdcmy8xc3ychzb9ayjkh4vgha2fy069"; libName = "jiff_tzdb"; libPath = "lib.rs"; authors = [ @@ -4628,14 +4618,25 @@ rec { }; "js-sys" = rec { crateName = "js-sys"; - version = "0.3.90"; + version = "0.3.99"; edition = "2021"; - sha256 = "19m5qg024y5xanjrq5c6m1sx69nnzqw7ychnbgnx9xmka1j6zp0l"; + sha256 = "04azrzsz91gr5s3z0ij36lz0kj9ry4lw3jz0mmbiwb251rsc8aql"; libName = "js_sys"; authors = [ "The wasm-bindgen Developers" ]; dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "futures-util"; + packageId = "futures-util"; + optional = true; + usesDefaultFeatures = false; + features = [ "std" ]; + } { name = "once_cell"; packageId = "once_cell"; @@ -4649,15 +4650,16 @@ rec { ]; features = { "default" = [ "std" "unsafe-eval" ]; - "std" = [ "wasm-bindgen/std" ]; + "futures-core-03-stream" = [ "dep:futures-util" "dep:futures-core" ]; + "std" = [ "wasm-bindgen/std" "dep:futures-util" ]; }; 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 " @@ -4683,7 +4685,7 @@ rec { } { name = "thiserror"; - packageId = "thiserror 1.0.69"; + packageId = "thiserror 2.0.18"; } ]; devDependencies = [ @@ -4775,10 +4777,10 @@ rec { }; "k8s-openapi" = rec { crateName = "k8s-openapi"; - version = "0.27.0"; + version = "0.27.1"; edition = "2021"; - links = "k8s-openapi-0.27.0"; - sha256 = "038zxrklpni04rpaww9dr7v8ln8zj8p7mgdd68bx5l8sc7rxd9h5"; + links = "k8s-openapi-0.27.1"; + sha256 = "0pldsxbxd4ckq94p8rkck4s862w33gfns6rclxr5imcx47sjdcsi"; libName = "k8s_openapi"; authors = [ "Arnav Singh " @@ -4848,7 +4850,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } ]; features = { @@ -4857,6 +4859,53 @@ rec { }; resolvedDefaultFeatures = [ "darling" ]; }; + "konst" = rec { + crateName = "konst"; + version = "0.2.20"; + edition = "2018"; + sha256 = "1yyf1fhk28wbf1lqrga9as4cpfmpbry9a5vvdqyxgz14g3nk708j"; + authors = [ + "rodrimati1992 " + ]; + dependencies = [ + { + name = "konst_macro_rules"; + packageId = "konst_macro_rules"; + } + ]; + features = { + "__ui" = [ "__test" "trybuild" "rust_latest_stable" ]; + "const_generics" = [ "rust_1_51" ]; + "constant_time_slice" = [ "rust_latest_stable" ]; + "default" = [ "cmp" "parsing" ]; + "deref_raw_in_fn" = [ "rust_1_56" ]; + "konst_proc_macros" = [ "dep:konst_proc_macros" ]; + "mut_refs" = [ "rust_latest_stable" "konst_macro_rules/mut_refs" ]; + "nightly_mut_refs" = [ "mut_refs" "konst_macro_rules/nightly_mut_refs" ]; + "parsing" = [ "parsing_no_proc" "konst_proc_macros" ]; + "rust_1_51" = [ "konst_macro_rules/rust_1_51" ]; + "rust_1_55" = [ "rust_1_51" "konst_macro_rules/rust_1_55" ]; + "rust_1_56" = [ "rust_1_55" "konst_macro_rules/rust_1_56" ]; + "rust_1_57" = [ "rust_1_56" "konst_macro_rules/rust_1_57" ]; + "rust_1_61" = [ "rust_1_57" "konst_macro_rules/rust_1_61" ]; + "rust_1_64" = [ "rust_1_61" ]; + "rust_latest_stable" = [ "rust_1_64" ]; + "trybuild" = [ "dep:trybuild" ]; + }; + resolvedDefaultFeatures = [ "rust_1_51" "rust_1_55" "rust_1_56" "rust_1_57" "rust_1_61" "rust_1_64" ]; + }; + "konst_macro_rules" = rec { + crateName = "konst_macro_rules"; + version = "0.2.19"; + edition = "2018"; + sha256 = "0dswja0dqcww4x3fwjnirc0azv2n6cazn8yv0kddksd8awzkz4x4"; + authors = [ + "rodrimati1992 " + ]; + features = { + }; + resolvedDefaultFeatures = [ "rust_1_51" "rust_1_55" "rust_1_56" "rust_1_57" "rust_1_61" ]; + }; "kube" = rec { crateName = "kube"; version = "3.1.0"; @@ -5331,7 +5380,7 @@ rec { } { name = "hashbrown"; - packageId = "hashbrown"; + packageId = "hashbrown 0.16.1"; } { name = "hostname"; @@ -5433,9 +5482,9 @@ rec { }; "libc" = rec { crateName = "libc"; - version = "0.2.182"; + version = "0.2.186"; edition = "2021"; - sha256 = "04k1w1mq9f4cxv520dbr5xw1i7xkbc9fcrvaggyjy25jdkdvl038"; + sha256 = "0rnyhzjyqq9x56skkllbjzzzwym3r61lq3l4hqj64v71gw0r3av8"; authors = [ "The Rust Project Developers" ]; @@ -5449,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 = [ @@ -5510,10 +5559,10 @@ rec { }; "libz-sys" = rec { crateName = "libz-sys"; - version = "1.1.24"; + version = "1.1.29"; edition = "2018"; links = "z"; - sha256 = "0f8879301wxgljw8snkcix90p6qbm4inp3sqrsjq9b2svv5yjda7"; + sha256 = "1n98kqya7a7a0cxf5n5z3g13rj7a1vqxynk2xc7bja1qfxbrdg45"; libName = "libz_sys"; authors = [ "Alex Crichton " @@ -5552,9 +5601,9 @@ rec { }; "litemap" = rec { crateName = "litemap"; - version = "0.8.1"; + version = "0.8.2"; edition = "2021"; - sha256 = "0xsy8pfp9s802rsj1bq2ys2kbk1g36w5dr3gkfip7gphb5x60wv3"; + sha256 = "1w7628bc7wwcxc4n4s5kw0610xk06710nh2hn5kwwk2wa91z9nlj"; authors = [ "The ICU4X Project Developers" ]; @@ -5590,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" ]; @@ -5646,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" @@ -5709,9 +5758,9 @@ rec { }; "mio" = rec { crateName = "mio"; - version = "1.1.1"; + version = "1.2.1"; edition = "2021"; - sha256 = "1z2phpalqbdgihrcjp8y09l3kgq6309jnhnr6h11l9s7mnqcm6x6"; + sha256 = "1nkggmrlnjs93w8rja4lvjj4aml1xqahgimv1h0p7d373kvhmg82"; authors = [ "Carl Lerche " "Thomas de Zeeuw " @@ -5721,17 +5770,7 @@ rec { { name = "libc"; packageId = "libc"; - target = { target, features }: ("hermit" == target."os" or null); - } - { - name = "libc"; - packageId = "libc"; - target = { target, features }: ("wasi" == target."os" or null); - } - { - name = "libc"; - packageId = "libc"; - target = { target, features }: (target."unix" or false); + target = { target, features }: ((target."unix" or false) || ("hermit" == target."os" or null) || ("wasi" == target."os" or null)); } { name = "wasi"; @@ -5820,7 +5859,7 @@ rec { } { name = "rand"; - packageId = "rand 0.8.5"; + packageId = "rand 0.8.6"; optional = true; usesDefaultFeatures = false; } @@ -5839,7 +5878,7 @@ rec { devDependencies = [ { name = "rand"; - packageId = "rand 0.8.5"; + packageId = "rand 0.8.6"; features = [ "small_rng" ]; } ]; @@ -5857,9 +5896,9 @@ rec { }; "num-conv" = rec { crateName = "num-conv"; - version = "0.2.0"; + version = "0.2.2"; edition = "2021"; - sha256 = "0l4hj7lp8zbb9am4j3p7vlcv47y9bbazinvnxx9zjhiwkibyr5yg"; + sha256 = "0hg4f9bwmy7cwpxdkm165dmkfc8jhkkayci234jsmi5ssb33j5sj"; libName = "num_conv"; authors = [ "Jacob Pratt " @@ -5953,9 +5992,9 @@ rec { }; "once_cell" = rec { crateName = "once_cell"; - version = "1.21.3"; + version = "1.21.4"; edition = "2021"; - sha256 = "0b9x77lb9f1j6nqgf5aka4s2qj0nly176bpbrv6f9iakk5ff3xa2"; + sha256 = "0l1v676wf71kjg2khch4dphwh1jp3291ffiymr2mvy1kxd5kwz4z"; authors = [ "Aleksey Kladov " ]; @@ -6145,9 +6184,9 @@ rec { }; "opentelemetry-otlp" = rec { crateName = "opentelemetry-otlp"; - version = "0.31.0"; + version = "0.31.1"; edition = "2021"; - sha256 = "1gv3h75z8c0p9b85mbq7f1rgsi18wip1xlfa6g82lkfa5pdnc8vs"; + sha256 = "07zp0b62b9dajnvvcd6j2ppw5zg7wp4ixka9z6fr3bxrrdmcss8z"; libName = "opentelemetry_otlp"; dependencies = [ { @@ -6259,6 +6298,9 @@ rec { "serde_json" = [ "dep:serde_json" ]; "serialize" = [ "serde" "serde_json" ]; "tls" = [ "tonic/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" ]; "tokio" = [ "dep:tokio" ]; @@ -6380,7 +6422,7 @@ rec { } { name = "rand"; - packageId = "rand 0.9.2"; + packageId = "rand 0.9.4"; optional = true; usesDefaultFeatures = false; features = [ "std" "std_rng" "small_rng" "os_rng" "thread_rng" ]; @@ -6804,9 +6846,9 @@ rec { }; "pin-project" = rec { crateName = "pin-project"; - version = "1.1.10"; + version = "1.1.13"; edition = "2021"; - sha256 = "12kadbnfm1f43cyadw9gsbyln1cy7vj764wz5c8wxaiza3filzv7"; + sha256 = "09091qp946lpmjz4yp0xil1r5v4hgc91fi19dg5csayhdqrv4ri4"; libName = "pin_project"; dependencies = [ { @@ -6818,9 +6860,9 @@ rec { }; "pin-project-internal" = rec { crateName = "pin-project-internal"; - version = "1.1.10"; + version = "1.1.13"; edition = "2021"; - sha256 = "0qgqzfl0f4lzaz7yl5llhbg97g68r15kljzihaw9wm64z17qx4bf"; + sha256 = "12rzlh07i1sdgrvzj6wgkka5bjqyvbfsl8knq6qi7g16m7q9aqy9"; procMacro = true; libName = "pin_project_internal"; dependencies = [ @@ -6843,22 +6885,11 @@ rec { }; "pin-project-lite" = rec { crateName = "pin-project-lite"; - version = "0.2.16"; + version = "0.2.17"; edition = "2018"; - sha256 = "16wzc7z7dfkf9bmjin22f5282783f6mdksnr0nv0j5ym5f9gyg1v"; + sha256 = "1kfmwvs271si96zay4mm8887v5khw0c27jc9srw1a75ykvgj54x8"; libName = "pin_project_lite"; - }; - "pin-utils" = rec { - crateName = "pin-utils"; - version = "0.1.0"; - edition = "2018"; - sha256 = "117ir7vslsl2z1a7qzhws4pd01cg2d3338c47swjyvqv2n60v1wb"; - libName = "pin_utils"; - authors = [ - "Josef Brandl " - ]; - }; "pkcs1" = rec { crateName = "pkcs1"; @@ -6930,9 +6961,9 @@ rec { }; "pkg-config" = rec { crateName = "pkg-config"; - version = "0.3.32"; + version = "0.3.33"; edition = "2018"; - sha256 = "0k4h3gnzs94sjb2ix6jyksacs52cf1fanpwsmlhjnwrdnp8dppby"; + sha256 = "17jnqmcbxsnwhg9gjf0nh6dj5k0x3hgwi3mb9krjnmfa9v435w8r"; libName = "pkg_config"; authors = [ "Alex Crichton " @@ -6954,9 +6985,9 @@ rec { }; "portable-atomic-util" = rec { crateName = "portable-atomic-util"; - version = "0.2.5"; + version = "0.2.7"; edition = "2018"; - sha256 = "1xcm0ia8756k6hdgafx4g3lx3fw0hvz2zqswq7c2sy58gxnvk7bs"; + sha256 = "0616j0fhy6y71hyxg3n86f6hng0fmsc269s3wp4gl8ww4p8hd8f2"; libName = "portable_atomic_util"; dependencies = [ { @@ -6967,15 +6998,16 @@ rec { } ]; features = { + "serde" = [ "dep:serde" ]; "std" = [ "alloc" ]; }; resolvedDefaultFeatures = [ "alloc" ]; }; "potential_utf" = rec { crateName = "potential_utf"; - version = "0.1.4"; + version = "0.1.5"; edition = "2021"; - sha256 = "0xxg0pkfpq299wvwln409z4fk80rbv55phh3f1jhjajy5x1ljfdp"; + sha256 = "0r0518fr32xbkgzqap509s3r60cr0iancsg9j1jgf37cyz7b20q1"; authors = [ "The ICU4X Project Developers" ]; @@ -7057,9 +7089,9 @@ rec { }; "proc-macro-crate" = rec { crateName = "proc-macro-crate"; - version = "3.4.0"; + version = "3.5.0"; edition = "2021"; - sha256 = "10v9qi51n4phn1lrj5r94kjq7yhci9jrkqnn6wpan05yjsgb3711"; + sha256 = "0kv1g1d1zjwxlgcaba2qlshzyy32j03xic8rskqlcr5mnblsfyz6"; libName = "proc_macro_crate"; authors = [ "Bastian Köcher " @@ -7219,9 +7251,9 @@ rec { }; "quote" = rec { crateName = "quote"; - version = "1.0.44"; + version = "1.0.45"; edition = "2021"; - sha256 = "1r7c7hxl66vz3q9qizgjhy77pdrrypqgk4ghc7260xvvfb7ypci1"; + sha256 = "095rb5rg7pbnwdp6v8w5jw93wndwyijgci1b5lw8j1h5cscn3wj1"; authors = [ "David Tolnay " ]; @@ -7250,11 +7282,11 @@ rec { "rustc-dep-of-std" = [ "core" ]; }; }; - "rand 0.8.5" = rec { + "rand 0.8.6" = rec { crateName = "rand"; - version = "0.8.5"; + version = "0.8.6"; edition = "2018"; - sha256 = "013l6931nn7gkc23jz5mm3qdhf93jjf0fg64nz2lp4i51qd8vbrl"; + sha256 = "12kd4rljn86m00rcaz4c1rcya4mb4gk5ig6i8xq00a8wjgxfr82w"; authors = [ "The Rand Project Developers" "The Rust Project Developers" @@ -7276,22 +7308,19 @@ rec { "default" = [ "std" "std_rng" ]; "getrandom" = [ "rand_core/getrandom" ]; "libc" = [ "dep:libc" ]; - "log" = [ "dep:log" ]; - "packed_simd" = [ "dep:packed_simd" ]; "rand_chacha" = [ "dep:rand_chacha" ]; "serde" = [ "dep:serde" ]; "serde1" = [ "serde" "rand_core/serde1" ]; - "simd_support" = [ "packed_simd" ]; "std" = [ "rand_core/std" "rand_chacha/std" "alloc" "getrandom" "libc" ]; "std_rng" = [ "rand_chacha" ]; }; resolvedDefaultFeatures = [ "rand_chacha" "std_rng" ]; }; - "rand 0.9.2" = rec { + "rand 0.9.4" = rec { crateName = "rand"; - version = "0.9.2"; + version = "0.9.4"; edition = "2021"; - sha256 = "1lah73ainvrgl7brcxx0pwhpnqa3sm3qaj672034jz8i0q7pgckd"; + sha256 = "1sknbxgs6nfg0nxdd7689lwbyr2i4vaswchrv4b34z8vpc3azia4"; authors = [ "The Rand Project Developers" "The Rust Project Developers" @@ -7311,7 +7340,6 @@ rec { ]; features = { "default" = [ "std" "std_rng" "os_rng" "small_rng" "thread_rng" ]; - "log" = [ "dep:log" ]; "os_rng" = [ "rand_core/os_rng" ]; "serde" = [ "dep:serde" "rand_core/serde" ]; "std" = [ "rand_core/std" "rand_chacha?/std" "alloc" ]; @@ -8186,9 +8214,9 @@ rec { }; "rustls" = rec { crateName = "rustls"; - version = "0.23.37"; + version = "0.23.40"; edition = "2021"; - sha256 = "193k5h0wcih6ghvkrxyzwncivr1bd3a8yw3lzp13pzfcbz5jb03m"; + sha256 = "12qnv3ag4wrw7aj8jng74kgrilpjm2b1rfcjaac8h691frccv1pg"; dependencies = [ { name = "log"; @@ -8255,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 = [ { @@ -8286,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 = [ { @@ -8367,9 +8395,9 @@ rec { }; "schannel" = rec { crateName = "schannel"; - version = "0.1.28"; + version = "0.1.29"; edition = "2018"; - sha256 = "1qb6s5gyxfz2inz753a4z3mc1d266mwvz0c5w7ppd3h44swq27c9"; + sha256 = "0ffrzz5vf2s3gnzvphgb5gg8fqifvryl07qcf7q3x1scj3jbghci"; authors = [ "Steven Fackler " "Steffen Butzer " @@ -8665,9 +8693,9 @@ rec { }; "semver" = rec { crateName = "semver"; - version = "1.0.27"; - edition = "2018"; - sha256 = "1qmi3akfrnqc2hfkdgcxhld5bv961wbk8my3ascv5068mc5fnryp"; + version = "1.0.28"; + edition = "2021"; + sha256 = "1kaimrpy876bcgi8bfj0qqfxk77zm9iz2zhn1hp9hj685z854y4a"; authors = [ "David Tolnay " ]; @@ -8824,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 " @@ -9067,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 " @@ -9137,9 +9165,9 @@ rec { }; "simd-adler32" = rec { crateName = "simd-adler32"; - version = "0.3.8"; + version = "0.3.9"; edition = "2018"; - sha256 = "18lx2gdgislabbvlgw5q3j5ssrr77v8kmkrxaanp3liimp2sc873"; + sha256 = "0532ysdwcvzyp2bwpk8qz0hijplcdwpssr5gy5r7qwqqy5z5qgbh"; libName = "simd_adler32"; authors = [ "Marvin Countryman " @@ -9248,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" ]; }; @@ -9338,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 = [ @@ -9368,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 = { @@ -9376,9 +9400,9 @@ rec { }; "socket2" = rec { crateName = "socket2"; - version = "0.6.2"; + version = "0.6.4"; edition = "2021"; - sha256 = "1q073zkvz96h216mfz6niqk2kjqrgqv2va6zj34qh84zv4xamx46"; + sha256 = "0ldyp5rhba15spwxj1n94xh7sjks1398c3vwpwkxkd1087nwzlaj"; authors = [ "Alex Crichton " "Thomas de Zeeuw " @@ -9387,11 +9411,11 @@ rec { { name = "libc"; packageId = "libc"; - target = { target, features }: (target."unix" or false); + target = { target, features }: ((target."unix" or false) || ("wasi" == target."os" or null)); } { name = "windows-sys"; - packageId = "windows-sys 0.60.2"; + packageId = "windows-sys 0.61.2"; target = { target, features }: (target."windows" or false); features = [ "Win32_Foundation" "Win32_Networking_WinSock" "Win32_System_IO" "Win32_System_Threading" "Win32_System_WindowsProgramming" ]; } @@ -9514,7 +9538,7 @@ rec { } { name = "rand"; - packageId = "rand 0.9.2"; + packageId = "rand 0.9.4"; } { name = "rand_core"; @@ -9536,7 +9560,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-shared"; @@ -9625,7 +9649,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-operator"; @@ -9760,7 +9784,7 @@ rec { } { name = "rand"; - packageId = "rand 0.9.2"; + packageId = "rand 0.9.4"; } { name = "regex"; @@ -9790,7 +9814,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-operator-derive"; @@ -9947,7 +9971,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "strum"; @@ -10035,7 +10059,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "strum"; @@ -10127,7 +10151,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-versioned-macros"; @@ -10271,7 +10295,7 @@ rec { } { name = "rand"; - packageId = "rand 0.9.2"; + packageId = "rand 0.9.4"; } { name = "serde"; @@ -10284,7 +10308,7 @@ rec { } { name = "snafu"; - packageId = "snafu 0.9.0"; + packageId = "snafu 0.9.1"; } { name = "stackable-certs"; @@ -10414,6 +10438,16 @@ rec { }; resolvedDefaultFeatures = [ "i128" ]; }; + "symlink" = rec { + crateName = "symlink"; + version = "0.1.0"; + edition = "2015"; + sha256 = "02h1i0b81mxb4vns4xrvrfibpcvs7jqqav8p3yilwik8cv73r5x7"; + authors = [ + "Chris Morgan " + ]; + + }; "syn 1.0.109" = rec { crateName = "syn"; version = "1.0.109"; @@ -10754,9 +10788,9 @@ rec { }; "tinystr" = rec { crateName = "tinystr"; - version = "0.8.2"; + version = "0.8.3"; edition = "2021"; - sha256 = "0sa8z88axdsf088hgw5p4xcyi6g3w3sgbb6qdp81bph9bk2fkls2"; + sha256 = "0vfr8x285w6zsqhna0a9jyhylwiafb2kc8pj2qaqaahw48236cn8"; authors = [ "The ICU4X Project Developers" ]; @@ -10846,9 +10880,9 @@ rec { }; "tokio" = rec { crateName = "tokio"; - version = "1.49.0"; + version = "1.52.3"; edition = "2021"; - sha256 = "11ix3pl03s0bp71q3wddrbf8xr0cpn47d7fzr6m42r3kswy918kj"; + sha256 = "1zpzazypkg61sw91na1m85x5s4rsjym335fwwhwm1hcs70dz1iwg"; authors = [ "Tokio Contributors " ]; @@ -10864,6 +10898,12 @@ rec { optional = true; target = { target, features }: ((target."tokio_unstable" or false) && ("linux" == target."os" or null)); } + { + name = "libc"; + packageId = "libc"; + optional = true; + target = { target, features }: ("wasi" == target."os" or null); + } { name = "libc"; packageId = "libc"; @@ -10903,7 +10943,7 @@ rec { name = "socket2"; packageId = "socket2"; optional = true; - target = { target, features }: (!(builtins.elem "wasm" target."family")); + target = { target, features }: ((!(builtins.elem "wasm" target."family")) || (("wasi" == target."os" or null) && (!("p1" == target."env" or null)))); features = [ "all" ]; } { @@ -10961,9 +11001,9 @@ rec { }; "tokio-macros" = rec { crateName = "tokio-macros"; - version = "2.6.0"; + version = "2.7.0"; edition = "2021"; - sha256 = "19czvgliginbzyhhfbmj77wazqn2y8g27y2nirfajdlm41bphh5g"; + sha256 = "15m4f37mdafs0gg36sh0rskm1i768lb7zmp8bw67kaxr3avnqniq"; procMacro = true; libName = "tokio_macros"; authors = [ @@ -11131,9 +11171,9 @@ rec { }; "toml_datetime" = rec { crateName = "toml_datetime"; - version = "0.7.5+spec-1.1.0"; - edition = "2021"; - sha256 = "0iqkgvgsxmszpai53dbip7sf2igic39s4dby29dbqf1h9bnwzqcj"; + version = "1.1.1+spec-1.1.0"; + edition = "2024"; + sha256 = "1mws2mkkf46l7inn77azhm0vdwxngv9vsbhbl0ah33p2c9gzcr9i"; dependencies = [ { name = "serde_core"; @@ -11152,9 +11192,9 @@ rec { }; "toml_edit" = rec { crateName = "toml_edit"; - version = "0.23.10+spec-1.0.0"; - edition = "2021"; - sha256 = "0saj5c676j8a3sqaj9akkp09wambg8aflji4zblwwa70azvvkj44"; + version = "0.25.12+spec-1.1.0"; + edition = "2024"; + sha256 = "1mx5paq837rjw7w51zprrjynk1vaig9yzxfqz9ac79jmd7f3w5fj"; dependencies = [ { name = "indexmap"; @@ -11187,9 +11227,9 @@ rec { }; "toml_parser" = rec { crateName = "toml_parser"; - version = "1.0.9+spec-1.1.0"; - edition = "2021"; - sha256 = "1i54qpvvcppy8ybdn9gssas81vfzq0kmgkcnxzhyf8w9w0al8bbh"; + version = "1.1.2+spec-1.1.0"; + edition = "2024"; + sha256 = "09kmzc55a0j21whm290wlf5a8b18a0qc87a1s8sncrckc6wfkax2"; dependencies = [ { name = "winnow"; @@ -11207,9 +11247,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 " ]; @@ -11336,9 +11376,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 " @@ -11480,9 +11520,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 " @@ -11516,11 +11556,6 @@ rec { packageId = "http-body"; optional = true; } - { - name = "iri-string"; - packageId = "iri-string"; - optional = true; - } { name = "mime"; packageId = "mime"; @@ -11550,6 +11585,11 @@ rec { optional = true; usesDefaultFeatures = false; } + { + name = "url"; + packageId = "url"; + optional = true; + } ]; devDependencies = [ { @@ -11571,35 +11611,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" ]; @@ -11608,7 +11646,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"; @@ -11681,9 +11719,9 @@ rec { }; "tracing-appender" = rec { crateName = "tracing-appender"; - version = "0.2.4"; + version = "0.2.5"; edition = "2018"; - sha256 = "1bxf7xvsr89glbq174cx0b9pinaacbhlmc85y1ssniv2rq5lhvbq"; + sha256 = "0g4a6q5s3wafid5lqw1ljzvh1nhk3a4zmb627fxv96dr7qcqc1h5"; libName = "tracing_appender"; authors = [ "Zeki Sherif " @@ -11694,6 +11732,10 @@ rec { name = "crossbeam-channel"; packageId = "crossbeam-channel"; } + { + name = "symlink"; + packageId = "symlink"; + } { name = "thiserror"; packageId = "thiserror 2.0.18"; @@ -11962,9 +12004,9 @@ rec { }; "tracing-subscriber" = rec { crateName = "tracing-subscriber"; - version = "0.3.22"; + version = "0.3.23"; edition = "2018"; - sha256 = "07hz575a0p1c2i4xw3gs3hkrykhndnkbfhyqdwjhvayx4ww18c1g"; + sha256 = "06fkr0qhggvrs861d7f74pn3i3a10h5jsp4n70jj9ys5b675fzyb"; libName = "tracing_subscriber"; authors = [ "Eliza Weisman " @@ -12095,13 +12137,9 @@ rec { }; "typenum" = rec { crateName = "typenum"; - version = "1.19.0"; + version = "1.20.1"; edition = "2018"; - sha256 = "1fw2mpbn2vmqan56j1b3fbpcdg80mz26fm53fs16bq5xcq84hban"; - authors = [ - "Paho Lurie-Gregg " - "Andre Bogus " - ]; + sha256 = "086s9ly0906kw5yw41249fba97w5zfxf03pyfwdkffvcprqfixdn"; features = { "scale-info" = [ "dep:scale-info" ]; "scale_info" = [ "scale-info/derive" ]; @@ -12134,9 +12172,9 @@ rec { }; "unicode-segmentation" = rec { crateName = "unicode-segmentation"; - version = "1.12.0"; + version = "1.13.3"; edition = "2018"; - sha256 = "14qla2jfx74yyb9ds3d2mpwpa4l4lzb9z57c6d2ba511458z5k7n"; + sha256 = "1a47zaq83p386r3baq4m018xd5q4q0grdg56i1x042dzn71x7xf6"; libName = "unicode_segmentation"; authors = [ "kwantam " @@ -12389,9 +12427,9 @@ rec { }; "wasip2" = rec { crateName = "wasip2"; - version = "1.0.2+wasi-0.2.9"; + version = "1.0.3+wasi-0.2.9"; edition = "2021"; - sha256 = "1xdw7v08jpfjdg94sp4lbdgzwa587m5ifpz6fpdnkh02kwizj5wm"; + sha256 = "1mi3w855dz99xzjqc4aa8c9q5b6z1y5c963pkk4cvmr6vdr4c1i0"; dependencies = [ { name = "wit-bindgen"; @@ -12409,9 +12447,9 @@ rec { }; "wasm-bindgen" = rec { crateName = "wasm-bindgen"; - version = "0.2.113"; + version = "0.2.122"; edition = "2021"; - sha256 = "1wpg101a5rqqilv4cz4929kbph9g15y4v2fvkbg7yjsrgy9jlwk0"; + sha256 = "02flix96brsb2r1i3grnikii302iqpdm337kl3xv5lklz5v4bl1y"; libName = "wasm_bindgen"; authors = [ "The wasm-bindgen Developers" @@ -12460,62 +12498,37 @@ rec { }; "wasm-bindgen-futures" = rec { crateName = "wasm-bindgen-futures"; - version = "0.4.63"; + version = "0.4.72"; edition = "2021"; - sha256 = "06j4hyxvlfvas7lhvgai44vh8izd59774wv5m8hla3kp1djz92ca"; + sha256 = "03qb24gfr072rk8hb69glfdc8yhqqqq2rhy3j5i0ps8sk79dnwwl"; libName = "wasm_bindgen_futures"; authors = [ "The wasm-bindgen Developers" ]; dependencies = [ - { - name = "cfg-if"; - packageId = "cfg-if"; - } - { - name = "futures-util"; - packageId = "futures-util"; - optional = true; - usesDefaultFeatures = false; - features = [ "std" ]; - } { name = "js-sys"; packageId = "js-sys"; usesDefaultFeatures = false; } - { - name = "once_cell"; - packageId = "once_cell"; - usesDefaultFeatures = false; - } { name = "wasm-bindgen"; packageId = "wasm-bindgen"; usesDefaultFeatures = false; } - { - name = "web-sys"; - packageId = "web-sys"; - usesDefaultFeatures = false; - target = { target, features }: (builtins.elem "atomics" targetFeatures); - features = [ "MessageEvent" "Worker" ]; - } ]; features = { "default" = [ "std" ]; - "futures-core" = [ "dep:futures-core" ]; - "futures-core-03-stream" = [ "futures-core" ]; - "futures-util" = [ "dep:futures-util" ]; - "std" = [ "wasm-bindgen/std" "js-sys/std" "web-sys/std" "futures-util" ]; + "futures-core-03-stream" = [ "js-sys/futures-core-03-stream" ]; + "std" = [ "wasm-bindgen/std" "js-sys/std" ]; }; - resolvedDefaultFeatures = [ "default" "futures-util" "std" ]; + resolvedDefaultFeatures = [ "default" "std" ]; }; "wasm-bindgen-macro" = rec { crateName = "wasm-bindgen-macro"; - version = "0.2.113"; + version = "0.2.122"; edition = "2021"; - sha256 = "0l1rbylzb1cs5i6ihmkgk8zic71pg563yadgqj8nnjq9jmiqrb0g"; + sha256 = "1inyl55bvdifx7l60q9wl0ivmw7236jg7jqmcqpxhsx3knq52qci"; procMacro = true; libName = "wasm_bindgen_macro"; authors = [ @@ -12537,9 +12550,9 @@ rec { }; "wasm-bindgen-macro-support" = rec { crateName = "wasm-bindgen-macro-support"; - version = "0.2.113"; + version = "0.2.122"; edition = "2021"; - sha256 = "0q4xmjmq1c80drv84hz9i9l7fj3yi0v2d11kh1r21p2rc77angxb"; + sha256 = "0pjw5kc2mbfz59agk5l21kh4hxzp94rygdvsnr4f3z6b5hv4g419"; libName = "wasm_bindgen_macro_support"; authors = [ "The wasm-bindgen Developers" @@ -12573,10 +12586,10 @@ rec { }; "wasm-bindgen-shared" = rec { crateName = "wasm-bindgen-shared"; - version = "0.2.113"; + version = "0.2.122"; edition = "2021"; links = "wasm_bindgen"; - sha256 = "1d9vdqrzksbfv30bvwy4kc57l08di24775hxq1yshkc2vcdhj3ny"; + sha256 = "0ds4mmfqvxwc5fp33hn0jblf0f6b4lghrd9mpkls66zic4n9p4ls"; libName = "wasm_bindgen_shared"; authors = [ "The wasm-bindgen Developers" @@ -12591,9 +12604,9 @@ rec { }; "web-sys" = rec { crateName = "web-sys"; - version = "0.3.90"; + version = "0.3.99"; edition = "2021"; - sha256 = "15wsyn0bmhgf4nkgl23l9fzcqml029jxdlavcbw304lhrsscwpkh"; + sha256 = "0dilfvl9jnyhi4skl6cry9wc300r693j0w82jjbq8yy3rx0i8qkd"; libName = "web_sys"; authors = [ "The wasm-bindgen Developers" @@ -12677,6 +12690,7 @@ rec { "CssStyleSheet" = [ "StyleSheet" ]; "CssSupportsRule" = [ "CssConditionRule" "CssGroupingRule" "CssRule" ]; "CssTransition" = [ "Animation" "EventTarget" ]; + "CssViewTransitionRule" = [ "CssRule" ]; "CustomEvent" = [ "Event" ]; "DedicatedWorkerGlobalScope" = [ "EventTarget" "WorkerGlobalScope" ]; "DelayNode" = [ "AudioNode" "EventTarget" ]; @@ -13083,7 +13097,7 @@ rec { "default" = [ "std" ]; "std" = [ "wasm-bindgen/std" "js-sys/std" ]; }; - resolvedDefaultFeatures = [ "AbortController" "AbortSignal" "Blob" "BlobPropertyBag" "Event" "EventTarget" "File" "FormData" "Headers" "MessageEvent" "ReadableStream" "Request" "RequestCache" "RequestCredentials" "RequestInit" "RequestMode" "Response" "ServiceWorkerGlobalScope" "Window" "Worker" "WorkerGlobalScope" "default" "std" ]; + resolvedDefaultFeatures = [ "AbortController" "AbortSignal" "Blob" "BlobPropertyBag" "EventTarget" "File" "FormData" "Headers" "ReadableStream" "Request" "RequestCache" "RequestCredentials" "RequestInit" "RequestMode" "Response" "ServiceWorkerGlobalScope" "Window" "WorkerGlobalScope" "default" "std" ]; }; "web-time" = rec { crateName = "web-time"; @@ -13257,7 +13271,7 @@ rec { dependencies = [ { name = "windows-targets"; - packageId = "windows-targets 0.52.6"; + packageId = "windows-targets"; } ]; features = { @@ -13493,271 +13507,6 @@ rec { }; resolvedDefaultFeatures = [ "Win32" "Win32_Foundation" "Win32_System" "Win32_System_Threading" "default" ]; }; - "windows-sys 0.60.2" = rec { - crateName = "windows-sys"; - version = "0.60.2"; - edition = "2021"; - sha256 = "1jrbc615ihqnhjhxplr2kw7rasrskv9wj3lr80hgfd42sbj01xgj"; - libName = "windows_sys"; - authors = [ - "Microsoft" - ]; - dependencies = [ - { - name = "windows-targets"; - packageId = "windows-targets 0.53.5"; - usesDefaultFeatures = false; - } - ]; - features = { - "Wdk" = [ "Win32_Foundation" ]; - "Wdk_Devices" = [ "Wdk" ]; - "Wdk_Devices_Bluetooth" = [ "Wdk_Devices" ]; - "Wdk_Devices_HumanInterfaceDevice" = [ "Wdk_Devices" ]; - "Wdk_Foundation" = [ "Wdk" ]; - "Wdk_Graphics" = [ "Wdk" ]; - "Wdk_Graphics_Direct3D" = [ "Wdk_Graphics" ]; - "Wdk_NetworkManagement" = [ "Wdk" ]; - "Wdk_NetworkManagement_Ndis" = [ "Wdk_NetworkManagement" ]; - "Wdk_NetworkManagement_WindowsFilteringPlatform" = [ "Wdk_NetworkManagement" ]; - "Wdk_Storage" = [ "Wdk" ]; - "Wdk_Storage_FileSystem" = [ "Wdk_Storage" ]; - "Wdk_Storage_FileSystem_Minifilters" = [ "Wdk_Storage_FileSystem" ]; - "Wdk_System" = [ "Wdk" ]; - "Wdk_System_IO" = [ "Wdk_System" ]; - "Wdk_System_Memory" = [ "Wdk_System" ]; - "Wdk_System_OfflineRegistry" = [ "Wdk_System" ]; - "Wdk_System_Registry" = [ "Wdk_System" ]; - "Wdk_System_SystemInformation" = [ "Wdk_System" ]; - "Wdk_System_SystemServices" = [ "Wdk_System" ]; - "Wdk_System_Threading" = [ "Wdk_System" ]; - "Win32" = [ "Win32_Foundation" ]; - "Win32_Data" = [ "Win32" ]; - "Win32_Data_HtmlHelp" = [ "Win32_Data" ]; - "Win32_Data_RightsManagement" = [ "Win32_Data" ]; - "Win32_Devices" = [ "Win32" ]; - "Win32_Devices_AllJoyn" = [ "Win32_Devices" ]; - "Win32_Devices_Beep" = [ "Win32_Devices" ]; - "Win32_Devices_BiometricFramework" = [ "Win32_Devices" ]; - "Win32_Devices_Bluetooth" = [ "Win32_Devices" ]; - "Win32_Devices_Cdrom" = [ "Win32_Devices" ]; - "Win32_Devices_Communication" = [ "Win32_Devices" ]; - "Win32_Devices_DeviceAndDriverInstallation" = [ "Win32_Devices" ]; - "Win32_Devices_DeviceQuery" = [ "Win32_Devices" ]; - "Win32_Devices_Display" = [ "Win32_Devices" ]; - "Win32_Devices_Dvd" = [ "Win32_Devices" ]; - "Win32_Devices_Enumeration" = [ "Win32_Devices" ]; - "Win32_Devices_Enumeration_Pnp" = [ "Win32_Devices_Enumeration" ]; - "Win32_Devices_Fax" = [ "Win32_Devices" ]; - "Win32_Devices_HumanInterfaceDevice" = [ "Win32_Devices" ]; - "Win32_Devices_Nfc" = [ "Win32_Devices" ]; - "Win32_Devices_Nfp" = [ "Win32_Devices" ]; - "Win32_Devices_PortableDevices" = [ "Win32_Devices" ]; - "Win32_Devices_Properties" = [ "Win32_Devices" ]; - "Win32_Devices_Pwm" = [ "Win32_Devices" ]; - "Win32_Devices_Sensors" = [ "Win32_Devices" ]; - "Win32_Devices_SerialCommunication" = [ "Win32_Devices" ]; - "Win32_Devices_Tapi" = [ "Win32_Devices" ]; - "Win32_Devices_Usb" = [ "Win32_Devices" ]; - "Win32_Devices_WebServicesOnDevices" = [ "Win32_Devices" ]; - "Win32_Foundation" = [ "Win32" ]; - "Win32_Gaming" = [ "Win32" ]; - "Win32_Globalization" = [ "Win32" ]; - "Win32_Graphics" = [ "Win32" ]; - "Win32_Graphics_Dwm" = [ "Win32_Graphics" ]; - "Win32_Graphics_Gdi" = [ "Win32_Graphics" ]; - "Win32_Graphics_GdiPlus" = [ "Win32_Graphics" ]; - "Win32_Graphics_Hlsl" = [ "Win32_Graphics" ]; - "Win32_Graphics_OpenGL" = [ "Win32_Graphics" ]; - "Win32_Graphics_Printing" = [ "Win32_Graphics" ]; - "Win32_Graphics_Printing_PrintTicket" = [ "Win32_Graphics_Printing" ]; - "Win32_Management" = [ "Win32" ]; - "Win32_Management_MobileDeviceManagementRegistration" = [ "Win32_Management" ]; - "Win32_Media" = [ "Win32" ]; - "Win32_Media_Audio" = [ "Win32_Media" ]; - "Win32_Media_DxMediaObjects" = [ "Win32_Media" ]; - "Win32_Media_KernelStreaming" = [ "Win32_Media" ]; - "Win32_Media_Multimedia" = [ "Win32_Media" ]; - "Win32_Media_Streaming" = [ "Win32_Media" ]; - "Win32_Media_WindowsMediaFormat" = [ "Win32_Media" ]; - "Win32_NetworkManagement" = [ "Win32" ]; - "Win32_NetworkManagement_Dhcp" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_Dns" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_InternetConnectionWizard" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_IpHelper" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_Multicast" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_Ndis" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_NetBios" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_NetManagement" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_NetShell" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_NetworkDiagnosticsFramework" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_P2P" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_QoS" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_Rras" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_Snmp" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_WNet" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_WebDav" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_WiFi" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_WindowsConnectionManager" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_WindowsFilteringPlatform" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_WindowsFirewall" = [ "Win32_NetworkManagement" ]; - "Win32_NetworkManagement_WindowsNetworkVirtualization" = [ "Win32_NetworkManagement" ]; - "Win32_Networking" = [ "Win32" ]; - "Win32_Networking_ActiveDirectory" = [ "Win32_Networking" ]; - "Win32_Networking_Clustering" = [ "Win32_Networking" ]; - "Win32_Networking_HttpServer" = [ "Win32_Networking" ]; - "Win32_Networking_Ldap" = [ "Win32_Networking" ]; - "Win32_Networking_WebSocket" = [ "Win32_Networking" ]; - "Win32_Networking_WinHttp" = [ "Win32_Networking" ]; - "Win32_Networking_WinInet" = [ "Win32_Networking" ]; - "Win32_Networking_WinSock" = [ "Win32_Networking" ]; - "Win32_Networking_WindowsWebServices" = [ "Win32_Networking" ]; - "Win32_Security" = [ "Win32" ]; - "Win32_Security_AppLocker" = [ "Win32_Security" ]; - "Win32_Security_Authentication" = [ "Win32_Security" ]; - "Win32_Security_Authentication_Identity" = [ "Win32_Security_Authentication" ]; - "Win32_Security_Authorization" = [ "Win32_Security" ]; - "Win32_Security_Credentials" = [ "Win32_Security" ]; - "Win32_Security_Cryptography" = [ "Win32_Security" ]; - "Win32_Security_Cryptography_Catalog" = [ "Win32_Security_Cryptography" ]; - "Win32_Security_Cryptography_Certificates" = [ "Win32_Security_Cryptography" ]; - "Win32_Security_Cryptography_Sip" = [ "Win32_Security_Cryptography" ]; - "Win32_Security_Cryptography_UI" = [ "Win32_Security_Cryptography" ]; - "Win32_Security_DiagnosticDataQuery" = [ "Win32_Security" ]; - "Win32_Security_DirectoryServices" = [ "Win32_Security" ]; - "Win32_Security_EnterpriseData" = [ "Win32_Security" ]; - "Win32_Security_ExtensibleAuthenticationProtocol" = [ "Win32_Security" ]; - "Win32_Security_Isolation" = [ "Win32_Security" ]; - "Win32_Security_LicenseProtection" = [ "Win32_Security" ]; - "Win32_Security_NetworkAccessProtection" = [ "Win32_Security" ]; - "Win32_Security_WinTrust" = [ "Win32_Security" ]; - "Win32_Security_WinWlx" = [ "Win32_Security" ]; - "Win32_Storage" = [ "Win32" ]; - "Win32_Storage_Cabinets" = [ "Win32_Storage" ]; - "Win32_Storage_CloudFilters" = [ "Win32_Storage" ]; - "Win32_Storage_Compression" = [ "Win32_Storage" ]; - "Win32_Storage_DistributedFileSystem" = [ "Win32_Storage" ]; - "Win32_Storage_FileHistory" = [ "Win32_Storage" ]; - "Win32_Storage_FileSystem" = [ "Win32_Storage" ]; - "Win32_Storage_Imapi" = [ "Win32_Storage" ]; - "Win32_Storage_IndexServer" = [ "Win32_Storage" ]; - "Win32_Storage_InstallableFileSystems" = [ "Win32_Storage" ]; - "Win32_Storage_IscsiDisc" = [ "Win32_Storage" ]; - "Win32_Storage_Jet" = [ "Win32_Storage" ]; - "Win32_Storage_Nvme" = [ "Win32_Storage" ]; - "Win32_Storage_OfflineFiles" = [ "Win32_Storage" ]; - "Win32_Storage_OperationRecorder" = [ "Win32_Storage" ]; - "Win32_Storage_Packaging" = [ "Win32_Storage" ]; - "Win32_Storage_Packaging_Appx" = [ "Win32_Storage_Packaging" ]; - "Win32_Storage_ProjectedFileSystem" = [ "Win32_Storage" ]; - "Win32_Storage_StructuredStorage" = [ "Win32_Storage" ]; - "Win32_Storage_Vhd" = [ "Win32_Storage" ]; - "Win32_Storage_Xps" = [ "Win32_Storage" ]; - "Win32_System" = [ "Win32" ]; - "Win32_System_AddressBook" = [ "Win32_System" ]; - "Win32_System_Antimalware" = [ "Win32_System" ]; - "Win32_System_ApplicationInstallationAndServicing" = [ "Win32_System" ]; - "Win32_System_ApplicationVerifier" = [ "Win32_System" ]; - "Win32_System_ClrHosting" = [ "Win32_System" ]; - "Win32_System_Com" = [ "Win32_System" ]; - "Win32_System_Com_Marshal" = [ "Win32_System_Com" ]; - "Win32_System_Com_StructuredStorage" = [ "Win32_System_Com" ]; - "Win32_System_Com_Urlmon" = [ "Win32_System_Com" ]; - "Win32_System_ComponentServices" = [ "Win32_System" ]; - "Win32_System_Console" = [ "Win32_System" ]; - "Win32_System_CorrelationVector" = [ "Win32_System" ]; - "Win32_System_DataExchange" = [ "Win32_System" ]; - "Win32_System_DeploymentServices" = [ "Win32_System" ]; - "Win32_System_DeveloperLicensing" = [ "Win32_System" ]; - "Win32_System_Diagnostics" = [ "Win32_System" ]; - "Win32_System_Diagnostics_Ceip" = [ "Win32_System_Diagnostics" ]; - "Win32_System_Diagnostics_Debug" = [ "Win32_System_Diagnostics" ]; - "Win32_System_Diagnostics_Debug_Extensions" = [ "Win32_System_Diagnostics_Debug" ]; - "Win32_System_Diagnostics_Etw" = [ "Win32_System_Diagnostics" ]; - "Win32_System_Diagnostics_ProcessSnapshotting" = [ "Win32_System_Diagnostics" ]; - "Win32_System_Diagnostics_ToolHelp" = [ "Win32_System_Diagnostics" ]; - "Win32_System_Diagnostics_TraceLogging" = [ "Win32_System_Diagnostics" ]; - "Win32_System_DistributedTransactionCoordinator" = [ "Win32_System" ]; - "Win32_System_Environment" = [ "Win32_System" ]; - "Win32_System_ErrorReporting" = [ "Win32_System" ]; - "Win32_System_EventCollector" = [ "Win32_System" ]; - "Win32_System_EventLog" = [ "Win32_System" ]; - "Win32_System_EventNotificationService" = [ "Win32_System" ]; - "Win32_System_GroupPolicy" = [ "Win32_System" ]; - "Win32_System_HostCompute" = [ "Win32_System" ]; - "Win32_System_HostComputeNetwork" = [ "Win32_System" ]; - "Win32_System_HostComputeSystem" = [ "Win32_System" ]; - "Win32_System_Hypervisor" = [ "Win32_System" ]; - "Win32_System_IO" = [ "Win32_System" ]; - "Win32_System_Iis" = [ "Win32_System" ]; - "Win32_System_Ioctl" = [ "Win32_System" ]; - "Win32_System_JobObjects" = [ "Win32_System" ]; - "Win32_System_Js" = [ "Win32_System" ]; - "Win32_System_Kernel" = [ "Win32_System" ]; - "Win32_System_LibraryLoader" = [ "Win32_System" ]; - "Win32_System_Mailslots" = [ "Win32_System" ]; - "Win32_System_Mapi" = [ "Win32_System" ]; - "Win32_System_Memory" = [ "Win32_System" ]; - "Win32_System_Memory_NonVolatile" = [ "Win32_System_Memory" ]; - "Win32_System_MessageQueuing" = [ "Win32_System" ]; - "Win32_System_MixedReality" = [ "Win32_System" ]; - "Win32_System_Ole" = [ "Win32_System" ]; - "Win32_System_PasswordManagement" = [ "Win32_System" ]; - "Win32_System_Performance" = [ "Win32_System" ]; - "Win32_System_Performance_HardwareCounterProfiling" = [ "Win32_System_Performance" ]; - "Win32_System_Pipes" = [ "Win32_System" ]; - "Win32_System_Power" = [ "Win32_System" ]; - "Win32_System_ProcessStatus" = [ "Win32_System" ]; - "Win32_System_Recovery" = [ "Win32_System" ]; - "Win32_System_Registry" = [ "Win32_System" ]; - "Win32_System_RemoteDesktop" = [ "Win32_System" ]; - "Win32_System_RemoteManagement" = [ "Win32_System" ]; - "Win32_System_RestartManager" = [ "Win32_System" ]; - "Win32_System_Restore" = [ "Win32_System" ]; - "Win32_System_Rpc" = [ "Win32_System" ]; - "Win32_System_Search" = [ "Win32_System" ]; - "Win32_System_Search_Common" = [ "Win32_System_Search" ]; - "Win32_System_SecurityCenter" = [ "Win32_System" ]; - "Win32_System_Services" = [ "Win32_System" ]; - "Win32_System_SetupAndMigration" = [ "Win32_System" ]; - "Win32_System_Shutdown" = [ "Win32_System" ]; - "Win32_System_StationsAndDesktops" = [ "Win32_System" ]; - "Win32_System_SubsystemForLinux" = [ "Win32_System" ]; - "Win32_System_SystemInformation" = [ "Win32_System" ]; - "Win32_System_SystemServices" = [ "Win32_System" ]; - "Win32_System_Threading" = [ "Win32_System" ]; - "Win32_System_Time" = [ "Win32_System" ]; - "Win32_System_TpmBaseServices" = [ "Win32_System" ]; - "Win32_System_UserAccessLogging" = [ "Win32_System" ]; - "Win32_System_Variant" = [ "Win32_System" ]; - "Win32_System_VirtualDosMachines" = [ "Win32_System" ]; - "Win32_System_WindowsProgramming" = [ "Win32_System" ]; - "Win32_System_Wmi" = [ "Win32_System" ]; - "Win32_UI" = [ "Win32" ]; - "Win32_UI_Accessibility" = [ "Win32_UI" ]; - "Win32_UI_ColorSystem" = [ "Win32_UI" ]; - "Win32_UI_Controls" = [ "Win32_UI" ]; - "Win32_UI_Controls_Dialogs" = [ "Win32_UI_Controls" ]; - "Win32_UI_HiDpi" = [ "Win32_UI" ]; - "Win32_UI_Input" = [ "Win32_UI" ]; - "Win32_UI_Input_Ime" = [ "Win32_UI_Input" ]; - "Win32_UI_Input_KeyboardAndMouse" = [ "Win32_UI_Input" ]; - "Win32_UI_Input_Pointer" = [ "Win32_UI_Input" ]; - "Win32_UI_Input_Touch" = [ "Win32_UI_Input" ]; - "Win32_UI_Input_XboxController" = [ "Win32_UI_Input" ]; - "Win32_UI_InteractionContext" = [ "Win32_UI" ]; - "Win32_UI_Magnification" = [ "Win32_UI" ]; - "Win32_UI_Shell" = [ "Win32_UI" ]; - "Win32_UI_Shell_Common" = [ "Win32_UI_Shell" ]; - "Win32_UI_Shell_PropertiesSystem" = [ "Win32_UI_Shell" ]; - "Win32_UI_TabletPC" = [ "Win32_UI" ]; - "Win32_UI_TextServices" = [ "Win32_UI" ]; - "Win32_UI_WindowsAndMessaging" = [ "Win32_UI" ]; - "Win32_Web" = [ "Win32" ]; - "Win32_Web_InternetExplorer" = [ "Win32_Web" ]; - }; - resolvedDefaultFeatures = [ "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_System" "Win32_System_IO" "Win32_System_Threading" "Win32_System_WindowsProgramming" "default" ]; - }; "windows-sys 0.61.2" = rec { crateName = "windows-sys"; version = "0.61.2"; @@ -14018,9 +13767,9 @@ 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 0.52.6" = rec { + "windows-targets" = rec { crateName = "windows-targets"; version = "0.52.6"; edition = "2021"; @@ -14032,104 +13781,48 @@ rec { dependencies = [ { name = "windows_aarch64_gnullvm"; - packageId = "windows_aarch64_gnullvm 0.52.6"; - target = { target, features }: (target.name == "aarch64-pc-windows-gnullvm"); - } - { - name = "windows_aarch64_msvc"; - packageId = "windows_aarch64_msvc 0.52.6"; - target = { target, features }: (("aarch64" == target."arch" or null) && ("msvc" == target."env" or null) && (!(target."windows_raw_dylib" or false))); - } - { - name = "windows_i686_gnu"; - packageId = "windows_i686_gnu 0.52.6"; - target = { target, features }: (("x86" == target."arch" or null) && ("gnu" == target."env" or null) && (!("llvm" == target."abi" or null)) && (!(target."windows_raw_dylib" or false))); - } - { - name = "windows_i686_gnullvm"; - packageId = "windows_i686_gnullvm 0.52.6"; - target = { target, features }: (target.name == "i686-pc-windows-gnullvm"); - } - { - name = "windows_i686_msvc"; - packageId = "windows_i686_msvc 0.52.6"; - target = { target, features }: (("x86" == target."arch" or null) && ("msvc" == target."env" or null) && (!(target."windows_raw_dylib" or false))); - } - { - name = "windows_x86_64_gnu"; - packageId = "windows_x86_64_gnu 0.52.6"; - target = { target, features }: (("x86_64" == target."arch" or null) && ("gnu" == target."env" or null) && (!("llvm" == target."abi" or null)) && (!(target."windows_raw_dylib" or false))); - } - { - name = "windows_x86_64_gnullvm"; - packageId = "windows_x86_64_gnullvm 0.52.6"; - target = { target, features }: (target.name == "x86_64-pc-windows-gnullvm"); - } - { - name = "windows_x86_64_msvc"; - packageId = "windows_x86_64_msvc 0.52.6"; - target = { target, features }: ((("x86_64" == target."arch" or null) || ("arm64ec" == target."arch" or null)) && ("msvc" == target."env" or null) && (!(target."windows_raw_dylib" or false))); - } - ]; - - }; - "windows-targets 0.53.5" = rec { - crateName = "windows-targets"; - version = "0.53.5"; - edition = "2021"; - sha256 = "1wv9j2gv3l6wj3gkw5j1kr6ymb5q6dfc42yvydjhv3mqa7szjia9"; - libName = "windows_targets"; - dependencies = [ - { - name = "windows-link"; - packageId = "windows-link"; - usesDefaultFeatures = false; - target = { target, features }: (target."windows_raw_dylib" or false); - } - { - name = "windows_aarch64_gnullvm"; - packageId = "windows_aarch64_gnullvm 0.53.1"; + packageId = "windows_aarch64_gnullvm"; target = { target, features }: (target.name == "aarch64-pc-windows-gnullvm"); } { name = "windows_aarch64_msvc"; - packageId = "windows_aarch64_msvc 0.53.1"; + packageId = "windows_aarch64_msvc"; target = { target, features }: (("aarch64" == target."arch" or null) && ("msvc" == target."env" or null) && (!(target."windows_raw_dylib" or false))); } { name = "windows_i686_gnu"; - packageId = "windows_i686_gnu 0.53.1"; + packageId = "windows_i686_gnu"; target = { target, features }: (("x86" == target."arch" or null) && ("gnu" == target."env" or null) && (!("llvm" == target."abi" or null)) && (!(target."windows_raw_dylib" or false))); } { name = "windows_i686_gnullvm"; - packageId = "windows_i686_gnullvm 0.53.1"; + packageId = "windows_i686_gnullvm"; target = { target, features }: (target.name == "i686-pc-windows-gnullvm"); } { name = "windows_i686_msvc"; - packageId = "windows_i686_msvc 0.53.1"; + packageId = "windows_i686_msvc"; target = { target, features }: (("x86" == target."arch" or null) && ("msvc" == target."env" or null) && (!(target."windows_raw_dylib" or false))); } { name = "windows_x86_64_gnu"; - packageId = "windows_x86_64_gnu 0.53.1"; + packageId = "windows_x86_64_gnu"; target = { target, features }: (("x86_64" == target."arch" or null) && ("gnu" == target."env" or null) && (!("llvm" == target."abi" or null)) && (!(target."windows_raw_dylib" or false))); } { name = "windows_x86_64_gnullvm"; - packageId = "windows_x86_64_gnullvm 0.53.1"; + packageId = "windows_x86_64_gnullvm"; target = { target, features }: (target.name == "x86_64-pc-windows-gnullvm"); } { name = "windows_x86_64_msvc"; - packageId = "windows_x86_64_msvc 0.53.1"; + packageId = "windows_x86_64_msvc"; target = { target, features }: ((("x86_64" == target."arch" or null) || ("arm64ec" == target."arch" or null)) && ("msvc" == target."env" or null) && (!(target."windows_raw_dylib" or false))); } ]; }; - "windows_aarch64_gnullvm 0.52.6" = rec { + "windows_aarch64_gnullvm" = rec { crateName = "windows_aarch64_gnullvm"; version = "0.52.6"; edition = "2021"; @@ -14139,14 +13832,7 @@ rec { ]; }; - "windows_aarch64_gnullvm 0.53.1" = rec { - crateName = "windows_aarch64_gnullvm"; - version = "0.53.1"; - edition = "2021"; - sha256 = "0lqvdm510mka9w26vmga7hbkmrw9glzc90l4gya5qbxlm1pl3n59"; - - }; - "windows_aarch64_msvc 0.52.6" = rec { + "windows_aarch64_msvc" = rec { crateName = "windows_aarch64_msvc"; version = "0.52.6"; edition = "2021"; @@ -14156,14 +13842,7 @@ rec { ]; }; - "windows_aarch64_msvc 0.53.1" = rec { - crateName = "windows_aarch64_msvc"; - version = "0.53.1"; - edition = "2021"; - sha256 = "01jh2adlwx043rji888b22whx4bm8alrk3khjpik5xn20kl85mxr"; - - }; - "windows_i686_gnu 0.52.6" = rec { + "windows_i686_gnu" = rec { crateName = "windows_i686_gnu"; version = "0.52.6"; edition = "2021"; @@ -14173,14 +13852,7 @@ rec { ]; }; - "windows_i686_gnu 0.53.1" = rec { - crateName = "windows_i686_gnu"; - version = "0.53.1"; - edition = "2021"; - sha256 = "18wkcm82ldyg4figcsidzwbg1pqd49jpm98crfz0j7nqd6h6s3ln"; - - }; - "windows_i686_gnullvm 0.52.6" = rec { + "windows_i686_gnullvm" = rec { crateName = "windows_i686_gnullvm"; version = "0.52.6"; edition = "2021"; @@ -14190,14 +13862,7 @@ rec { ]; }; - "windows_i686_gnullvm 0.53.1" = rec { - crateName = "windows_i686_gnullvm"; - version = "0.53.1"; - edition = "2021"; - sha256 = "030qaxqc4salz6l4immfb6sykc6gmhyir9wzn2w8mxj8038mjwzs"; - - }; - "windows_i686_msvc 0.52.6" = rec { + "windows_i686_msvc" = rec { crateName = "windows_i686_msvc"; version = "0.52.6"; edition = "2021"; @@ -14207,14 +13872,7 @@ rec { ]; }; - "windows_i686_msvc 0.53.1" = rec { - crateName = "windows_i686_msvc"; - version = "0.53.1"; - edition = "2021"; - sha256 = "1hi6scw3mn2pbdl30ji5i4y8vvspb9b66l98kkz350pig58wfyhy"; - - }; - "windows_x86_64_gnu 0.52.6" = rec { + "windows_x86_64_gnu" = rec { crateName = "windows_x86_64_gnu"; version = "0.52.6"; edition = "2021"; @@ -14224,14 +13882,7 @@ rec { ]; }; - "windows_x86_64_gnu 0.53.1" = rec { - crateName = "windows_x86_64_gnu"; - version = "0.53.1"; - edition = "2021"; - sha256 = "16d4yiysmfdlsrghndr97y57gh3kljkwhfdbcs05m1jasz6l4f4w"; - - }; - "windows_x86_64_gnullvm 0.52.6" = rec { + "windows_x86_64_gnullvm" = rec { crateName = "windows_x86_64_gnullvm"; version = "0.52.6"; edition = "2021"; @@ -14241,14 +13892,7 @@ rec { ]; }; - "windows_x86_64_gnullvm 0.53.1" = rec { - crateName = "windows_x86_64_gnullvm"; - version = "0.53.1"; - edition = "2021"; - sha256 = "1qbspgv4g3q0vygkg8rnql5c6z3caqv38japiynyivh75ng1gyhg"; - - }; - "windows_x86_64_msvc 0.52.6" = rec { + "windows_x86_64_msvc" = rec { crateName = "windows_x86_64_msvc"; version = "0.52.6"; edition = "2021"; @@ -14257,19 +13901,12 @@ rec { "Microsoft" ]; - }; - "windows_x86_64_msvc 0.53.1" = rec { - crateName = "windows_x86_64_msvc"; - version = "0.53.1"; - edition = "2021"; - sha256 = "0l6npq76vlq4ksn4bwsncpr8508mk0gmznm6wnhjg95d19gzzfyn"; - }; "winnow" = rec { crateName = "winnow"; - version = "0.7.14"; + version = "1.0.3"; edition = "2021"; - sha256 = "0a88ahjqhyn2ln1yplq2xsigm09kxqkdkkk2c2mfxkbzszln8lss"; + sha256 = "1wajycd3krn6h699vydjv7hm0ll5l31p899qzpk59y2is74y34h5"; dependencies = [ { name = "memchr"; @@ -14279,38 +13916,42 @@ rec { } ]; features = { + "ascii" = [ "parser" ]; + "binary" = [ "parser" ]; "debug" = [ "std" "dep:anstream" "dep:anstyle" "dep:is_terminal_polyfill" "dep:terminal_size" ]; - "default" = [ "std" ]; + "default" = [ "std" "ascii" "binary" ]; "simd" = [ "dep:memchr" ]; "std" = [ "alloc" "memchr?/std" ]; - "unstable-doc" = [ "alloc" "std" "simd" "unstable-recover" ]; + "unstable-doc" = [ "alloc" "std" "ascii" "binary" "simd" "unstable-recover" ]; + "unstable-recover" = [ "parser" ]; }; - resolvedDefaultFeatures = [ "alloc" "default" "std" ]; + resolvedDefaultFeatures = [ "alloc" "ascii" "binary" "default" "parser" "std" ]; }; "wit-bindgen" = rec { crateName = "wit-bindgen"; - version = "0.51.0"; + version = "0.57.1"; edition = "2024"; - sha256 = "19fazgch8sq5cvjv3ynhhfh5d5x08jq2pkw8jfb05vbcyqcr496p"; + sha256 = "0vjk2jb593ri9k1aq4iqs2si9mrw5q46wxnn78im7hm7hx799gqy"; libName = "wit_bindgen"; authors = [ "Alex Crichton " ]; features = { - "async" = [ "std" "wit-bindgen-rust-macro?/async" ]; - "async-spawn" = [ "async" "dep:futures" ]; + "async-spawn" = [ "async" "dep:futures" "std" ]; "bitflags" = [ "dep:bitflags" ]; - "default" = [ "macros" "realloc" "async" "std" "bitflags" ]; + "default" = [ "macros" "realloc" "async" "std" "bitflags" "macro-string" ]; + "futures-stream" = [ "async" "dep:futures" ]; "inter-task-wakeup" = [ "async" ]; + "macro-string" = [ "wit-bindgen-rust-macro?/macro-string" ]; "macros" = [ "dep:wit-bindgen-rust-macro" ]; "rustc-dep-of-std" = [ "dep:core" "dep:alloc" ]; }; }; "writeable" = rec { crateName = "writeable"; - version = "0.6.2"; + version = "0.6.3"; edition = "2021"; - sha256 = "1fg08y97n6vk7l0rnjggw3xyrii6dcqg54wqaxldrlk98zdy1pcy"; + sha256 = "1i54d13h9bpap2hf13xcry1s4lxh7ap3923g8f3c0grd7c9fbyhz"; authors = [ "The ICU4X Project Developers" ]; @@ -14388,9 +14029,9 @@ rec { }; "yoke" = rec { crateName = "yoke"; - version = "0.8.1"; + version = "0.8.2"; edition = "2021"; - sha256 = "0m29dm0bf5iakxgma0bj6dbmc3b8qi9b1vaw9sa76kdqmz3fbmkj"; + sha256 = "1jprcs7a98a5whvfs6r3jvfh1nnfp6zyijl7y4ywmn88lzywbs5b"; authors = [ "Manish Goregaokar " ]; @@ -14423,9 +14064,9 @@ rec { }; "yoke-derive" = rec { crateName = "yoke-derive"; - version = "0.8.1"; + version = "0.8.2"; edition = "2021"; - sha256 = "0pbyja133jnng4mrhimzdq4a0y26421g734ybgz8wsgbfhl0andn"; + sha256 = "13l5y5sz4lqm7rmyakjbh6vwgikxiql51xfff9hq2j485hk4r16y"; procMacro = true; libName = "yoke_derive"; authors = [ @@ -14454,9 +14095,9 @@ rec { }; "zerocopy" = rec { crateName = "zerocopy"; - version = "0.8.40"; + version = "0.8.50"; edition = "2021"; - sha256 = "1r9j2mlb54q1l9pgall3mk0gg6cprhdncvbbgsgxnxmmj3jcd2d7"; + sha256 = "1laahnfxs4qyfb1fdf5nbb2qfshi72b1hbi0ffp2zy2m1r7ms1iv"; authors = [ "Joshua Liebow-Feeser " "Jack Wrenn " @@ -14490,9 +14131,9 @@ rec { }; "zerocopy-derive" = rec { crateName = "zerocopy-derive"; - version = "0.8.40"; + version = "0.8.50"; edition = "2021"; - sha256 = "0lsrhg5nvf0c40z644a014l2nrvh7xw0ff3i9744k9vif2d4hp7n"; + sha256 = "0fdnr9qslx1hbn2i9rsvy9s95mychfy2vj90ajsjm2basccinqqb"; procMacro = true; libName = "zerocopy_derive"; authors = [ @@ -14525,11 +14166,11 @@ rec { }; "zerofrom" = rec { crateName = "zerofrom"; - version = "0.1.6"; + version = "0.1.8"; edition = "2021"; - sha256 = "19dyky67zkjichsb7ykhv0aqws3q0jfvzww76l66c19y6gh45k2h"; + sha256 = "0wjjdj7gdmd0iq91gzkxl7dlv0nhkk80l4bmdpzh3a1yh48mmh0f"; authors = [ - "Manish Goregaokar " + "The ICU4X Project Developers" ]; dependencies = [ { @@ -14547,9 +14188,9 @@ rec { }; "zerofrom-derive" = rec { crateName = "zerofrom-derive"; - version = "0.1.6"; + version = "0.1.7"; edition = "2021"; - sha256 = "00l5niw7c1b0lf1vhvajpjmcnbdp2vn96jg4nmkhq2db0rp5s7np"; + sha256 = "18c4wsnznhdxx6m80piil1lbyszdiwsshgjrybqcm4b6qic22lqi"; procMacro = true; libName = "zerofrom_derive"; authors = [ @@ -14628,9 +14269,9 @@ rec { }; "zerotrie" = rec { crateName = "zerotrie"; - version = "0.2.3"; + version = "0.2.4"; edition = "2021"; - sha256 = "0lbqznlqazmrwwzslw0ci7p3pqxykrbfhq29npj0gmb2amxc2n9a"; + sha256 = "1gr0pkcn3qsr6in6iixqyp0vbzwf2j1jzyvh7yl2yydh3p9m548g"; authors = [ "The ICU4X Project Developers" ]; @@ -14655,7 +14296,9 @@ rec { } ]; features = { + "alloc" = [ "zerovec?/alloc" ]; "databake" = [ "dep:databake" "zerovec?/databake" ]; + "dense" = [ "dep:zerovec" ]; "litemap" = [ "dep:litemap" "alloc" ]; "serde" = [ "dep:serde_core" "dep:litemap" "alloc" "litemap/serde" "zerovec?/serde" ]; "yoke" = [ "dep:yoke" ]; @@ -14666,9 +14309,9 @@ rec { }; "zerovec" = rec { crateName = "zerovec"; - version = "0.11.5"; + version = "0.11.6"; edition = "2021"; - sha256 = "00m0p47k2g9mkv505hky5xh3r6ps7v8qc0dy4pspg542jj972a3c"; + sha256 = "0fdjsy6b31q9i0d73sl7xjd12xadbwi45lkpfgqnmasrqg5i3ych"; authors = [ "The ICU4X Project Developers" ]; @@ -14691,11 +14334,20 @@ rec { usesDefaultFeatures = false; } ]; + devDependencies = [ + { + name = "yoke"; + packageId = "yoke"; + usesDefaultFeatures = false; + features = [ "derive" ]; + } + ]; features = { "alloc" = [ "serde?/alloc" ]; "databake" = [ "dep:databake" ]; "derive" = [ "dep:zerovec-derive" ]; "hashmap" = [ "dep:twox-hash" "alloc" ]; + "schemars" = [ "dep:schemars" "alloc" ]; "serde" = [ "dep:serde" ]; "yoke" = [ "dep:yoke" ]; }; @@ -14703,9 +14355,9 @@ rec { }; "zerovec-derive" = rec { crateName = "zerovec-derive"; - version = "0.11.2"; + version = "0.11.3"; edition = "2021"; - sha256 = "1wsig4h5j7a1scd5hrlnragnazjny9qjc44hancb6p6a76ay7p7a"; + sha256 = "0m85qj92mmfvhjra6ziqky5b1p4kcmp5069k7kfadp5hr8jw8pb2"; procMacro = true; libName = "zerovec_derive"; authors = [ diff --git a/Cargo.toml b/Cargo.toml index 94904783..50909c51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,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" futures = { version = "0.3", features = ["compat"] } indoc = "2.0" @@ -26,7 +26,7 @@ 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" tracing-futures = { version = "0.2", features = ["futures-03"] } xml = "1.3" diff --git a/extra/crds.yaml b/extra/crds.yaml index 4a41458a..247708f2 100644 --- a/extra/crds.yaml +++ b/extra/crds.yaml @@ -606,63 +606,69 @@ spec: properties: core-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 hadoop-policy.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 hdfs-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 ssl-client.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 ssl-server.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 type: object envOverrides: @@ -1193,63 +1199,69 @@ spec: properties: core-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 hadoop-policy.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 hdfs-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 ssl-client.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 ssl-server.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 type: object envOverrides: @@ -1726,63 +1738,69 @@ spec: properties: core-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 hadoop-policy.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 hdfs-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 ssl-client.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 ssl-server.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 type: object envOverrides: @@ -2216,63 +2234,69 @@ spec: properties: core-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 hadoop-policy.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 hdfs-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 ssl-client.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 ssl-server.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 type: object envOverrides: @@ -2932,63 +2956,69 @@ spec: properties: core-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 hadoop-policy.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 hdfs-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 ssl-client.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 ssl-server.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 type: object envOverrides: @@ -3668,63 +3698,69 @@ spec: properties: core-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 hadoop-policy.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 hdfs-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 ssl-client.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 ssl-server.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 type: object envOverrides: diff --git a/rust/operator-binary/src/config/mod.rs b/rust/operator-binary/src/config/mod.rs index b48898ad..ba5f734a 100644 --- a/rust/operator-binary/src/config/mod.rs +++ b/rust/operator-binary/src/config/mod.rs @@ -2,22 +2,23 @@ use std::collections::BTreeMap; use stackable_operator::utils::cluster_info::KubernetesClusterInfo; -use crate::config::writer::to_hadoop_xml; - -use crate::crd::{ - HdfsPodRef, - constants::{ - DEFAULT_JOURNAL_NODE_RPC_PORT, DEFAULT_NAME_NODE_HTTP_PORT, DEFAULT_NAME_NODE_HTTPS_PORT, - DEFAULT_NAME_NODE_RPC_PORT, DFS_DATANODE_DATA_DIR, DFS_HA_NAMENODES, - DFS_JOURNALNODE_EDITS_DIR, DFS_JOURNALNODE_RPC_ADDRESS, DFS_NAME_SERVICES, - DFS_NAMENODE_HTTP_ADDRESS, DFS_NAMENODE_HTTPS_ADDRESS, DFS_NAMENODE_NAME_DIR, - DFS_NAMENODE_RPC_ADDRESS, DFS_NAMENODE_SHARED_EDITS_DIR, DFS_REPLICATION, FS_DEFAULT_FS, - HA_ZOOKEEPER_QUORUM, JOURNALNODE_ROOT_DATA_DIR, NAMENODE_ROOT_DATA_DIR, - PROMETHEUS_ENDPOINT_ENABLED, SERVICE_PORT_NAME_HTTP, SERVICE_PORT_NAME_HTTPS, - SERVICE_PORT_NAME_RPC, +use crate::{ + config::writer::to_hadoop_xml, + crd::{ + HdfsPodRef, + constants::{ + DEFAULT_JOURNAL_NODE_RPC_PORT, DEFAULT_NAME_NODE_HTTP_PORT, + DEFAULT_NAME_NODE_HTTPS_PORT, DEFAULT_NAME_NODE_RPC_PORT, DFS_DATANODE_DATA_DIR, + DFS_HA_NAMENODES, DFS_JOURNALNODE_EDITS_DIR, DFS_JOURNALNODE_RPC_ADDRESS, + DFS_NAME_SERVICES, DFS_NAMENODE_HTTP_ADDRESS, DFS_NAMENODE_HTTPS_ADDRESS, + DFS_NAMENODE_NAME_DIR, DFS_NAMENODE_RPC_ADDRESS, DFS_NAMENODE_SHARED_EDITS_DIR, + DFS_REPLICATION, FS_DEFAULT_FS, HA_ZOOKEEPER_QUORUM, JOURNALNODE_ROOT_DATA_DIR, + NAMENODE_ROOT_DATA_DIR, PROMETHEUS_ENDPOINT_ENABLED, SERVICE_PORT_NAME_HTTP, + SERVICE_PORT_NAME_HTTPS, SERVICE_PORT_NAME_RPC, + }, + storage::{DataNodeStorageConfig, DataNodeStorageConfigInnerType}, + v1alpha1, }, - storage::{DataNodeStorageConfig, DataNodeStorageConfigInnerType}, - v1alpha1, }; pub mod jvm; @@ -275,9 +276,7 @@ impl CoreSiteConfigBuilder { } } -fn to_optional_values( - config: &BTreeMap, -) -> BTreeMap> { +fn to_optional_values(config: &BTreeMap) -> BTreeMap> { config .iter() .map(|(k, v)| (k.clone(), Some(v.clone()))) diff --git a/rust/operator-binary/src/config/writer.rs b/rust/operator-binary/src/config/writer.rs index 20c1e1b6..cc161306 100644 --- a/rust/operator-binary/src/config/writer.rs +++ b/rust/operator-binary/src/config/writer.rs @@ -121,7 +121,10 @@ mod tests { #[test] fn hadoop_xml_escapes_special_characters() { let rendered = xml(&[("k", Some("&b"))]); - assert!(rendered.contains("<a>&b"), "{rendered}"); + assert!( + rendered.contains("<a>&b"), + "{rendered}" + ); } #[test] diff --git a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs index aff683da..6adb7d11 100644 --- a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs +++ b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs @@ -147,9 +147,7 @@ mod tests { "{xml}" ); assert!( - xml.contains( - "dfs.datanode.max.transfer.threads\n 8192" - ), + xml.contains("dfs.datanode.max.transfer.threads\n 8192"), "{xml}" ); } diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index a7f6bc83..d7ed2d2b 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -56,7 +56,10 @@ mod tests { fn file_names_match_the_hadoop_on_disk_names() { assert_eq!(ConfigFileName::HdfsSite.to_string(), "hdfs-site.xml"); assert_eq!(ConfigFileName::CoreSite.to_string(), "core-site.xml"); - assert_eq!(ConfigFileName::HadoopPolicy.to_string(), "hadoop-policy.xml"); + assert_eq!( + ConfigFileName::HadoopPolicy.to_string(), + "hadoop-policy.xml" + ); assert_eq!(ConfigFileName::SslServer.to_string(), "ssl-server.xml"); assert_eq!(ConfigFileName::SslClient.to_string(), "ssl-client.xml"); assert_eq!(ConfigFileName::Security.to_string(), "security.properties"); diff --git a/rust/operator-binary/src/controller/build/properties/ssl_client.rs b/rust/operator-binary/src/controller/build/properties/ssl_client.rs index 25cab995..5a94b46e 100644 --- a/rust/operator-binary/src/controller/build/properties/ssl_client.rs +++ b/rust/operator-binary/src/controller/build/properties/ssl_client.rs @@ -69,7 +69,10 @@ mod tests { #[test] fn user_overrides_win_over_injected_defaults() { - let xml = build(true, config_overrides(&[("ssl.client.truststore.type", "jks")])); + let xml = build( + true, + config_overrides(&[("ssl.client.truststore.type", "jks")]), + ); assert!( xml.contains("ssl.client.truststore.type\n jks"), "{xml}" diff --git a/rust/operator-binary/src/controller/build/properties/ssl_server.rs b/rust/operator-binary/src/controller/build/properties/ssl_server.rs index ea80dcff..1a18623a 100644 --- a/rust/operator-binary/src/controller/build/properties/ssl_server.rs +++ b/rust/operator-binary/src/controller/build/properties/ssl_server.rs @@ -81,7 +81,10 @@ mod tests { #[test] fn user_overrides_win_over_injected_defaults() { - let xml = build(true, config_overrides(&[("ssl.server.keystore.type", "jks")])); + let xml = build( + true, + config_overrides(&[("ssl.server.keystore.type", "jks")]), + ); assert!( xml.contains("ssl.server.keystore.type\n jks"), "{xml}" diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 862188cb..505d1917 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -108,7 +108,11 @@ pub fn validate_cluster( /// product-config `transform_all_roles_to_config` step. fn collect_role_group_overrides( role: Option<&Role>, -) -> Vec<(String, v1alpha1::HdfsConfigOverrides, BTreeMap)> { +) -> Vec<( + String, + v1alpha1::HdfsConfigOverrides, + BTreeMap, +)> { let Some(role) = role else { return Vec::new(); }; diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index f568e9d2..71bf15a7 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -569,7 +569,6 @@ impl v1alpha1::HdfsCluster { } } - pub fn upgrade_state(&self) -> Result, UpgradeStateError> { use upgrade_state_error::*; let Some(status) = self.status.as_ref() else { diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index e285d29f..c785286f 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -45,11 +45,11 @@ use strum::{EnumDiscriminants, IntoEnumIterator, IntoStaticStr}; use crate::{ OPERATOR_NAME, build_recommended_labels, config::writer::PropertiesWriterError, + container::{self, ContainerConfig}, controller::build::properties::{ ConfigFileName, core_site, hadoop_policy, hdfs_site, security_properties, ssl_client, ssl_server, }, - container::{self, ContainerConfig}, crd::{ AnyNodeConfig, HdfsClusterStatus, HdfsNodeRole, HdfsPodRef, UpgradeState, UpgradeStateError, constants::*, v1alpha1, @@ -611,10 +611,14 @@ fn rolegroup_config_map( ) .context(BuildCoreSiteXmlSnafu)?; let hadoop_policy_xml = hadoop_policy::build(config_overrides.hadoop_policy_xml.clone()); - let ssl_server_xml = - ssl_server::build(hdfs.has_https_enabled(), config_overrides.ssl_server_xml.clone()); - let ssl_client_xml = - ssl_client::build(hdfs.has_https_enabled(), config_overrides.ssl_client_xml.clone()); + let ssl_server_xml = ssl_server::build( + hdfs.has_https_enabled(), + config_overrides.ssl_server_xml.clone(), + ); + let ssl_client_xml = ssl_client::build( + hdfs.has_https_enabled(), + config_overrides.ssl_client_xml.clone(), + ); let mut builder = ConfigMapBuilder::new(); builder From 12bc737ca7e2fd6dd012068b8377f4fa566550ec Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 21:01:31 +0200 Subject: [PATCH 10/18] refactor: extract ConfigMap building into controller/build/config_map Moves rolegroup_config_map out of hdfs_controller into controller/build/config_map::build_rolegroup_config_map with its own Error enum, mirroring trino-operator. The function now takes the ValidatedCluster and looks up the role group's merged config and overrides internally instead of receiving them pre-destructured. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/controller/build/config_map.rs | 159 ++++++++++++++++++ .../src/controller/build/mod.rs | 1 + rust/operator-binary/src/hdfs_controller.rs | 141 +--------------- 3 files changed, 169 insertions(+), 132 deletions(-) create mode 100644 rust/operator-binary/src/controller/build/config_map.rs 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..4af45c59 --- /dev/null +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -0,0 +1,159 @@ +//! Build the per-rolegroup `ConfigMap` for the HdfsCluster. + +use std::str::FromStr; + +use snafu::{OptionExt, ResultExt, Snafu}; +use stackable_operator::{ + builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, + k8s_openapi::api::core::v1::ConfigMap, + kube::runtime::reflector::ObjectRef, + role_utils::RoleGroupRef, + utils::cluster_info::KubernetesClusterInfo, +}; + +use crate::{ + config::writer::PropertiesWriterError, + controller::build::properties::{ + ConfigFileName, core_site, hadoop_policy, hdfs_site, security_properties, ssl_client, + ssl_server, + }, + crd::{HdfsNodeRole, HdfsPodRef, v1alpha1}, + hdfs_controller::ValidatedCluster, + product_logging::extend_role_group_config_map, +}; + +#[derive(Snafu, Debug)] +pub enum Error { + #[snafu(display("object has no name"))] + ObjectHasNoName { + obj_ref: ObjectRef, + }, + + #[snafu(display("could not parse HDFS role [{role}]"))] + UnidentifiedHdfsRole { + source: strum::ParseError, + role: String, + }, + + #[snafu(display("the validated cluster has no role group {role_group:?} for role {role:?}"))] + MissingRoleGroup { role: String, role_group: String }, + + #[snafu(display("failed to build core-site.xml"))] + BuildCoreSiteXml { source: core_site::Error }, + + #[snafu(display("failed to serialize {} for {rolegroup}", ConfigFileName::Security))] + JvmSecurityProperties { + source: PropertiesWriterError, + rolegroup: String, + }, + + #[snafu(display("failed to add the logging configuration to the ConfigMap {cm_name:?}"))] + InvalidLoggingConfig { + source: crate::product_logging::Error, + cm_name: String, + }, + + #[snafu(display("cannot build config map for role {role:?} and role group {role_group:?}"))] + Assemble { + source: stackable_operator::builder::configmap::Error, + role: String, + role_group: String, + }, +} + +type Result = std::result::Result; + +#[allow(clippy::too_many_arguments)] +pub fn build_rolegroup_config_map( + cluster: &ValidatedCluster, + hdfs: &v1alpha1::HdfsCluster, + cluster_info: &KubernetesClusterInfo, + metadata: &ObjectMetaBuilder, + rolegroup_ref: &RoleGroupRef, + namenode_podrefs: &[HdfsPodRef], + journalnode_podrefs: &[HdfsPodRef], +) -> Result { + tracing::info!("Setting up ConfigMap for {:?}", rolegroup_ref); + + let role = HdfsNodeRole::from_str(&rolegroup_ref.role).with_context(|_| { + UnidentifiedHdfsRoleSnafu { + role: rolegroup_ref.role.clone(), + } + })?; + let rolegroup_config = cluster + .role_groups + .get(&role) + .and_then(|role_groups| role_groups.get(&rolegroup_ref.role_group)) + .with_context(|| MissingRoleGroupSnafu { + role: rolegroup_ref.role.clone(), + role_group: rolegroup_ref.role_group.clone(), + })?; + let merged_config = &rolegroup_config.merged_config; + let config_overrides = &rolegroup_config.config_overrides; + let hdfs_opa_config = cluster.hdfs_opa_config.as_ref(); + + let hdfs_name = hdfs + .metadata + .name + .as_deref() + .with_context(|| ObjectHasNoNameSnafu { + obj_ref: ObjectRef::from_obj(hdfs), + })?; + + let hdfs_site_xml = hdfs_site::build( + hdfs, + hdfs_name, + cluster_info, + merged_config, + namenode_podrefs, + journalnode_podrefs, + hdfs_opa_config, + config_overrides.hdfs_site_xml.clone(), + ); + let core_site_xml = core_site::build( + hdfs, + hdfs_name, + role, + cluster_info, + hdfs_opa_config, + config_overrides.core_site_xml.clone(), + ) + .context(BuildCoreSiteXmlSnafu)?; + let hadoop_policy_xml = hadoop_policy::build(config_overrides.hadoop_policy_xml.clone()); + let ssl_server_xml = ssl_server::build( + hdfs.has_https_enabled(), + config_overrides.ssl_server_xml.clone(), + ); + let ssl_client_xml = ssl_client::build( + hdfs.has_https_enabled(), + config_overrides.ssl_client_xml.clone(), + ); + + let mut builder = ConfigMapBuilder::new(); + builder + .metadata(metadata.build()) + .add_data(ConfigFileName::CoreSite.to_string(), core_site_xml) + .add_data(ConfigFileName::HdfsSite.to_string(), hdfs_site_xml) + .add_data(ConfigFileName::HadoopPolicy.to_string(), hadoop_policy_xml) + .add_data(ConfigFileName::SslServer.to_string(), ssl_server_xml) + .add_data(ConfigFileName::SslClient.to_string(), ssl_client_xml) + .add_data( + ConfigFileName::Security.to_string(), + security_properties::build(config_overrides.security_properties.clone()).with_context( + |_| JvmSecurityPropertiesSnafu { + rolegroup: rolegroup_ref.role_group.clone(), + }, + )?, + ); + + extend_role_group_config_map(rolegroup_ref, merged_config, &mut builder).context( + InvalidLoggingConfigSnafu { + cm_name: rolegroup_ref.object_name(), + }, + )?; + + builder.build().with_context(|_| AssembleSnafu { + role: rolegroup_ref.role.clone(), + role_group: rolegroup_ref.role_group.clone(), + }) +} diff --git a/rust/operator-binary/src/controller/build/mod.rs b/rust/operator-binary/src/controller/build/mod.rs index 09d2bb68..933a20b9 100644 --- a/rust/operator-binary/src/controller/build/mod.rs +++ b/rust/operator-binary/src/controller/build/mod.rs @@ -1 +1,2 @@ +pub mod config_map; pub mod properties; diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index c785286f..03c3e551 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -1,10 +1,9 @@ -use std::{collections::BTreeMap, str::FromStr, sync::Arc}; +use std::{collections::BTreeMap, sync::Arc}; use const_format::concatcp; -use snafu::{OptionExt, ResultExt, Snafu}; +use snafu::{ResultExt, Snafu}; use stackable_operator::{ builder::{ - configmap::ConfigMapBuilder, meta::ObjectMetaBuilder, pod::{PodBuilder, security::PodSecurityContextBuilder}, }, @@ -17,7 +16,7 @@ use stackable_operator::{ DeepMerge, api::{ apps::v1::{StatefulSet, StatefulSetSpec}, - core::v1::{ConfigMap, ServiceAccount}, + core::v1::ServiceAccount, }, apimachinery::pkg::apis::meta::v1::LabelSelector, }, @@ -44,12 +43,7 @@ use strum::{EnumDiscriminants, IntoEnumIterator, IntoStaticStr}; use crate::{ OPERATOR_NAME, build_recommended_labels, - config::writer::PropertiesWriterError, container::{self, ContainerConfig}, - controller::build::properties::{ - ConfigFileName, core_site, hadoop_policy, hdfs_site, security_properties, ssl_client, - ssl_server, - }, crd::{ AnyNodeConfig, HdfsClusterStatus, HdfsNodeRole, HdfsPodRef, UpgradeState, UpgradeStateError, constants::*, v1alpha1, @@ -60,7 +54,6 @@ use crate::{ graceful_shutdown::{self, add_graceful_shutdown_config}, pdb::add_pdbs, }, - product_logging::extend_role_group_config_map, security::opa::HdfsOpaConfig, service::{self, rolegroup_headless_service, rolegroup_metrics_service}, }; @@ -144,16 +137,9 @@ pub enum Error { obj_ref: ObjectRef, }, - #[snafu(display("object has no name"))] - ObjectHasNoName { - obj_ref: ObjectRef, - }, - - #[snafu(display("cannot build config map for role {role:?} and role group {role_group:?}"))] + #[snafu(display("failed to build the role group ConfigMap"))] BuildRoleGroupConfigMap { - source: stackable_operator::builder::configmap::Error, - role: String, - role_group: String, + source: crate::controller::build::config_map::Error, }, #[snafu(display("cannot collect discovery configuration"))] @@ -185,12 +171,6 @@ pub enum Error { #[snafu(display("failed to create pod references"))] CreatePodReferences { source: crate::crd::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 create cluster event"))] FailedToCreateClusterEvent { source: crate::event::Error }, @@ -212,18 +192,6 @@ pub enum Error { source: stackable_operator::commons::rbac::Error, }, - #[snafu(display("failed to serialize {} for {rolegroup}", ConfigFileName::Security))] - JvmSecurityProperties { - source: PropertiesWriterError, - rolegroup: String, - }, - - #[snafu(display("could not parse HDFS role [{role}]"))] - UnidentifiedHdfsRole { - source: strum::ParseError, - role: String, - }, - #[snafu(display("failed to configure graceful shutdown"))] GracefulShutdown { source: graceful_shutdown::Error }, @@ -241,9 +209,6 @@ pub enum Error { source: stackable_operator::builder::meta::Error, }, - #[snafu(display("failed to build core-site.xml"))] - BuildCoreSiteXml { source: core_site::Error }, - #[snafu(display("HdfsCluster object is invalid"))] InvalidHdfsCluster { source: error_boundary::InvalidObject, @@ -402,17 +367,16 @@ pub async fn reconcile_hdfs( )) .context(ObjectMetaSnafu)?; - let rg_configmap = rolegroup_config_map( + let rg_configmap = crate::controller::build::config_map::build_rolegroup_config_map( + &validated, hdfs, &client.kubernetes_cluster_info, metadata, &rolegroup_ref, - &validated_rg_config.config_overrides, &namenode_podrefs, &journalnode_podrefs, - merged_config, - &validated.hdfs_opa_config, - )?; + ) + .context(BuildRoleGroupConfigMapSnafu)?; let rg_statefulset = rolegroup_statefulset( hdfs, @@ -564,93 +528,6 @@ pub async fn reconcile_hdfs( Ok(Action::await_change()) } -#[allow(clippy::too_many_arguments)] -fn rolegroup_config_map( - hdfs: &v1alpha1::HdfsCluster, - cluster_info: &KubernetesClusterInfo, - metadata: &ObjectMetaBuilder, - rolegroup_ref: &RoleGroupRef, - config_overrides: &v1alpha1::HdfsConfigOverrides, - namenode_podrefs: &[HdfsPodRef], - journalnode_podrefs: &[HdfsPodRef], - merged_config: &AnyNodeConfig, - hdfs_opa_config: &Option, -) -> HdfsOperatorResult { - tracing::info!("Setting up ConfigMap for {:?}", rolegroup_ref); - - let role = HdfsNodeRole::from_str(&rolegroup_ref.role).with_context(|_| { - UnidentifiedHdfsRoleSnafu { - role: rolegroup_ref.role.clone(), - } - })?; - let hdfs_name = hdfs - .metadata - .name - .as_deref() - .with_context(|| ObjectHasNoNameSnafu { - obj_ref: ObjectRef::from_obj(hdfs), - })?; - - let hdfs_site_xml = hdfs_site::build( - hdfs, - hdfs_name, - cluster_info, - merged_config, - namenode_podrefs, - journalnode_podrefs, - hdfs_opa_config.as_ref(), - config_overrides.hdfs_site_xml.clone(), - ); - let core_site_xml = core_site::build( - hdfs, - hdfs_name, - role, - cluster_info, - hdfs_opa_config.as_ref(), - config_overrides.core_site_xml.clone(), - ) - .context(BuildCoreSiteXmlSnafu)?; - let hadoop_policy_xml = hadoop_policy::build(config_overrides.hadoop_policy_xml.clone()); - let ssl_server_xml = ssl_server::build( - hdfs.has_https_enabled(), - config_overrides.ssl_server_xml.clone(), - ); - let ssl_client_xml = ssl_client::build( - hdfs.has_https_enabled(), - config_overrides.ssl_client_xml.clone(), - ); - - let mut builder = ConfigMapBuilder::new(); - builder - .metadata(metadata.build()) - .add_data(ConfigFileName::CoreSite.to_string(), core_site_xml) - .add_data(ConfigFileName::HdfsSite.to_string(), hdfs_site_xml) - .add_data(ConfigFileName::HadoopPolicy.to_string(), hadoop_policy_xml) - .add_data(ConfigFileName::SslServer.to_string(), ssl_server_xml) - .add_data(ConfigFileName::SslClient.to_string(), ssl_client_xml) - .add_data( - ConfigFileName::Security.to_string(), - security_properties::build(config_overrides.security_properties.clone()).with_context( - |_| JvmSecurityPropertiesSnafu { - rolegroup: rolegroup_ref.role_group.clone(), - }, - )?, - ); - - extend_role_group_config_map(rolegroup_ref, merged_config, &mut builder).context( - InvalidLoggingConfigSnafu { - cm_name: rolegroup_ref.object_name(), - }, - )?; - - builder - .build() - .with_context(|_| BuildRoleGroupConfigMapSnafu { - role: rolegroup_ref.role.clone(), - role_group: rolegroup_ref.role_group.clone(), - }) -} - #[allow(clippy::too_many_arguments)] fn rolegroup_statefulset( hdfs: &v1alpha1::HdfsCluster, From 09eb91228fb97f68e24578d7b240e2041923813b Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 21:52:51 +0200 Subject: [PATCH 11/18] refactor: resolve cluster-wide config into ValidatedClusterConfig Mirrors trino-operator: ValidatedCluster now carries a ValidatedClusterConfig (name, namespace, dfs_replication, https/kerberos/ authentication/authorization flags, rack awareness, OPA authorization) resolved once during validation. The standalone hdfs_opa_config field is folded into it. The build steps no longer take the raw HdfsCluster: - hdfs_site/core_site builders and build_rolegroup_config_map consume &ValidatedClusterConfig / &ValidatedCluster. - The lower-level HdfsSiteConfigBuilder/CoreSiteConfigBuilder and their kerberos security_config impls take primitives (a KerberosConfig struct and bools) to keep the config layer free of controller types. Behavior-preserving: the flags are computed by the same HdfsCluster predicates as before, just resolved up-front. The discovery path keeps using the raw HdfsCluster as it does not go through validation. Co-Authored-By: Claude Opus 4.8 (1M context) --- rust/operator-binary/src/config/mod.rs | 5 +- .../src/controller/build/config_map.rs | 30 ++------- .../controller/build/properties/core_site.rs | 37 +++++----- .../controller/build/properties/hdfs_site.rs | 39 +++++------ .../src/controller/build/properties/mod.rs | 6 +- .../src/controller/validate.rs | 5 +- rust/operator-binary/src/discovery.rs | 17 +++-- rust/operator-binary/src/hdfs_controller.rs | 40 ++++++++++- rust/operator-binary/src/security/kerberos.rs | 67 ++++++++++--------- 9 files changed, 137 insertions(+), 109 deletions(-) diff --git a/rust/operator-binary/src/config/mod.rs b/rust/operator-binary/src/config/mod.rs index ba5f734a..2a466ae8 100644 --- a/rust/operator-binary/src/config/mod.rs +++ b/rust/operator-binary/src/config/mod.rs @@ -17,7 +17,6 @@ use crate::{ SERVICE_PORT_NAME_HTTPS, SERVICE_PORT_NAME_RPC, }, storage::{DataNodeStorageConfig, DataNodeStorageConfigInnerType}, - v1alpha1, }, }; @@ -168,11 +167,11 @@ impl HdfsSiteConfigBuilder { pub fn dfs_namenode_http_address_ha( &mut self, - hdfs: &v1alpha1::HdfsCluster, + https_enabled: bool, cluster_info: &KubernetesClusterInfo, namenode_podrefs: &[HdfsPodRef], ) -> &mut Self { - if hdfs.has_https_enabled() { + if https_enabled { self.dfs_namenode_address_ha( cluster_info, namenode_podrefs, diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index 4af45c59..da9ca68f 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -6,7 +6,6 @@ use snafu::{OptionExt, ResultExt, Snafu}; use stackable_operator::{ builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, k8s_openapi::api::core::v1::ConfigMap, - kube::runtime::reflector::ObjectRef, role_utils::RoleGroupRef, utils::cluster_info::KubernetesClusterInfo, }; @@ -24,11 +23,6 @@ use crate::{ #[derive(Snafu, Debug)] pub enum Error { - #[snafu(display("object has no name"))] - ObjectHasNoName { - obj_ref: ObjectRef, - }, - #[snafu(display("could not parse HDFS role [{role}]"))] UnidentifiedHdfsRole { source: strum::ParseError, @@ -63,10 +57,8 @@ pub enum Error { type Result = std::result::Result; -#[allow(clippy::too_many_arguments)] pub fn build_rolegroup_config_map( cluster: &ValidatedCluster, - hdfs: &v1alpha1::HdfsCluster, cluster_info: &KubernetesClusterInfo, metadata: &ObjectMetaBuilder, rolegroup_ref: &RoleGroupRef, @@ -90,42 +82,30 @@ pub fn build_rolegroup_config_map( })?; let merged_config = &rolegroup_config.merged_config; let config_overrides = &rolegroup_config.config_overrides; - let hdfs_opa_config = cluster.hdfs_opa_config.as_ref(); - - let hdfs_name = hdfs - .metadata - .name - .as_deref() - .with_context(|| ObjectHasNoNameSnafu { - obj_ref: ObjectRef::from_obj(hdfs), - })?; + let cluster_config = &cluster.cluster_config; let hdfs_site_xml = hdfs_site::build( - hdfs, - hdfs_name, + cluster_config, cluster_info, merged_config, namenode_podrefs, journalnode_podrefs, - hdfs_opa_config, config_overrides.hdfs_site_xml.clone(), ); let core_site_xml = core_site::build( - hdfs, - hdfs_name, + cluster_config, role, cluster_info, - hdfs_opa_config, config_overrides.core_site_xml.clone(), ) .context(BuildCoreSiteXmlSnafu)?; let hadoop_policy_xml = hadoop_policy::build(config_overrides.hadoop_policy_xml.clone()); let ssl_server_xml = ssl_server::build( - hdfs.has_https_enabled(), + cluster_config.https_enabled, config_overrides.ssl_server_xml.clone(), ); let ssl_client_xml = ssl_client::build( - hdfs.has_https_enabled(), + cluster_config.https_enabled, config_overrides.ssl_client_xml.clone(), ); 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 f1aff53a..dc7100f8 100644 --- a/rust/operator-binary/src/controller/build/properties/core_site.rs +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -10,8 +10,9 @@ use stackable_operator::{ use crate::{ config::CoreSiteConfigBuilder, controller::build::properties::resolved_overrides, - crd::{HdfsNodeRole, v1alpha1}, - security::{kerberos, opa::HdfsOpaConfig}, + crd::HdfsNodeRole, + hdfs_controller::ValidatedClusterConfig, + security::kerberos::{self, KerberosConfig}, }; #[derive(Debug, Snafu)] @@ -23,18 +24,24 @@ pub enum Error { /// Renders `core-site.xml`: operator defaults + kerberos/OPA security config, /// with user `configOverrides` applied last. pub fn build( - hdfs: &v1alpha1::HdfsCluster, - hdfs_name: &str, + cluster_config: &ValidatedClusterConfig, role: HdfsNodeRole, cluster_info: &KubernetesClusterInfo, - opa_config: Option<&HdfsOpaConfig>, overrides: KeyValueConfigOverrides, ) -> Result { - let mut core_site = CoreSiteConfigBuilder::new(hdfs_name.to_string()); + let kerberos = KerberosConfig { + cluster_name: &cluster_config.name, + cluster_namespace: cluster_config.namespace.as_deref(), + authentication_enabled: cluster_config.authentication_enabled, + kerberos_enabled: cluster_config.kerberos_enabled, + authorization_enabled: cluster_config.authorization_enabled, + }; + + let mut core_site = CoreSiteConfigBuilder::new(cluster_config.name.clone()); core_site .fs_default_fs() .ha_zookeeper_quorum() - .security_config(hdfs, cluster_info) + .security_config(&kerberos, cluster_info) .context(BuildSecurityConfigSnafu)? .enable_prometheus_endpoint() // The default (4096) hasn't changed since 2009. @@ -42,13 +49,13 @@ pub fn build( .add("io.file.buffer.size", "131072"); // Rack awareness topology provider, namenode only. Previously injected via // the product-config `Configuration::compute_files`. - if role == HdfsNodeRole::Name && hdfs.rackawareness_config().is_some() { + if role == HdfsNodeRole::Name && cluster_config.rack_awareness.is_some() { core_site.add( "net.topology.node.switch.mapping.impl", "tech.stackable.hadoop.StackableTopologyProvider", ); } - if let Some(opa_config) = opa_config { + if let Some(opa_config) = &cluster_config.authorization { opa_config.add_core_site_config(&mut core_site); } // the extend with config must come last in order to have overrides working!!! @@ -60,18 +67,15 @@ pub fn build( mod tests { use super::*; use crate::controller::build::properties::test_support::{ - cluster_info, config_overrides, minimal_hdfs, + cluster_info, config_overrides, validated_cluster_config, }; #[test] fn renders_operator_defaults() { - let hdfs = minimal_hdfs(); let xml = build( - &hdfs, - "hdfs", + &validated_cluster_config(), HdfsNodeRole::Name, &cluster_info(), - None, config_overrides(&[]), ) .unwrap(); @@ -93,13 +97,10 @@ mod tests { #[test] fn user_overrides_win_over_defaults() { - let hdfs = minimal_hdfs(); let xml = build( - &hdfs, - "hdfs", + &validated_cluster_config(), HdfsNodeRole::Name, &cluster_info(), - None, config_overrides(&[("io.file.buffer.size", "65536")]), ) .unwrap(); diff --git a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs index 6adb7d11..fcbdb182 100644 --- a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs +++ b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs @@ -9,21 +9,18 @@ use stackable_operator::{ use crate::{ config::HdfsSiteConfigBuilder, controller::build::properties::resolved_overrides, - crd::{AnyNodeConfig, HdfsPodRef, v1alpha1}, - security::opa::HdfsOpaConfig, + crd::{AnyNodeConfig, HdfsPodRef}, + hdfs_controller::ValidatedClusterConfig, }; /// Renders `hdfs-site.xml`: operator defaults, HA wiring derived from the pod /// refs, kerberos/OPA security config, with user `configOverrides` applied last. -#[allow(clippy::too_many_arguments)] pub fn build( - hdfs: &v1alpha1::HdfsCluster, - hdfs_name: &str, + cluster_config: &ValidatedClusterConfig, cluster_info: &KubernetesClusterInfo, merged_config: &AnyNodeConfig, namenode_podrefs: &[HdfsPodRef], journalnode_podrefs: &[HdfsPodRef], - opa_config: Option<&HdfsOpaConfig>, overrides: KeyValueConfigOverrides, ) -> String { // IMPORTANT: these folders must be under the volume mount point, otherwise they will not @@ -37,7 +34,7 @@ pub fn build( // https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithNFS.html // This caused a deadlock with no namenode becoming active during a startup after // HDFS was completely down for a while. - let mut hdfs_site = HdfsSiteConfigBuilder::new(hdfs_name.to_string()); + let mut hdfs_site = HdfsSiteConfigBuilder::new(cluster_config.name.clone()); hdfs_site .dfs_namenode_name_dir() .dfs_datanode_data_dir( @@ -46,15 +43,15 @@ pub fn build( .map(|node| node.resources.storage.clone()), ) .dfs_journalnode_edits_dir() - .dfs_replication(hdfs.spec.cluster_config.dfs_replication) + .dfs_replication(cluster_config.dfs_replication) .dfs_name_services() .dfs_ha_namenodes(namenode_podrefs) .dfs_namenode_shared_edits_dir(cluster_info, journalnode_podrefs) .dfs_namenode_name_dir_ha(namenode_podrefs) .dfs_namenode_rpc_address_ha(cluster_info, namenode_podrefs) - .dfs_namenode_http_address_ha(hdfs, cluster_info, namenode_podrefs) + .dfs_namenode_http_address_ha(cluster_config.https_enabled, cluster_info, namenode_podrefs) .dfs_client_failover_proxy_provider() - .security_config(hdfs) + .security_config(cluster_config.kerberos_enabled) .add("dfs.ha.fencing.methods", "shell(/bin/true)") .add("dfs.ha.automatic-failover.enabled", "true") .add("dfs.ha.namenode.id", "${env.POD_NAME}") @@ -99,12 +96,12 @@ pub fn build( // But today's Java and IO should be able to handle more, so bump it to 8192 for // better performance/concurrency. .add("dfs.datanode.max.transfer.threads", "8192"); - if hdfs.has_https_enabled() { + if cluster_config.https_enabled { hdfs_site.add("dfs.datanode.registered.https.port", "${env.HTTPS_PORT}"); } else { hdfs_site.add("dfs.datanode.registered.http.port", "${env.HTTP_PORT}"); } - if let Some(opa_config) = opa_config { + if let Some(opa_config) = &cluster_config.authorization { opa_config.add_hdfs_site_config(&mut hdfs_site); } // the extend with config must come last in order to have overrides working!!! @@ -117,9 +114,9 @@ mod tests { use super::*; use crate::{ controller::build::properties::test_support::{ - cluster_info, config_overrides, minimal_hdfs, + cluster_info, config_overrides, minimal_hdfs, validated_cluster_config, }, - crd::HdfsNodeRole, + crd::{HdfsNodeRole, v1alpha1}, }; fn namenode_merged_config(hdfs: &v1alpha1::HdfsCluster) -> AnyNodeConfig { @@ -130,16 +127,13 @@ mod tests { #[test] fn renders_operator_defaults() { - let hdfs = minimal_hdfs(); - let merged = namenode_merged_config(&hdfs); + let merged = namenode_merged_config(&minimal_hdfs()); let xml = build( - &hdfs, - "hdfs", + &validated_cluster_config(), &cluster_info(), &merged, &[], &[], - None, config_overrides(&[]), ); assert!( @@ -154,16 +148,13 @@ mod tests { #[test] fn user_overrides_win_over_defaults() { - let hdfs = minimal_hdfs(); - let merged = namenode_merged_config(&hdfs); + let merged = namenode_merged_config(&minimal_hdfs()); let xml = build( - &hdfs, - "hdfs", + &validated_cluster_config(), &cluster_info(), &merged, &[], &[], - None, config_overrides(&[("dfs.replication", "5")]), ); assert!( diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index d7ed2d2b..e3884bda 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -73,7 +73,7 @@ pub(crate) mod test_support { v2::config_overrides::KeyValueConfigOverrides, }; - use crate::crd::v1alpha1; + use crate::{crd::v1alpha1, hdfs_controller::ValidatedClusterConfig}; /// Builds a [`KeyValueConfigOverrides`] from `(key, value)` pairs for tests. pub fn config_overrides(pairs: &[(&str, &str)]) -> KeyValueConfigOverrides { @@ -120,4 +120,8 @@ spec: cluster_domain: DomainName::try_from("cluster.local").unwrap(), } } + + pub fn validated_cluster_config() -> ValidatedClusterConfig { + ValidatedClusterConfig::resolve(&minimal_hdfs(), None) + } } diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 505d1917..80321dad 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -20,7 +20,8 @@ use strum::IntoEnumIterator; use crate::{ crd::{HdfsNodeRole, v1alpha1}, hdfs_controller::{ - CONTAINER_IMAGE_BASE_NAME, ValidatedCluster, ValidatedRoleConfig, ValidatedRoleGroupConfig, + CONTAINER_IMAGE_BASE_NAME, ValidatedCluster, ValidatedClusterConfig, ValidatedRoleConfig, + ValidatedRoleGroupConfig, }, security::opa::HdfsOpaConfig, }; @@ -97,9 +98,9 @@ pub fn validate_cluster( Ok(ValidatedCluster { image: resolved_product_image, + cluster_config: ValidatedClusterConfig::resolve(hdfs, hdfs_opa_config), role_groups, role_configs, - hdfs_opa_config, }) } diff --git a/rust/operator-binary/src/discovery.rs b/rust/operator-binary/src/discovery.rs index 47942a3d..28474bfa 100644 --- a/rust/operator-binary/src/discovery.rs +++ b/rust/operator-binary/src/discovery.rs @@ -12,7 +12,7 @@ use crate::{ config::{CoreSiteConfigBuilder, HdfsSiteConfigBuilder}, controller::build::properties::ConfigFileName, crd::{HdfsNodeRole, HdfsPodRef, v1alpha1}, - security::kerberos, + security::kerberos::{self, KerberosConfig}, }; type Result = std::result::Result; @@ -89,9 +89,9 @@ fn build_discovery_hdfs_site_xml( .dfs_name_services() .dfs_ha_namenodes(namenode_podrefs) .dfs_namenode_rpc_address_ha(cluster_info, namenode_podrefs) - .dfs_namenode_http_address_ha(hdfs, cluster_info, namenode_podrefs) + .dfs_namenode_http_address_ha(hdfs.has_https_enabled(), cluster_info, namenode_podrefs) .dfs_client_failover_proxy_provider() - .security_discovery_config(hdfs) + .security_discovery_config(hdfs.has_kerberos_enabled()) .build_as_xml() } @@ -100,9 +100,18 @@ fn build_discovery_core_site_xml( cluster_info: &KubernetesClusterInfo, logical_name: String, ) -> Result { + let cluster_name = hdfs.name_any(); + let cluster_namespace = hdfs.namespace(); + let kerberos = KerberosConfig { + cluster_name: &cluster_name, + cluster_namespace: cluster_namespace.as_deref(), + authentication_enabled: hdfs.authentication_config().is_some(), + kerberos_enabled: hdfs.has_kerberos_enabled(), + authorization_enabled: hdfs.has_authorization_enabled(), + }; Ok(CoreSiteConfigBuilder::new(logical_name) .fs_default_fs() - .security_discovery_config(hdfs, cluster_info) + .security_discovery_config(&kerberos, cluster_info) .context(BuildSecurityDiscoveryConfigMapSnafu)? .build_as_xml()) } diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index 03c3e551..47082b79 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -71,9 +71,46 @@ pub const CONTAINER_IMAGE_BASE_NAME: &str = "hadoop"; #[derive(Clone, Debug)] pub struct ValidatedCluster { pub image: ResolvedProductImage, + pub cluster_config: ValidatedClusterConfig, pub role_groups: BTreeMap>, pub role_configs: BTreeMap, - pub hdfs_opa_config: Option, +} + +/// Cluster-wide settings resolved once during validation, so the build steps no +/// longer need the raw `HdfsCluster` to render config. The flags are computed by +/// the same `HdfsCluster` predicates used previously, just resolved up-front. +#[derive(Clone, Debug)] +pub struct ValidatedClusterConfig { + /// The logical (and Kubernetes object) name of the cluster. + pub name: String, + /// The cluster namespace, used to build kerberos principals. + pub namespace: Option, + pub dfs_replication: u8, + pub https_enabled: bool, + pub kerberos_enabled: bool, + pub authentication_enabled: bool, + pub authorization_enabled: bool, + pub rack_awareness: Option, + pub authorization: Option, +} + +impl ValidatedClusterConfig { + pub fn resolve( + hdfs: &v1alpha1::HdfsCluster, + authorization: Option, + ) -> ValidatedClusterConfig { + ValidatedClusterConfig { + name: hdfs.name_any(), + namespace: hdfs.namespace(), + dfs_replication: hdfs.spec.cluster_config.dfs_replication, + https_enabled: hdfs.has_https_enabled(), + kerberos_enabled: hdfs.has_kerberos_enabled(), + authentication_enabled: hdfs.authentication_config().is_some(), + authorization_enabled: hdfs.has_authorization_enabled(), + rack_awareness: hdfs.rackawareness_config(), + authorization, + } + } } /// Per-role configuration extracted during validation. @@ -369,7 +406,6 @@ pub async fn reconcile_hdfs( let rg_configmap = crate::controller::build::config_map::build_rolegroup_config_map( &validated, - hdfs, &client.kubernetes_cluster_info, metadata, &rolegroup_ref, diff --git a/rust/operator-binary/src/security/kerberos.rs b/rust/operator-binary/src/security/kerberos.rs index 989f7af3..2862d278 100644 --- a/rust/operator-binary/src/security/kerberos.rs +++ b/rust/operator-binary/src/security/kerberos.rs @@ -1,13 +1,9 @@ -use snafu::{ResultExt, Snafu}; -use stackable_operator::{ - kube::{ResourceExt, runtime::reflector::ObjectRef}, - utils::cluster_info::KubernetesClusterInfo, -}; +use snafu::{OptionExt, Snafu}; +use stackable_operator::utils::cluster_info::KubernetesClusterInfo; use crate::{ config::{CoreSiteConfigBuilder, HdfsSiteConfigBuilder}, controller::build::properties::ConfigFileName, - crd::v1alpha1, }; pub const KERBEROS_CONTAINER_PATH: &str = "/stackable/kerberos"; @@ -17,16 +13,27 @@ type Result = std::result::Result; #[derive(Snafu, Debug)] #[allow(clippy::enum_variant_names)] pub enum Error { - #[snafu(display("object has no namespace"))] - ObjectHasNoNamespace { - source: crate::crd::Error, - obj_ref: ObjectRef, - }, + #[snafu(display( + "the cluster {name:?} has no namespace, which is required to build kerberos principals" + ))] + ObjectHasNoNamespace { name: String }, +} + +/// The cluster-wide security settings the `security_config` builders need, +/// resolved from the `HdfsCluster` so the builders don't depend on the raw CRD. +pub struct KerberosConfig<'a> { + pub cluster_name: &'a str, + pub cluster_namespace: Option<&'a str>, + /// Whether an `authentication` config is set (gates the core-site security config). + pub authentication_enabled: bool, + /// Whether kerberos is enabled (gates the discovery security config). + pub kerberos_enabled: bool, + pub authorization_enabled: bool, } impl HdfsSiteConfigBuilder { - pub fn security_config(&mut self, hdfs: &v1alpha1::HdfsCluster) -> &mut Self { - if hdfs.has_kerberos_enabled() { + pub fn security_config(&mut self, kerberos_enabled: bool) -> &mut Self { + if kerberos_enabled { self.add("dfs.block.access.token.enable", "true") .add("dfs.http.policy", "HTTPS_ONLY") .add("hadoop.kerberos.keytab.login.autorenewal.enabled", "true") @@ -43,8 +50,8 @@ impl HdfsSiteConfigBuilder { self } - pub fn security_discovery_config(&mut self, hdfs: &v1alpha1::HdfsCluster) -> &mut Self { - if hdfs.has_kerberos_enabled() { + pub fn security_discovery_config(&mut self, kerberos_enabled: bool) -> &mut Self { + if kerberos_enabled { // We want e.g. hbase to automatically renew the Kerberos tickets. // This shouldn't harm any other consumers. self.add("hadoop.kerberos.keytab.login.autorenewal.enabled", "true"); @@ -67,11 +74,12 @@ impl HdfsSiteConfigBuilder { impl CoreSiteConfigBuilder { pub fn security_config( &mut self, - hdfs: &v1alpha1::HdfsCluster, + kerberos: &KerberosConfig, cluster_info: &KubernetesClusterInfo, ) -> Result<&mut Self> { - if hdfs.authentication_config().is_some() { - let principal_host_part = principal_host_part(hdfs, cluster_info)?; + if kerberos.authentication_enabled { + let principal_host_part = + principal_host_part(kerberos.cluster_name, kerberos.cluster_namespace, cluster_info)?; self.add("hadoop.security.authentication", "kerberos") // Not adding hadoop.registry.kerberos.realm, as it seems to not be used by our customers @@ -118,7 +126,7 @@ impl CoreSiteConfigBuilder { format!("nn/{principal_host_part}"), ); - if !hdfs.has_authorization_enabled() { + if !kerberos.authorization_enabled { // In case *no* OPA authorizer is used, we got the following error message: // java.io.IOException: No groups found for user nn // In case the OPA authorizer is used everything seems to be fine. @@ -136,11 +144,12 @@ impl CoreSiteConfigBuilder { pub fn security_discovery_config( &mut self, - hdfs: &v1alpha1::HdfsCluster, + kerberos: &KerberosConfig, cluster_info: &KubernetesClusterInfo, ) -> Result<&mut Self> { - if hdfs.has_kerberos_enabled() { - let principal_host_part = principal_host_part(hdfs, cluster_info)?; + if kerberos.kerberos_enabled { + let principal_host_part = + principal_host_part(kerberos.cluster_name, kerberos.cluster_namespace, cluster_info)?; self.add("hadoop.security.authentication", "kerberos") .add( @@ -180,17 +189,15 @@ impl CoreSiteConfigBuilder { /// /// After we have switched to using the following principals everything worked without problems fn principal_host_part( - hdfs: &v1alpha1::HdfsCluster, + cluster_name: &str, + cluster_namespace: Option<&str>, cluster_info: &KubernetesClusterInfo, ) -> Result { - let hdfs_name = hdfs.name_any(); - let hdfs_namespace = hdfs - .namespace_or_error() - .with_context(|_| ObjectHasNoNamespaceSnafu { - obj_ref: ObjectRef::from_obj(hdfs), - })?; + let cluster_namespace = cluster_namespace.context(ObjectHasNoNamespaceSnafu { + name: cluster_name.to_string(), + })?; let cluster_domain = &cluster_info.cluster_domain; Ok(format!( - "{hdfs_name}.{hdfs_namespace}.svc.{cluster_domain}@${{env.KERBEROS_REALM}}", + "{cluster_name}.{cluster_namespace}.svc.{cluster_domain}@${{env.KERBEROS_REALM}}", )) } From 3ca11acd5c566234a630389d276ab530b0ef5078 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Tue, 2 Jun 2026 22:08:02 +0200 Subject: [PATCH 12/18] refactor: add typed ClusterName to ValidatedCluster Adds a top-level name: ClusterName field to ValidatedCluster (mirroring trino-operator), constructed and validated in the validate step. The per-file builders and build_rolegroup_config_map now take the whole &ValidatedCluster, reading cluster.name and cluster.cluster_config. product_version is intentionally not added: unlike Trino (integer versions parsed to u16), HDFS uses semver product versions, so the image keeps carrying the version string. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/controller/build/config_map.rs | 4 ++-- .../src/controller/build/properties/core_site.rs | 15 ++++++++------- .../src/controller/build/properties/hdfs_site.rs | 13 +++++++------ .../src/controller/build/properties/mod.rs | 9 ++++++--- rust/operator-binary/src/controller/validate.rs | 10 +++++++++- rust/operator-binary/src/hdfs_controller.rs | 6 +++--- 6 files changed, 35 insertions(+), 22 deletions(-) diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index da9ca68f..7296190c 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -85,7 +85,7 @@ pub fn build_rolegroup_config_map( let cluster_config = &cluster.cluster_config; let hdfs_site_xml = hdfs_site::build( - cluster_config, + cluster, cluster_info, merged_config, namenode_podrefs, @@ -93,7 +93,7 @@ pub fn build_rolegroup_config_map( config_overrides.hdfs_site_xml.clone(), ); let core_site_xml = core_site::build( - cluster_config, + cluster, role, cluster_info, config_overrides.core_site_xml.clone(), 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 dc7100f8..378050a1 100644 --- a/rust/operator-binary/src/controller/build/properties/core_site.rs +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -11,7 +11,7 @@ use crate::{ config::CoreSiteConfigBuilder, controller::build::properties::resolved_overrides, crd::HdfsNodeRole, - hdfs_controller::ValidatedClusterConfig, + hdfs_controller::ValidatedCluster, security::kerberos::{self, KerberosConfig}, }; @@ -24,20 +24,21 @@ pub enum Error { /// Renders `core-site.xml`: operator defaults + kerberos/OPA security config, /// with user `configOverrides` applied last. pub fn build( - cluster_config: &ValidatedClusterConfig, + cluster: &ValidatedCluster, role: HdfsNodeRole, cluster_info: &KubernetesClusterInfo, overrides: KeyValueConfigOverrides, ) -> Result { + let cluster_config = &cluster.cluster_config; let kerberos = KerberosConfig { - cluster_name: &cluster_config.name, + cluster_name: cluster.name.as_ref(), cluster_namespace: cluster_config.namespace.as_deref(), authentication_enabled: cluster_config.authentication_enabled, kerberos_enabled: cluster_config.kerberos_enabled, authorization_enabled: cluster_config.authorization_enabled, }; - let mut core_site = CoreSiteConfigBuilder::new(cluster_config.name.clone()); + let mut core_site = CoreSiteConfigBuilder::new(cluster.name.as_ref().to_owned()); core_site .fs_default_fs() .ha_zookeeper_quorum() @@ -67,13 +68,13 @@ pub fn build( mod tests { use super::*; use crate::controller::build::properties::test_support::{ - cluster_info, config_overrides, validated_cluster_config, + cluster_info, config_overrides, validated_cluster, }; #[test] fn renders_operator_defaults() { let xml = build( - &validated_cluster_config(), + &validated_cluster(), HdfsNodeRole::Name, &cluster_info(), config_overrides(&[]), @@ -98,7 +99,7 @@ mod tests { #[test] fn user_overrides_win_over_defaults() { let xml = build( - &validated_cluster_config(), + &validated_cluster(), HdfsNodeRole::Name, &cluster_info(), config_overrides(&[("io.file.buffer.size", "65536")]), diff --git a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs index fcbdb182..ab7d65b5 100644 --- a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs +++ b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs @@ -10,19 +10,20 @@ use crate::{ config::HdfsSiteConfigBuilder, controller::build::properties::resolved_overrides, crd::{AnyNodeConfig, HdfsPodRef}, - hdfs_controller::ValidatedClusterConfig, + hdfs_controller::ValidatedCluster, }; /// Renders `hdfs-site.xml`: operator defaults, HA wiring derived from the pod /// refs, kerberos/OPA security config, with user `configOverrides` applied last. pub fn build( - cluster_config: &ValidatedClusterConfig, + cluster: &ValidatedCluster, cluster_info: &KubernetesClusterInfo, merged_config: &AnyNodeConfig, namenode_podrefs: &[HdfsPodRef], journalnode_podrefs: &[HdfsPodRef], overrides: KeyValueConfigOverrides, ) -> String { + let cluster_config = &cluster.cluster_config; // IMPORTANT: these folders must be under the volume mount point, otherwise they will not // be formatted by the namenode, or used by the other services. // See also: https://github.com/apache-spark-on-k8s/kubernetes-HDFS/commit/aef9586ecc8551ca0f0a468c3b917d8c38f494a0 @@ -34,7 +35,7 @@ pub fn build( // https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithNFS.html // This caused a deadlock with no namenode becoming active during a startup after // HDFS was completely down for a while. - let mut hdfs_site = HdfsSiteConfigBuilder::new(cluster_config.name.clone()); + let mut hdfs_site = HdfsSiteConfigBuilder::new(cluster.name.as_ref().to_owned()); hdfs_site .dfs_namenode_name_dir() .dfs_datanode_data_dir( @@ -114,7 +115,7 @@ mod tests { use super::*; use crate::{ controller::build::properties::test_support::{ - cluster_info, config_overrides, minimal_hdfs, validated_cluster_config, + cluster_info, config_overrides, minimal_hdfs, validated_cluster, }, crd::{HdfsNodeRole, v1alpha1}, }; @@ -129,7 +130,7 @@ mod tests { fn renders_operator_defaults() { let merged = namenode_merged_config(&minimal_hdfs()); let xml = build( - &validated_cluster_config(), + &validated_cluster(), &cluster_info(), &merged, &[], @@ -150,7 +151,7 @@ mod tests { fn user_overrides_win_over_defaults() { let merged = namenode_merged_config(&minimal_hdfs()); let xml = build( - &validated_cluster_config(), + &validated_cluster(), &cluster_info(), &merged, &[], diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index e3884bda..cce8b003 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -73,7 +73,9 @@ pub(crate) mod test_support { v2::config_overrides::KeyValueConfigOverrides, }; - use crate::{crd::v1alpha1, hdfs_controller::ValidatedClusterConfig}; + use crate::{ + controller::validate::validate_cluster, crd::v1alpha1, hdfs_controller::ValidatedCluster, + }; /// Builds a [`KeyValueConfigOverrides`] from `(key, value)` pairs for tests. pub fn config_overrides(pairs: &[(&str, &str)]) -> KeyValueConfigOverrides { @@ -121,7 +123,8 @@ spec: } } - pub fn validated_cluster_config() -> ValidatedClusterConfig { - ValidatedClusterConfig::resolve(&minimal_hdfs(), None) + pub fn validated_cluster() -> ValidatedCluster { + validate_cluster(&minimal_hdfs(), "oci.example.org", None) + .expect("validate should succeed for the minimal fixture") } } diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 80321dad..c7ba19fc 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -7,13 +7,15 @@ //! validated via [`HdfsNodeRole::merged_config`], and the per-file //! `configOverrides` / `envOverrides` are merged here (role group wins). -use std::collections::BTreeMap; +use std::{collections::BTreeMap, str::FromStr}; use snafu::{ResultExt, Snafu}; use stackable_operator::{ commons::product_image_selection, config::merge::Merge, + kube::ResourceExt, role_utils::{GenericRoleConfig, JavaCommonConfig, Role}, + v2::types::operator::ClusterName, }; use strum::IntoEnumIterator; @@ -33,6 +35,11 @@ pub enum Error { source: product_image_selection::Error, }, + #[snafu(display("invalid cluster name"))] + InvalidClusterName { + source: stackable_operator::v2::macros::attributed_string_type::Error, + }, + #[snafu(display("failed to resolve and merge config for role and role group"))] FailedToResolveConfig { source: crate::crd::Error }, } @@ -97,6 +104,7 @@ pub fn validate_cluster( } Ok(ValidatedCluster { + name: ClusterName::from_str(&hdfs.name_any()).context(InvalidClusterNameSnafu)?, image: resolved_product_image, cluster_config: ValidatedClusterConfig::resolve(hdfs, hdfs_opa_config), role_groups, diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index 47082b79..77230903 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -38,6 +38,7 @@ use stackable_operator::{ rollout::check_statefulset_rollout_complete, }, utils::cluster_info::KubernetesClusterInfo, + v2::types::operator::ClusterName, }; use strum::{EnumDiscriminants, IntoEnumIterator, IntoStaticStr}; @@ -70,6 +71,8 @@ pub const CONTAINER_IMAGE_BASE_NAME: &str = "hadoop"; /// the controller. #[derive(Clone, Debug)] pub struct ValidatedCluster { + /// The logical (and Kubernetes object) name of the cluster. + pub name: ClusterName, pub image: ResolvedProductImage, pub cluster_config: ValidatedClusterConfig, pub role_groups: BTreeMap>, @@ -81,8 +84,6 @@ pub struct ValidatedCluster { /// the same `HdfsCluster` predicates used previously, just resolved up-front. #[derive(Clone, Debug)] pub struct ValidatedClusterConfig { - /// The logical (and Kubernetes object) name of the cluster. - pub name: String, /// The cluster namespace, used to build kerberos principals. pub namespace: Option, pub dfs_replication: u8, @@ -100,7 +101,6 @@ impl ValidatedClusterConfig { authorization: Option, ) -> ValidatedClusterConfig { ValidatedClusterConfig { - name: hdfs.name_any(), namespace: hdfs.namespace(), dfs_replication: hdfs.spec.cluster_config.dfs_replication, https_enabled: hdfs.has_https_enabled(), From 5b22234205f9ef09880eb5c2dc9b386a01208a95 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 10:39:55 +0200 Subject: [PATCH 13/18] fix: update hashes --- Cargo.nix | 18 +++++++++--------- crate-hashes.json | 18 +++++++++--------- rust/operator-binary/src/config/writer.rs | 4 +--- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/Cargo.nix b/Cargo.nix index 7c3a2886..bd93b000 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 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + 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 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_certs"; authors = [ @@ -9707,7 +9707,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_operator"; authors = [ @@ -9892,7 +9892,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; procMacro = true; libName = "stackable_operator_derive"; @@ -9927,7 +9927,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_shared"; authors = [ @@ -10008,7 +10008,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_telemetry"; authors = [ @@ -10118,7 +10118,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_versioned"; authors = [ @@ -10168,7 +10168,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; procMacro = true; libName = "stackable_versioned_macros"; @@ -10236,7 +10236,7 @@ rec { src = pkgs.fetchgit { url = "https://github.com/stackabletech//operator-rs.git"; rev = "a31cd2514445b251038fc4ea7abc28c57b2a6ad9"; - sha256 = "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk"; + sha256 = "0idpq1xdkr94zrd95xsvrwkj3bvzbii9a7qmw23rn5w4yiwgmj96"; }; libName = "stackable_webhook"; authors = [ diff --git a/crate-hashes.json b/crate-hashes.json index 5564a89e..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": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-certs@0.4.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator-derive@0.3.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-operator@0.111.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-shared@0.1.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-telemetry@0.6.3": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned-macros@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-versioned@0.10.0": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", - "git+https://github.com/stackabletech//operator-rs.git?branch=smooth-operator#stackable-webhook@0.9.1": "0lj969rjbxairjglrnaq0xhabvdrq5nd6wl1i0y9pr50nhh7zvgk", + "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 diff --git a/rust/operator-binary/src/config/writer.rs b/rust/operator-binary/src/config/writer.rs index cc161306..08250f9f 100644 --- a/rust/operator-binary/src/config/writer.rs +++ b/rust/operator-binary/src/config/writer.rs @@ -1,9 +1,7 @@ //! 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. The on-wire format is pinned -//! by the kuttl ConfigMap snapshots under -//! `tests/templates/kuttl/smoke/31_configmap_hdfs-*-default.yaml.j2`. +//! longer depends on `product-config` for rendering. use std::io::Write; From ed57da555cab34e5c75bc2b9901be18a1f41eb4b Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 11:15:45 +0200 Subject: [PATCH 14/18] refactor: resolve namenode/journalnode pod refs during validation Move the pod_refs lookups for namenodes and journalnodes out of reconcile_hdfs and into validate_cluster, storing the results on ValidatedCluster. Build steps that already receive the validated cluster (config_map and hdfs_site) now read the refs from it instead of taking them as separate parameters. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/controller/build/config_map.rs | 6 +----- .../controller/build/properties/hdfs_site.rs | 14 ++++--------- .../src/controller/build/properties/mod.rs | 1 + .../src/controller/validate.rs | 14 +++++++++++++ rust/operator-binary/src/crd/mod.rs | 1 + rust/operator-binary/src/hdfs_controller.rs | 21 +++++++------------ 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index 7296190c..90fb45f6 100644 --- a/rust/operator-binary/src/controller/build/config_map.rs +++ b/rust/operator-binary/src/controller/build/config_map.rs @@ -16,7 +16,7 @@ use crate::{ ConfigFileName, core_site, hadoop_policy, hdfs_site, security_properties, ssl_client, ssl_server, }, - crd::{HdfsNodeRole, HdfsPodRef, v1alpha1}, + crd::{HdfsNodeRole, v1alpha1}, hdfs_controller::ValidatedCluster, product_logging::extend_role_group_config_map, }; @@ -62,8 +62,6 @@ pub fn build_rolegroup_config_map( cluster_info: &KubernetesClusterInfo, metadata: &ObjectMetaBuilder, rolegroup_ref: &RoleGroupRef, - namenode_podrefs: &[HdfsPodRef], - journalnode_podrefs: &[HdfsPodRef], ) -> Result { tracing::info!("Setting up ConfigMap for {:?}", rolegroup_ref); @@ -88,8 +86,6 @@ pub fn build_rolegroup_config_map( cluster, cluster_info, merged_config, - namenode_podrefs, - journalnode_podrefs, config_overrides.hdfs_site_xml.clone(), ); let core_site_xml = core_site::build( diff --git a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs index ab7d65b5..2315d542 100644 --- a/rust/operator-binary/src/controller/build/properties/hdfs_site.rs +++ b/rust/operator-binary/src/controller/build/properties/hdfs_site.rs @@ -7,10 +7,8 @@ use stackable_operator::{ }; use crate::{ - config::HdfsSiteConfigBuilder, - controller::build::properties::resolved_overrides, - crd::{AnyNodeConfig, HdfsPodRef}, - hdfs_controller::ValidatedCluster, + config::HdfsSiteConfigBuilder, controller::build::properties::resolved_overrides, + crd::AnyNodeConfig, hdfs_controller::ValidatedCluster, }; /// Renders `hdfs-site.xml`: operator defaults, HA wiring derived from the pod @@ -19,11 +17,11 @@ pub fn build( cluster: &ValidatedCluster, cluster_info: &KubernetesClusterInfo, merged_config: &AnyNodeConfig, - namenode_podrefs: &[HdfsPodRef], - journalnode_podrefs: &[HdfsPodRef], overrides: KeyValueConfigOverrides, ) -> String { let cluster_config = &cluster.cluster_config; + let namenode_podrefs = &cluster.namenode_podrefs; + let journalnode_podrefs = &cluster.journalnode_podrefs; // IMPORTANT: these folders must be under the volume mount point, otherwise they will not // be formatted by the namenode, or used by the other services. // See also: https://github.com/apache-spark-on-k8s/kubernetes-HDFS/commit/aef9586ecc8551ca0f0a468c3b917d8c38f494a0 @@ -133,8 +131,6 @@ mod tests { &validated_cluster(), &cluster_info(), &merged, - &[], - &[], config_overrides(&[]), ); assert!( @@ -154,8 +150,6 @@ mod tests { &validated_cluster(), &cluster_info(), &merged, - &[], - &[], config_overrides(&[("dfs.replication", "5")]), ); assert!( diff --git a/rust/operator-binary/src/controller/build/properties/mod.rs b/rust/operator-binary/src/controller/build/properties/mod.rs index cce8b003..61849ad7 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -94,6 +94,7 @@ apiVersion: hdfs.stackable.tech/v1alpha1 kind: HdfsCluster metadata: name: hdfs + namespace: default spec: image: productVersion: 3.4.0 diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index c7ba19fc..1efff6f0 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -42,6 +42,9 @@ pub enum Error { #[snafu(display("failed to resolve and merge config for role and role group"))] FailedToResolveConfig { source: crate::crd::Error }, + + #[snafu(display("failed to create pod references"))] + CreatePodReferences { source: crate::crd::Error }, } pub fn validate_cluster( @@ -103,12 +106,23 @@ pub fn validate_cluster( role_groups.insert(hdfs_role, group_configs); } + // A list of all name and journal nodes across all role groups is needed for all + // ConfigMaps and initialization checks. + let namenode_podrefs = hdfs + .pod_refs(&HdfsNodeRole::Name) + .context(CreatePodReferencesSnafu)?; + let journalnode_podrefs = hdfs + .pod_refs(&HdfsNodeRole::Journal) + .context(CreatePodReferencesSnafu)?; + Ok(ValidatedCluster { name: ClusterName::from_str(&hdfs.name_any()).context(InvalidClusterNameSnafu)?, image: resolved_product_image, cluster_config: ValidatedClusterConfig::resolve(hdfs, hdfs_opa_config), role_groups, role_configs, + namenode_podrefs, + journalnode_podrefs, }) } diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 71bf15a7..2301aab0 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -1161,6 +1161,7 @@ impl HdfsNodeRole { /// Reference to a single `Pod` that is a component of a [`HdfsCluster`] /// /// Used for service discovery. +#[derive(Clone, Debug)] pub struct HdfsPodRef { pub namespace: String, pub role_group_service_name: String, diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index 77230903..d9361430 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -77,6 +77,12 @@ pub struct ValidatedCluster { pub cluster_config: ValidatedClusterConfig, pub role_groups: BTreeMap>, pub role_configs: BTreeMap, + /// Pod references for all namenodes across all role groups. Needed for all + /// ConfigMaps and initialization checks. Resolved once during validation. + pub namenode_podrefs: Vec, + /// Pod references for all journalnodes across all role groups. Resolved once + /// during validation. + pub journalnode_podrefs: Vec, } /// Cluster-wide settings resolved once during validation, so the build steps no @@ -205,9 +211,6 @@ pub enum Error { source: stackable_operator::cluster_resources::Error, }, - #[snafu(display("failed to create pod references"))] - CreatePodReferences { source: crate::crd::Error }, - #[snafu(display("failed to create cluster event"))] FailedToCreateClusterEvent { source: crate::event::Error }, @@ -296,13 +299,6 @@ pub async fn reconcile_hdfs( let resolved_product_image = &validated.image; let hdfs_obj_ref = hdfs.object_ref(&()); - // A list of all name and journal nodes across all role groups is needed for all ConfigMaps and initialization checks. - let namenode_podrefs = hdfs - .pod_refs(&HdfsNodeRole::Name) - .context(CreatePodReferencesSnafu)?; - let journalnode_podrefs = hdfs - .pod_refs(&HdfsNodeRole::Journal) - .context(CreatePodReferencesSnafu)?; let mut cluster_resources = ClusterResources::new( APP_NAME, @@ -409,8 +405,6 @@ pub async fn reconcile_hdfs( &client.kubernetes_cluster_info, metadata, &rolegroup_ref, - &namenode_podrefs, - &journalnode_podrefs, ) .context(BuildRoleGroupConfigMapSnafu)?; @@ -423,7 +417,7 @@ pub async fn reconcile_hdfs( resolved_product_image, Some(env_overrides), merged_config, - &namenode_podrefs, + &validated.namenode_podrefs, &rbac_sa, )?; @@ -686,6 +680,7 @@ apiVersion: hdfs.stackable.tech/v1alpha1 kind: HdfsCluster metadata: name: hdfs + namespace: default spec: image: productVersion: 3.4.0 From 383fb77b7745c088b131421980c5b09d38ac85a4 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 11:38:48 +0200 Subject: [PATCH 15/18] style: rustfmt principal_host_part call in kerberos.rs Co-Authored-By: Claude Opus 4.8 (1M context) --- rust/operator-binary/src/security/kerberos.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/rust/operator-binary/src/security/kerberos.rs b/rust/operator-binary/src/security/kerberos.rs index 2862d278..857bf481 100644 --- a/rust/operator-binary/src/security/kerberos.rs +++ b/rust/operator-binary/src/security/kerberos.rs @@ -78,8 +78,11 @@ impl CoreSiteConfigBuilder { cluster_info: &KubernetesClusterInfo, ) -> Result<&mut Self> { if kerberos.authentication_enabled { - let principal_host_part = - principal_host_part(kerberos.cluster_name, kerberos.cluster_namespace, cluster_info)?; + let principal_host_part = principal_host_part( + kerberos.cluster_name, + kerberos.cluster_namespace, + cluster_info, + )?; self.add("hadoop.security.authentication", "kerberos") // Not adding hadoop.registry.kerberos.realm, as it seems to not be used by our customers @@ -148,8 +151,11 @@ impl CoreSiteConfigBuilder { cluster_info: &KubernetesClusterInfo, ) -> Result<&mut Self> { if kerberos.kerberos_enabled { - let principal_host_part = - principal_host_part(kerberos.cluster_name, kerberos.cluster_namespace, cluster_info)?; + let principal_host_part = principal_host_part( + kerberos.cluster_name, + kerberos.cluster_namespace, + cluster_info, + )?; self.add("hadoop.security.authentication", "kerberos") .add( From 4d60ec990208821cc977f06dec7e8b8e57813262 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 13:13:53 +0200 Subject: [PATCH 16/18] chore: remove left over product config references --- .../reference/environment-variables.adoc | 26 ------------------- .../controller/build/properties/core_site.rs | 3 +-- .../build/properties/security_properties.rs | 5 ++-- .../src/controller/validate.rs | 16 +++++------- rust/operator-binary/src/service.rs | 3 --- 5 files changed, 9 insertions(+), 44 deletions(-) diff --git a/docs/modules/hdfs/pages/reference/environment-variables.adoc b/docs/modules/hdfs/pages/reference/environment-variables.adoc index 875bc3a7..09564694 100644 --- a/docs/modules/hdfs/pages/reference/environment-variables.adoc +++ b/docs/modules/hdfs/pages/reference/environment-variables.adoc @@ -33,32 +33,6 @@ docker run \ oci.stackable.tech/sdp/hdfs-operator:0.0.0-dev ---- -== PRODUCT_CONFIG - -*Default value*: `/etc/stackable/hdfs-operator/config-spec/properties.yaml` - -*Required*: false - -*Multiple values*: false - -[source] ----- -export PRODUCT_CONFIG=/foo/bar/properties.yaml -stackable-hdfs-operator run ----- - -or via docker: - ----- -docker run \ - --name hdfs-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/hdfs-operator:0.0.0-dev ----- - == WATCH_NAMESPACE *Default value*: All namespaces 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 378050a1..b263b181 100644 --- a/rust/operator-binary/src/controller/build/properties/core_site.rs +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -48,8 +48,7 @@ pub fn build( // The default (4096) hasn't changed since 2009. // Increase to 128k to allow for faster transfers. .add("io.file.buffer.size", "131072"); - // Rack awareness topology provider, namenode only. Previously injected via - // the product-config `Configuration::compute_files`. + // Rack awareness topology provider, namenode only. if role == HdfsNodeRole::Name && cluster_config.rack_awareness.is_some() { core_site.add( "net.topology.node.switch.mapping.impl", 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 bce30cf7..336585c4 100644 --- a/rust/operator-binary/src/controller/build/properties/security_properties.rs +++ b/rust/operator-binary/src/controller/build/properties/security_properties.rs @@ -1,8 +1,7 @@ //! Builds the `security.properties` (JVM security) config file. //! -//! The operator injects recommended JVM DNS cache TTLs (previously supplied via -//! the product-config `properties.yaml`); user `configOverrides` are applied on -//! top. +//! The operator injects recommended JVM DNS cache TTLs. +//! User `configOverrides` are applied on top. use std::collections::BTreeMap; diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 1efff6f0..0731cb72 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -1,11 +1,9 @@ //! The validate step in the HdfsCluster controller. //! -//! Synchronously merges and validates the cluster spec into the typed -//! [`ValidatedCluster`], consumed by `controller::build::*`. This replaces the -//! product-config `transform_all_roles_to_config` / -//! `validate_all_roles_and_groups_config` steps: config fragments are merged and -//! validated via [`HdfsNodeRole::merged_config`], and the per-file -//! `configOverrides` / `envOverrides` are merged here (role group wins). +//! Synchronously merges and validates the cluster spec into the typed [`ValidatedCluster`] +//! consumed by `controller::build::*`. Config fragments are merged and validated via +//! [`HdfsNodeRole::merged_config`], and the per-file `configOverrides` / `envOverrides` +//! are merged here (role group wins). use std::{collections::BTreeMap, str::FromStr}; @@ -85,8 +83,7 @@ pub fn validate_cluster( .merged_config(hdfs, &role_group_name) .context(FailedToResolveConfigSnafu)?; - // Rack awareness topology labels, namenode only. Previously injected - // via the product-config `Configuration::compute_env`. + // Rack awareness topology labels, namenode only. if hdfs_role == HdfsNodeRole::Name { if let Some(rack_awareness) = hdfs.rackawareness_config() { env_overrides.insert("TOPOLOGY_LABELS".to_string(), rack_awareness); @@ -127,8 +124,7 @@ pub fn validate_cluster( } /// Merges the role-level and role-group-level `configOverrides` and `envOverrides` -/// for every role group of a role (the role group wins). Replaces the -/// product-config `transform_all_roles_to_config` step. +/// for every role group of a role (the role group wins). fn collect_role_group_overrides( role: Option<&Role>, ) -> Vec<( diff --git a/rust/operator-binary/src/service.rs b/rust/operator-binary/src/service.rs index e250b6fb..630af3bf 100644 --- a/rust/operator-binary/src/service.rs +++ b/rust/operator-binary/src/service.rs @@ -19,9 +19,6 @@ pub enum Error { #[snafu(display("failed to build prometheus label"))] BuildPrometheusLabel { source: LabelError }, - #[snafu(display("failed to build role-group selector label"))] - BuildRoleGroupSelectorLabel { source: LabelError }, - #[snafu(display("failed to build object meta data"))] ObjectMeta { source: stackable_operator::builder::meta::Error, From 523a376ff19655d9f4ddbdafb2c83135fcdaf4bf Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Wed, 3 Jun 2026 13:24:46 +0200 Subject: [PATCH 17/18] chore: adapted changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c97e55e..781cc69b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,12 +18,15 @@ All notable changes to this project will be documented in this file. - Bump `stackable-operator` to 0.111.1 ([#777], [#778]). - Internal operator refactoring: introduce dereference() and validate() steps in the reconciler ([#783]). - test: Bump vector-aggregator to 0.55.0, replace /graphql call with gRPC call ([#787]). +- 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 ([#790]). [#770]: https://github.com/stackabletech/hdfs-operator/pull/770 [#777]: https://github.com/stackabletech/hdfs-operator/pull/777 [#778]: https://github.com/stackabletech/hdfs-operator/pull/778 [#783]: https://github.com/stackabletech/hdfs-operator/pull/783 [#787]: https://github.com/stackabletech/hdfs-operator/pull/787 +[#790]: https://github.com/stackabletech/hdfs-operator/pull/790 ## [26.3.0] - 2026-03-16 From 05e6f29796f5266ee720d1cac969489646b67ec1 Mon Sep 17 00:00:00 2001 From: Malte Sander Date: Thu, 4 Jun 2026 14:58:43 +0200 Subject: [PATCH 18/18] refactor: move logging & discovery to build step --- rust/operator-binary/src/container.rs | 14 +- .../src/controller/build/config_map.rs | 23 ++-- .../src/{ => controller/build}/discovery.rs | 64 +++++---- .../src/controller/build/mod.rs | 1 + .../controller/build/properties/core_site.rs | 2 +- .../build/properties/logging.rs} | 129 +++++++++--------- .../src/controller/build/properties/mod.rs | 1 + .../src/controller/validate.rs | 1 + rust/operator-binary/src/hdfs_controller.rs | 16 +-- rust/operator-binary/src/main.rs | 2 - 10 files changed, 123 insertions(+), 130 deletions(-) rename rust/operator-binary/src/{ => controller/build}/discovery.rs (61%) rename rust/operator-binary/src/{product_logging.rs => controller/build/properties/logging.rs} (65%) diff --git a/rust/operator-binary/src/container.rs b/rust/operator-binary/src/container.rs index 98e7de23..9fdff944 100644 --- a/rust/operator-binary/src/container.rs +++ b/rust/operator-binary/src/container.rs @@ -61,6 +61,13 @@ use crate::{ self, jvm::{construct_global_jvm_args, construct_role_specific_jvm_args}, }, + controller::build::properties::logging::{ + FORMAT_NAMENODES_LOG4J_CONFIG_FILE, FORMAT_ZOOKEEPER_LOG4J_CONFIG_FILE, + HDFS_LOG4J_CONFIG_FILE, MAX_FORMAT_NAMENODE_LOG_FILE_SIZE, + MAX_FORMAT_ZOOKEEPER_LOG_FILE_SIZE, MAX_HDFS_LOG_FILE_SIZE, + MAX_WAIT_NAMENODES_LOG_FILE_SIZE, MAX_ZKFC_LOG_FILE_SIZE, STACKABLE_LOG_DIR, + WAIT_FOR_NAMENODES_LOG4J_CONFIG_FILE, ZKFC_LOG4J_CONFIG_FILE, + }, crd::{ AnyNodeConfig, DataNodeContainer, HdfsNodeRole, HdfsPodRef, NameNodeContainer, UpgradeState, @@ -77,13 +84,6 @@ use crate::{ storage::DataNodeStorageConfig, v1alpha1, }, - product_logging::{ - FORMAT_NAMENODES_LOG4J_CONFIG_FILE, FORMAT_ZOOKEEPER_LOG4J_CONFIG_FILE, - HDFS_LOG4J_CONFIG_FILE, MAX_FORMAT_NAMENODE_LOG_FILE_SIZE, - MAX_FORMAT_ZOOKEEPER_LOG_FILE_SIZE, MAX_HDFS_LOG_FILE_SIZE, - MAX_WAIT_NAMENODES_LOG_FILE_SIZE, MAX_ZKFC_LOG_FILE_SIZE, STACKABLE_LOG_DIR, - WAIT_FOR_NAMENODES_LOG4J_CONFIG_FILE, ZKFC_LOG4J_CONFIG_FILE, - }, security::kerberos::KERBEROS_CONTAINER_PATH, }; diff --git a/rust/operator-binary/src/controller/build/config_map.rs b/rust/operator-binary/src/controller/build/config_map.rs index 90fb45f6..88422e21 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 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, utils::cluster_info::KubernetesClusterInfo, }; @@ -13,12 +14,11 @@ use stackable_operator::{ use crate::{ config::writer::PropertiesWriterError, controller::build::properties::{ - ConfigFileName, core_site, hadoop_policy, hdfs_site, security_properties, ssl_client, - ssl_server, + ConfigFileName, core_site, hadoop_policy, hdfs_site, logging, security_properties, + ssl_client, ssl_server, }, crd::{HdfsNodeRole, v1alpha1}, hdfs_controller::ValidatedCluster, - product_logging::extend_role_group_config_map, }; #[derive(Snafu, Debug)] @@ -41,12 +41,6 @@ pub enum Error { rolegroup: String, }, - #[snafu(display("failed to add the logging configuration to the ConfigMap {cm_name:?}"))] - InvalidLoggingConfig { - source: crate::product_logging::Error, - cm_name: String, - }, - #[snafu(display("cannot build config map for role {role:?} and role group {role_group:?}"))] Assemble { source: stackable_operator::builder::configmap::Error, @@ -122,11 +116,12 @@ pub fn build_rolegroup_config_map( )?, ); - extend_role_group_config_map(rolegroup_ref, merged_config, &mut builder).context( - InvalidLoggingConfigSnafu { - cm_name: rolegroup_ref.object_name(), - }, - )?; + for (log_config_file, log4j_config) in logging::build_log4j_configs(merged_config) { + builder.add_data(log_config_file, log4j_config); + } + if let Some(vector_config) = logging::build_vector_config(rolegroup_ref, merged_config) { + builder.add_data(VECTOR_CONFIG_FILE, vector_config); + } builder.build().with_context(|_| AssembleSnafu { role: rolegroup_ref.role.clone(), diff --git a/rust/operator-binary/src/discovery.rs b/rust/operator-binary/src/controller/build/discovery.rs similarity index 61% rename from rust/operator-binary/src/discovery.rs rename to rust/operator-binary/src/controller/build/discovery.rs index 28474bfa..f5a5ebca 100644 --- a/rust/operator-binary/src/discovery.rs +++ b/rust/operator-binary/src/controller/build/discovery.rs @@ -1,9 +1,10 @@ +//! Build the discovery `ConfigMap` for the HdfsCluster. + use snafu::{ResultExt, Snafu}; use stackable_operator::{ builder::{configmap::ConfigMapBuilder, meta::ObjectMetaBuilder}, - commons::product_image_selection::ResolvedProductImage, k8s_openapi::api::core::v1::ConfigMap, - kube::{ResourceExt, runtime::reflector::ObjectRef}, + kube::runtime::reflector::ObjectRef, utils::cluster_info::KubernetesClusterInfo, }; @@ -12,6 +13,7 @@ use crate::{ config::{CoreSiteConfigBuilder, HdfsSiteConfigBuilder}, controller::build::properties::ConfigFileName, crd::{HdfsNodeRole, HdfsPodRef, v1alpha1}, + hdfs_controller::{HDFS_CONTROLLER_NAME, ValidatedCluster}, security::kerberos::{self, KerberosConfig}, }; @@ -42,23 +44,26 @@ pub enum Error { /// Creates a discovery config map containing the `hdfs-site.xml` and `core-site.xml` /// for clients. -pub fn build_discovery_configmap( - hdfs: &v1alpha1::HdfsCluster, +/// +/// The rendered content comes entirely from `cluster` (with the externally-resolved +/// `cluster_info` and `namenode_podrefs`); `owner_ref` is retained only for the ConfigMap +/// ObjectMeta / owner reference. +pub fn build_discovery_config_map( + cluster: &ValidatedCluster, cluster_info: &KubernetesClusterInfo, - controller: &str, namenode_podrefs: &[HdfsPodRef], - resolved_product_image: &ResolvedProductImage, + owner_ref: &v1alpha1::HdfsCluster, ) -> Result { let metadata = ObjectMetaBuilder::new() - .name_and_namespace(hdfs) - .ownerreference_from_resource(hdfs, None, Some(true)) + .name_and_namespace(owner_ref) + .ownerreference_from_resource(owner_ref, None, Some(true)) .context(ObjectMissingMetadataForOwnerRefSnafu { - hdfs: ObjectRef::from_obj(hdfs), + hdfs: ObjectRef::from_obj(owner_ref), })? .with_recommended_labels(&build_recommended_labels( - hdfs, - controller, - &resolved_product_image.app_version_label_value, + owner_ref, + HDFS_CONTROLLER_NAME, + &cluster.image.app_version_label_value, &HdfsNodeRole::Name.to_string(), "discovery", )) @@ -69,47 +74,48 @@ pub fn build_discovery_configmap( .metadata(metadata) .add_data( ConfigFileName::HdfsSite.to_string(), - build_discovery_hdfs_site_xml(hdfs, cluster_info, hdfs.name_any(), namenode_podrefs), + build_discovery_hdfs_site_xml(cluster, cluster_info, namenode_podrefs), ) .add_data( ConfigFileName::CoreSite.to_string(), - build_discovery_core_site_xml(hdfs, cluster_info, hdfs.name_any())?, + build_discovery_core_site_xml(cluster, cluster_info)?, ) .build() .context(BuildConfigMapSnafu) } fn build_discovery_hdfs_site_xml( - hdfs: &v1alpha1::HdfsCluster, + cluster: &ValidatedCluster, cluster_info: &KubernetesClusterInfo, - logical_name: String, namenode_podrefs: &[HdfsPodRef], ) -> String { - HdfsSiteConfigBuilder::new(logical_name) + HdfsSiteConfigBuilder::new(cluster.name.as_ref().to_owned()) .dfs_name_services() .dfs_ha_namenodes(namenode_podrefs) .dfs_namenode_rpc_address_ha(cluster_info, namenode_podrefs) - .dfs_namenode_http_address_ha(hdfs.has_https_enabled(), cluster_info, namenode_podrefs) + .dfs_namenode_http_address_ha( + cluster.cluster_config.https_enabled, + cluster_info, + namenode_podrefs, + ) .dfs_client_failover_proxy_provider() - .security_discovery_config(hdfs.has_kerberos_enabled()) + .security_discovery_config(cluster.cluster_config.kerberos_enabled) .build_as_xml() } fn build_discovery_core_site_xml( - hdfs: &v1alpha1::HdfsCluster, + cluster: &ValidatedCluster, cluster_info: &KubernetesClusterInfo, - logical_name: String, ) -> Result { - let cluster_name = hdfs.name_any(); - let cluster_namespace = hdfs.namespace(); + let cluster_config = &cluster.cluster_config; let kerberos = KerberosConfig { - cluster_name: &cluster_name, - cluster_namespace: cluster_namespace.as_deref(), - authentication_enabled: hdfs.authentication_config().is_some(), - kerberos_enabled: hdfs.has_kerberos_enabled(), - authorization_enabled: hdfs.has_authorization_enabled(), + cluster_name: cluster.name.as_ref(), + cluster_namespace: cluster.namespace.as_deref(), + authentication_enabled: cluster_config.authentication_enabled, + kerberos_enabled: cluster_config.kerberos_enabled, + authorization_enabled: cluster_config.authorization_enabled, }; - Ok(CoreSiteConfigBuilder::new(logical_name) + Ok(CoreSiteConfigBuilder::new(cluster.name.as_ref().to_owned()) .fs_default_fs() .security_discovery_config(&kerberos, cluster_info) .context(BuildSecurityDiscoveryConfigMapSnafu)? diff --git a/rust/operator-binary/src/controller/build/mod.rs b/rust/operator-binary/src/controller/build/mod.rs index 933a20b9..4a7bba72 100644 --- a/rust/operator-binary/src/controller/build/mod.rs +++ b/rust/operator-binary/src/controller/build/mod.rs @@ -1,2 +1,3 @@ pub mod config_map; +pub mod discovery; pub mod 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 index b263b181..88bc229f 100644 --- a/rust/operator-binary/src/controller/build/properties/core_site.rs +++ b/rust/operator-binary/src/controller/build/properties/core_site.rs @@ -32,7 +32,7 @@ pub fn build( let cluster_config = &cluster.cluster_config; let kerberos = KerberosConfig { cluster_name: cluster.name.as_ref(), - cluster_namespace: cluster_config.namespace.as_deref(), + cluster_namespace: cluster.namespace.as_deref(), authentication_enabled: cluster_config.authentication_enabled, kerberos_enabled: cluster_config.kerberos_enabled, authorization_enabled: cluster_config.authorization_enabled, diff --git a/rust/operator-binary/src/product_logging.rs b/rust/operator-binary/src/controller/build/properties/logging.rs similarity index 65% rename from rust/operator-binary/src/product_logging.rs rename to rust/operator-binary/src/controller/build/properties/logging.rs index c4054c14..6c493f26 100644 --- a/rust/operator-binary/src/product_logging.rs +++ b/rust/operator-binary/src/controller/build/properties/logging.rs @@ -1,8 +1,8 @@ +//! Builds the log4j and Vector logging configuration for the rolegroup `ConfigMap`. + use std::{borrow::Cow, fmt::Display}; -use snafu::Snafu; use stackable_operator::{ - builder::configmap::ConfigMapBuilder, memory::{BinaryMultiple, MemoryQuantity}, product_logging::{ self, @@ -13,26 +13,6 @@ use stackable_operator::{ use crate::crd::{AnyNodeConfig, DataNodeContainer, NameNodeContainer, 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, - }, -} - -type Result = std::result::Result; - pub const STACKABLE_LOG_DIR: &str = "/stackable/log"; // We have a maximum of 4 continuous logging files for Namenodes. Datanodes and Journalnodes // require less. @@ -75,41 +55,16 @@ const FORMAT_NAMENODES_LOG_FILE: &str = "format-namenodes.log4j.xml"; const FORMAT_ZOOKEEPER_LOG_FILE: &str = "format-zookeeper.log4j.xml"; const WAIT_FOR_NAMENODES_LOG_FILE: &str = "wait-for-namenodes.log4j.xml"; -/// Extend the role group ConfigMap with logging and Vector configurations -pub fn extend_role_group_config_map( - rolegroup: &RoleGroupRef, - merged_config: &AnyNodeConfig, - cm_builder: &mut ConfigMapBuilder, -) -> Result<()> { - fn add_log4j_config_if_automatic( - cm_builder: &mut ConfigMapBuilder, - log_config: Option>, - log_config_file: &str, - container_name: impl Display, - log_file: &str, - max_log_file_size: MemoryQuantity, - ) { - if let Some(ContainerLogConfig { - choice: Some(ContainerLogConfigChoice::Automatic(log_config)), - }) = log_config.as_deref() - { - cm_builder.add_data( - log_config_file, - product_logging::framework::create_log4j_config( - &format!("{STACKABLE_LOG_DIR}/{container_name}"), - log_file, - max_log_file_size - .scale_to(BinaryMultiple::Mebi) - .floor() - .value as u32, - CONSOLE_CONVERSION_PATTERN, - log_config, - ), - ); - } - } +/// Renders the `*.log4j.properties` files for every container of this role group that uses the +/// operator's automatic logging configuration. +/// +/// Returns `(filename, rendered content)` pairs; containers using a custom log ConfigMap are +/// skipped, so the result is empty when none use automatic logging. +pub fn build_log4j_configs(merged_config: &AnyNodeConfig) -> Vec<(&'static str, String)> { + let mut configs = Vec::new(); + add_log4j_config_if_automatic( - cm_builder, + &mut configs, Some(merged_config.hdfs_logging()), HDFS_LOG4J_CONFIG_FILE, "hdfs", @@ -117,7 +72,7 @@ pub fn extend_role_group_config_map( MAX_HDFS_LOG_FILE_SIZE, ); add_log4j_config_if_automatic( - cm_builder, + &mut configs, merged_config .as_namenode() .map(|nn| nn.logging.for_container(&NameNodeContainer::Zkfc)), @@ -127,7 +82,7 @@ pub fn extend_role_group_config_map( MAX_ZKFC_LOG_FILE_SIZE, ); add_log4j_config_if_automatic( - cm_builder, + &mut configs, merged_config.as_namenode().map(|nn| { nn.logging .for_container(&NameNodeContainer::FormatNameNodes) @@ -138,7 +93,7 @@ pub fn extend_role_group_config_map( MAX_FORMAT_NAMENODE_LOG_FILE_SIZE, ); add_log4j_config_if_automatic( - cm_builder, + &mut configs, merged_config.as_namenode().map(|nn| { nn.logging .for_container(&NameNodeContainer::FormatZooKeeper) @@ -149,7 +104,7 @@ pub fn extend_role_group_config_map( MAX_FORMAT_ZOOKEEPER_LOG_FILE_SIZE, ); add_log4j_config_if_automatic( - cm_builder, + &mut configs, merged_config.as_datanode().map(|dn| { dn.logging .for_container(&DataNodeContainer::WaitForNameNodes) @@ -160,6 +115,48 @@ pub fn extend_role_group_config_map( MAX_WAIT_NAMENODES_LOG_FILE_SIZE, ); + configs +} + +fn add_log4j_config_if_automatic( + configs: &mut Vec<(&'static str, String)>, + log_config: Option>, + log_config_file: &'static str, + container_name: impl Display, + log_file: &str, + max_log_file_size: MemoryQuantity, +) { + if let Some(ContainerLogConfig { + choice: Some(ContainerLogConfigChoice::Automatic(log_config)), + }) = log_config.as_deref() + { + configs.push(( + log_config_file, + product_logging::framework::create_log4j_config( + &format!("{STACKABLE_LOG_DIR}/{container_name}"), + log_file, + max_log_file_size + .scale_to(BinaryMultiple::Mebi) + .floor() + .value as u32, + CONSOLE_CONVERSION_PATTERN, + log_config, + ), + )); + } +} + +/// 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, + merged_config: &AnyNodeConfig, +) -> Option { + if !merged_config.vector_logging_enabled() { + return None; + } + let vector_log_config = merged_config.vector_logging(); let vector_log_config = if let ContainerLogConfig { choice: Some(ContainerLogConfigChoice::Automatic(log_config)), @@ -170,12 +167,8 @@ pub fn extend_role_group_config_map( None }; - if merged_config.vector_logging_enabled() { - cm_builder.add_data( - product_logging::framework::VECTOR_CONFIG_FILE, - product_logging::framework::create_vector_config(rolegroup, vector_log_config), - ); - } - - Ok(()) + Some(product_logging::framework::create_vector_config( + rolegroup, + vector_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 61849ad7..7b5d6deb 100644 --- a/rust/operator-binary/src/controller/build/properties/mod.rs +++ b/rust/operator-binary/src/controller/build/properties/mod.rs @@ -10,6 +10,7 @@ use stackable_operator::v2::config_overrides::KeyValueConfigOverrides; pub mod core_site; pub mod hadoop_policy; pub mod hdfs_site; +pub mod logging; pub mod security_properties; pub mod ssl_client; pub mod ssl_server; diff --git a/rust/operator-binary/src/controller/validate.rs b/rust/operator-binary/src/controller/validate.rs index 0731cb72..b44bb9d7 100644 --- a/rust/operator-binary/src/controller/validate.rs +++ b/rust/operator-binary/src/controller/validate.rs @@ -114,6 +114,7 @@ pub fn validate_cluster( Ok(ValidatedCluster { name: ClusterName::from_str(&hdfs.name_any()).context(InvalidClusterNameSnafu)?, + namespace: hdfs.namespace(), image: resolved_product_image, cluster_config: ValidatedClusterConfig::resolve(hdfs, hdfs_opa_config), role_groups, diff --git a/rust/operator-binary/src/hdfs_controller.rs b/rust/operator-binary/src/hdfs_controller.rs index d9361430..93aa6fb9 100644 --- a/rust/operator-binary/src/hdfs_controller.rs +++ b/rust/operator-binary/src/hdfs_controller.rs @@ -45,11 +45,11 @@ use strum::{EnumDiscriminants, IntoEnumIterator, IntoStaticStr}; use crate::{ OPERATOR_NAME, build_recommended_labels, container::{self, ContainerConfig}, + controller::build::discovery::{self, build_discovery_config_map}, crd::{ AnyNodeConfig, HdfsClusterStatus, HdfsNodeRole, HdfsPodRef, UpgradeState, UpgradeStateError, constants::*, v1alpha1, }, - discovery::{self, build_discovery_configmap}, event::{build_invalid_replica_message, publish_warning_event}, operations::{ graceful_shutdown::{self, add_graceful_shutdown_config}, @@ -60,7 +60,7 @@ use crate::{ }; pub const RESOURCE_MANAGER_HDFS_CONTROLLER: &str = "hdfs-operator-hdfs-controller"; -const HDFS_CONTROLLER_NAME: &str = "hdfs-controller"; +pub const HDFS_CONTROLLER_NAME: &str = "hdfs-controller"; pub const HDFS_FULL_CONTROLLER_NAME: &str = concatcp!(HDFS_CONTROLLER_NAME, '.', OPERATOR_NAME); pub const CONTAINER_IMAGE_BASE_NAME: &str = "hadoop"; @@ -73,6 +73,8 @@ pub const CONTAINER_IMAGE_BASE_NAME: &str = "hadoop"; pub struct ValidatedCluster { /// The logical (and Kubernetes object) name of the cluster. pub name: ClusterName, + /// The cluster namespace, used to build kerberos principals. + pub namespace: Option, pub image: ResolvedProductImage, pub cluster_config: ValidatedClusterConfig, pub role_groups: BTreeMap>, @@ -90,8 +92,6 @@ pub struct ValidatedCluster { /// the same `HdfsCluster` predicates used previously, just resolved up-front. #[derive(Clone, Debug)] pub struct ValidatedClusterConfig { - /// The cluster namespace, used to build kerberos principals. - pub namespace: Option, pub dfs_replication: u8, pub https_enabled: bool, pub kerberos_enabled: bool, @@ -107,7 +107,6 @@ impl ValidatedClusterConfig { authorization: Option, ) -> ValidatedClusterConfig { ValidatedClusterConfig { - namespace: hdfs.namespace(), dfs_replication: hdfs.spec.cluster_config.dfs_replication, https_enabled: hdfs.has_https_enabled(), kerberos_enabled: hdfs.has_kerberos_enabled(), @@ -486,15 +485,14 @@ pub async fn reconcile_hdfs( // Discovery CM will fail to build until the rest of the cluster has been deployed, so do it last // so that failure won't inhibit the rest of the cluster from booting up. - let discovery_cm = build_discovery_configmap( - hdfs, + let discovery_cm = build_discovery_config_map( + &validated, &client.kubernetes_cluster_info, - HDFS_CONTROLLER_NAME, &hdfs .namenode_listener_refs(client) .await .context(CollectDiscoveryConfigSnafu)?, - resolved_product_image, + hdfs, ) .context(BuildDiscoveryConfigMapSnafu)?; diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 8385e61c..90eab18d 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -45,12 +45,10 @@ mod config; mod container; mod controller; mod crd; -mod discovery; mod event; mod hdfs_clusterrolebinding_nodes_controller; mod hdfs_controller; mod operations; -mod product_logging; mod security; mod service; mod webhooks;