diff --git a/CHANGELOG.md b/CHANGELOG.md index d58d2a6d..893ed1a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Changed + +- Rewrite of the OPA bundle builder ([#578]). + +### Fixed + +- Bundle builder should no longer keep serving deleted rules until it is restarted ([#578]). + +[#578]: https://github.com/stackabletech/opa-operator/pull/578 + ## [24.7.0] - 2024-07-24 ### Added diff --git a/Cargo.lock b/Cargo.lock index 9a50c46b..34806ed8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -470,6 +470,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" version = "0.5.13" @@ -550,6 +559,15 @@ dependencies = [ "syn 2.0.70", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derivative" version = "2.2.0" @@ -675,6 +693,28 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fluent-uri" version = "0.1.4" @@ -714,12 +754,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - [[package]] name = "futures" version = "0.3.30" @@ -797,7 +831,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ - "futures 0.1.31", "futures-channel", "futures-core", "futures-io", @@ -1277,7 +1310,7 @@ dependencies = [ "bytes", "chrono", "either", - "futures 0.3.30", + "futures", "home", "http", "http-body", @@ -1347,7 +1380,7 @@ dependencies = [ "async-trait", "backoff", "derivative", - "futures 0.3.30", + "futures", "hashbrown", "json-patch", "jsonptr", @@ -1519,6 +1552,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.19" @@ -1703,7 +1742,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.2", "smallvec", "windows-targets 0.52.6", ] @@ -1807,6 +1846,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1901,6 +1946,15 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.5.2" @@ -2386,6 +2440,22 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "stackable-opa-bundle-builder" +version = "0.0.0-dev" +dependencies = [ + "axum", + "clap", + "flate2", + "futures", + "hyper", + "snafu 0.8.4", + "stackable-operator", + "tar", + "tokio", + "tracing", +] + [[package]] name = "stackable-opa-crd" version = "0.0.0-dev" @@ -2408,7 +2478,7 @@ dependencies = [ "built", "clap", "fnv", - "futures 0.3.30", + "futures", "indoc", "pin-project", "product-config", @@ -2429,7 +2499,7 @@ version = "0.0.0-dev" dependencies = [ "axum", "clap", - "futures 0.3.30", + "futures", "hyper", "moka", "pin-project", @@ -2447,8 +2517,8 @@ dependencies = [ [[package]] name = "stackable-operator" -version = "0.70.0" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.70.0#045af8d77cb91d412bfcdc939e85d98ac77f1029" +version = "0.71.0" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.71.0#d33dce772ca349b046a98fef2fa0b94a0d1db916" dependencies = [ "chrono", "clap", @@ -2457,7 +2527,7 @@ dependencies = [ "derivative", "dockerfile-parser", "either", - "futures 0.3.30", + "futures", "json-patch", "k8s-openapi", "kube", @@ -2476,6 +2546,7 @@ dependencies = [ "strum", "tokio", "tracing", + "tracing-appender", "tracing-opentelemetry", "tracing-subscriber", "url", @@ -2484,7 +2555,7 @@ dependencies = [ [[package]] name = "stackable-operator-derive" version = "0.3.1" -source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.70.0#045af8d77cb91d412bfcdc939e85d98ac77f1029" +source = "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.71.0#d33dce772ca349b046a98fef2fa0b94a0d1db916" dependencies = [ "darling", "proc-macro2", @@ -2587,6 +2658,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" +[[package]] +name = "tar" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "tempfile" version = "3.10.1" @@ -2651,6 +2733,37 @@ dependencies = [ "threadpool", ] +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -2802,6 +2915,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" version = "0.1.27" @@ -2852,6 +2977,16 @@ dependencies = [ "web-time", ] +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.18" @@ -2862,12 +2997,15 @@ dependencies = [ "nu-ansi-term", "once_cell", "regex", + "serde", + "serde_json", "sharded-slab", "smallvec", "thread_local", "tracing", "tracing-core", "tracing-log", + "tracing-serde", ] [[package]] @@ -3259,6 +3397,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys", + "rustix", +] + [[package]] name = "xml-rs" version = "0.8.20" diff --git a/Cargo.nix b/Cargo.nix index 3476fcb0..6f2244f4 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -35,6 +35,16 @@ rec { # You can override the features with # workspaceMembers."${crateName}".build.override { features = [ "default" "feature1" ... ]; }. workspaceMembers = { + "stackable-opa-bundle-builder" = rec { + packageId = "stackable-opa-bundle-builder"; + build = internal.buildRustCrateWithFeatures { + packageId = "stackable-opa-bundle-builder"; + }; + + # Debug support which might change between releases. + # File a bug if you depend on any for non-debug work! + debug = internal.debugCrate { inherit packageId; }; + }; "stackable-opa-crd" = rec { packageId = "stackable-opa-crd"; build = internal.buildRustCrateWithFeatures { @@ -1485,6 +1495,26 @@ rec { ]; }; + "crc32fast" = rec { + crateName = "crc32fast"; + version = "1.4.2"; + edition = "2015"; + sha256 = "1czp7vif73b8xslr3c9yxysmh9ws2r8824qda7j47ffs9pcnjxx9"; + authors = [ + "Sam Rijs " + "Alex Crichton " + ]; + dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; + } + ]; + features = { + "default" = [ "std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "crossbeam-channel" = rec { crateName = "crossbeam-channel"; version = "0.5.13"; @@ -1683,6 +1713,33 @@ rec { ]; }; + "deranged" = rec { + crateName = "deranged"; + version = "0.3.11"; + edition = "2021"; + sha256 = "1d1ibqqnr5qdrpw8rclwrf1myn3wf0dygl04idf4j2s49ah6yaxl"; + authors = [ + "Jacob Pratt " + ]; + dependencies = [ + { + name = "powerfmt"; + packageId = "powerfmt"; + optional = true; + usesDefaultFeatures = false; + } + ]; + features = { + "default" = [ "std" ]; + "num" = [ "dep:num-traits" ]; + "powerfmt" = [ "dep:powerfmt" ]; + "quickcheck" = [ "dep:quickcheck" "alloc" ]; + "rand" = [ "dep:rand" ]; + "serde" = [ "dep:serde" ]; + "std" = [ "alloc" ]; + }; + resolvedDefaultFeatures = [ "alloc" "powerfmt" "std" ]; + }; "derivative" = rec { crateName = "derivative"; version = "2.2.0"; @@ -2020,6 +2077,86 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" "std" ]; }; + "filetime" = rec { + crateName = "filetime"; + version = "0.2.23"; + edition = "2018"; + sha256 = "1za0sbq7fqidk8aaq9v7m9ms0sv8mmi49g6p5cphpan819q4gr0y"; + authors = [ + "Alex Crichton " + ]; + dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "libc"; + packageId = "libc"; + target = { target, features }: (target."unix" or false); + } + { + name = "redox_syscall"; + packageId = "redox_syscall 0.4.1"; + target = { target, features }: ("redox" == target."os" or null); + } + { + name = "windows-sys"; + packageId = "windows-sys 0.52.0"; + target = { target, features }: (target."windows" or false); + features = [ "Win32_Foundation" "Win32_Storage_FileSystem" ]; + } + ]; + + }; + "flate2" = rec { + crateName = "flate2"; + version = "1.0.30"; + edition = "2018"; + sha256 = "1bjx56n0wq5w7vsjn7b5rbmqiw0vc3mfzz1rl7i2jy0wzmy44m2z"; + authors = [ + "Alex Crichton " + "Josh Triplett " + ]; + dependencies = [ + { + name = "crc32fast"; + packageId = "crc32fast"; + } + { + name = "miniz_oxide"; + packageId = "miniz_oxide"; + optional = true; + usesDefaultFeatures = false; + features = [ "with-alloc" ]; + } + { + name = "miniz_oxide"; + packageId = "miniz_oxide"; + usesDefaultFeatures = false; + target = { target, features }: (("wasm32" == target."arch" or null) && (!("emscripten" == target."os" or null))); + features = [ "with-alloc" ]; + } + ]; + features = { + "any_zlib" = [ "any_impl" ]; + "cloudflare-zlib-sys" = [ "dep:cloudflare-zlib-sys" ]; + "cloudflare_zlib" = [ "any_zlib" "cloudflare-zlib-sys" ]; + "default" = [ "rust_backend" ]; + "libz-ng-sys" = [ "dep:libz-ng-sys" ]; + "libz-rs-sys" = [ "dep:libz-rs-sys" ]; + "libz-sys" = [ "dep:libz-sys" ]; + "miniz-sys" = [ "rust_backend" ]; + "miniz_oxide" = [ "dep:miniz_oxide" ]; + "rust_backend" = [ "miniz_oxide" "any_impl" ]; + "zlib" = [ "any_zlib" "libz-sys" ]; + "zlib-default" = [ "any_zlib" "libz-sys/default" ]; + "zlib-ng" = [ "any_zlib" "libz-ng-sys" ]; + "zlib-ng-compat" = [ "zlib" "libz-sys/zlib-ng" ]; + "zlib-rs" = [ "any_zlib" "libz-rs-sys" ]; + }; + resolvedDefaultFeatures = [ "any_impl" "default" "miniz_oxide" "rust_backend" ]; + }; "fluent-uri" = rec { crateName = "fluent-uri"; version = "0.1.4"; @@ -2104,20 +2241,7 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" "std" ]; }; - "futures 0.1.31" = rec { - crateName = "futures"; - version = "0.1.31"; - edition = "2015"; - sha256 = "0y46qbmhi37dqkch8dlfq5aninqpzqgrr98awkb3rn4fxww1lirs"; - authors = [ - "Alex Crichton " - ]; - features = { - "default" = [ "use_std" "with-deprecated" ]; - }; - resolvedDefaultFeatures = [ "default" "use_std" "with-deprecated" ]; - }; - "futures 0.3.30" = rec { + "futures" = rec { crateName = "futures"; version = "0.3.30"; edition = "2018"; @@ -2176,7 +2300,7 @@ rec { "unstable" = [ "futures-core/unstable" "futures-task/unstable" "futures-channel/unstable" "futures-io/unstable" "futures-util/unstable" ]; "write-all-vectored" = [ "futures-util/write-all-vectored" ]; }; - resolvedDefaultFeatures = [ "alloc" "async-await" "compat" "default" "executor" "futures-executor" "std" ]; + resolvedDefaultFeatures = [ "alloc" "async-await" "default" "executor" "futures-executor" "std" ]; }; "futures-channel" = rec { crateName = "futures-channel"; @@ -2316,12 +2440,6 @@ rec { sha256 = "0j0xqhcir1zf2dcbpd421kgw6wvsk0rpxflylcysn1rlp3g02r1x"; libName = "futures_util"; dependencies = [ - { - name = "futures"; - packageId = "futures 0.1.31"; - rename = "futures_01"; - optional = true; - } { name = "futures-channel"; packageId = "futures-channel"; @@ -2399,7 +2517,7 @@ rec { "unstable" = [ "futures-core/unstable" "futures-task/unstable" ]; "write-all-vectored" = [ "io" ]; }; - resolvedDefaultFeatures = [ "alloc" "async-await" "async-await-macro" "channel" "compat" "default" "futures-channel" "futures-io" "futures-macro" "futures-sink" "futures_01" "io" "memchr" "sink" "slab" "std" ]; + resolvedDefaultFeatures = [ "alloc" "async-await" "async-await-macro" "channel" "default" "futures-channel" "futures-io" "futures-macro" "futures-sink" "io" "memchr" "sink" "slab" "std" ]; }; "generic-array" = rec { crateName = "generic-array"; @@ -3920,7 +4038,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures"; optional = true; usesDefaultFeatures = false; features = [ "std" ]; @@ -4061,7 +4179,7 @@ rec { devDependencies = [ { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures"; usesDefaultFeatures = false; features = [ "async-await" ]; } @@ -4274,7 +4392,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures"; usesDefaultFeatures = false; features = [ "async-await" ]; } @@ -4487,7 +4605,7 @@ rec { "default" = [ "std" "general" "errno" ]; "rustc-dep-of-std" = [ "core" "compiler_builtins" "no_std" ]; }; - resolvedDefaultFeatures = [ "elf" "errno" "general" "ioctl" "no_std" ]; + resolvedDefaultFeatures = [ "elf" "errno" "general" "ioctl" "no_std" "std" ]; }; "lock_api" = rec { crateName = "lock_api"; @@ -4623,6 +4741,7 @@ rec { "simd" = [ "simd-adler32" ]; "simd-adler32" = [ "dep:simd-adler32" ]; }; + resolvedDefaultFeatures = [ "with-alloc" ]; }; "mio" = rec { crateName = "mio"; @@ -4855,6 +4974,17 @@ rec { "serde" = [ "dep:serde" ]; }; }; + "num-conv" = rec { + crateName = "num-conv"; + version = "0.1.0"; + edition = "2021"; + sha256 = "1ndiyg82q73783jq18isi71a7mjh56wxrk52rlvyx0mi5z9ibmai"; + libName = "num_conv"; + authors = [ + "Jacob Pratt " + ]; + + }; "num-traits" = rec { crateName = "num-traits"; version = "0.2.19"; @@ -5455,7 +5585,7 @@ rec { } { name = "redox_syscall"; - packageId = "redox_syscall"; + packageId = "redox_syscall 0.5.2"; target = { target, features }: ("redox" == target."os" or null); } { @@ -5718,6 +5848,20 @@ rec { ]; }; + "powerfmt" = rec { + crateName = "powerfmt"; + version = "0.2.0"; + edition = "2021"; + sha256 = "14ckj2xdpkhv3h6l5sdmb9f1d57z8hbfpdldjc2vl5givq2y77j3"; + authors = [ + "Jacob Pratt " + ]; + features = { + "default" = [ "std" "macros" ]; + "macros" = [ "dep:powerfmt-macros" ]; + "std" = [ "alloc" ]; + }; + }; "ppv-lite86" = rec { crateName = "ppv-lite86"; version = "0.2.17"; @@ -6011,7 +6155,27 @@ rec { "termimad" = [ "dep:termimad" ]; }; }; - "redox_syscall" = rec { + "redox_syscall 0.4.1" = rec { + crateName = "redox_syscall"; + version = "0.4.1"; + edition = "2018"; + sha256 = "1aiifyz5dnybfvkk4cdab9p2kmphag1yad6iknc7aszlxxldf8j7"; + libName = "syscall"; + authors = [ + "Jeremy Soller " + ]; + dependencies = [ + { + name = "bitflags"; + packageId = "bitflags 1.3.2"; + } + ]; + features = { + "core" = [ "dep:core" ]; + "rustc-dep-of-std" = [ "core" "bitflags/rustc-dep-of-std" ]; + }; + }; + "redox_syscall 0.5.2" = rec { crateName = "redox_syscall"; version = "0.5.2"; edition = "2018"; @@ -7703,6 +7867,70 @@ rec { }; resolvedDefaultFeatures = [ "once" ]; }; + "stackable-opa-bundle-builder" = rec { + crateName = "stackable-opa-bundle-builder"; + version = "0.0.0-dev"; + edition = "2021"; + crateBin = [ + { + name = "stackable-opa-bundle-builder"; + path = "src/main.rs"; + requiredFeatures = [ ]; + } + ]; + # We can't filter paths with references in Nix 2.4 + # See https://github.com/NixOS/nix/issues/5410 + src = if ((lib.versionOlder builtins.nixVersion "2.4pre20211007") || (lib.versionOlder "2.5" builtins.nixVersion )) + then lib.cleanSourceWith { filter = sourceFilter; src = ./rust/bundle-builder; } + else ./rust/bundle-builder; + authors = [ + "Stackable GmbH " + ]; + dependencies = [ + { + name = "axum"; + packageId = "axum"; + } + { + name = "clap"; + packageId = "clap"; + } + { + name = "flate2"; + packageId = "flate2"; + } + { + name = "futures"; + packageId = "futures"; + } + { + name = "hyper"; + packageId = "hyper"; + } + { + name = "snafu"; + packageId = "snafu 0.8.4"; + } + { + name = "stackable-operator"; + packageId = "stackable-operator"; + } + { + name = "tar"; + packageId = "tar"; + } + { + name = "tokio"; + packageId = "tokio"; + features = [ "full" ]; + } + { + name = "tracing"; + packageId = "tracing"; + } + ]; + + }; "stackable-opa-crd" = rec { crateName = "stackable-opa-crd"; version = "0.0.0-dev"; @@ -7788,8 +8016,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; - features = [ "compat" ]; + packageId = "futures"; } { name = "indoc"; @@ -7882,8 +8109,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; - features = [ "compat" ]; + packageId = "futures"; } { name = "hyper"; @@ -7946,13 +8172,13 @@ rec { }; "stackable-operator" = rec { crateName = "stackable-operator"; - version = "0.70.0"; + version = "0.71.0"; edition = "2021"; workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "045af8d77cb91d412bfcdc939e85d98ac77f1029"; - sha256 = "1z4pa8xsh5hlnjizx37y0wv50dm943q1gj78madqzasssr8l8rwa"; + rev = "d33dce772ca349b046a98fef2fa0b94a0d1db916"; + sha256 = "0bcpkqy8707yddjcwk5hbzpzjkqrknizvi9mxxjh52vzp6r583hk"; }; libName = "stackable_operator"; authors = [ @@ -7991,7 +8217,7 @@ rec { } { name = "futures"; - packageId = "futures 0.3.30"; + packageId = "futures"; } { name = "json-patch"; @@ -8075,6 +8301,10 @@ rec { name = "tracing"; packageId = "tracing"; } + { + name = "tracing-appender"; + packageId = "tracing-appender"; + } { name = "tracing-opentelemetry"; packageId = "tracing-opentelemetry"; @@ -8082,7 +8312,7 @@ rec { { name = "tracing-subscriber"; packageId = "tracing-subscriber"; - features = [ "env-filter" ]; + features = [ "env-filter" "json" ]; } { name = "url"; @@ -8101,8 +8331,8 @@ rec { workspace_member = null; src = pkgs.fetchgit { url = "https://github.com/stackabletech/operator-rs.git"; - rev = "045af8d77cb91d412bfcdc939e85d98ac77f1029"; - sha256 = "1z4pa8xsh5hlnjizx37y0wv50dm943q1gj78madqzasssr8l8rwa"; + rev = "d33dce772ca349b046a98fef2fa0b94a0d1db916"; + sha256 = "0bcpkqy8707yddjcwk5hbzpzjkqrknizvi9mxxjh52vzp6r583hk"; }; procMacro = true; libName = "stackable_operator_derive"; @@ -8365,6 +8595,37 @@ rec { ]; }; + "tar" = rec { + crateName = "tar"; + version = "0.4.41"; + edition = "2021"; + sha256 = "02a9wksw2ci87461czsn0vpvb0wlb152yw4ya77nzdxmbynpsyfb"; + authors = [ + "Alex Crichton " + ]; + dependencies = [ + { + name = "filetime"; + packageId = "filetime"; + } + { + name = "libc"; + packageId = "libc"; + target = { target, features }: (target."unix" or false); + } + { + name = "xattr"; + packageId = "xattr"; + optional = true; + target = { target, features }: (target."unix" or false); + } + ]; + features = { + "default" = [ "xattr" ]; + "xattr" = [ "dep:xattr" ]; + }; + resolvedDefaultFeatures = [ "default" "xattr" ]; + }; "tempfile" = rec { crateName = "tempfile"; version = "3.10.1"; @@ -8522,6 +8783,123 @@ rec { }; resolvedDefaultFeatures = [ "default" "log" "server" "threadpool" ]; }; + "time" = rec { + crateName = "time"; + version = "0.3.36"; + edition = "2021"; + sha256 = "11g8hdpahgrf1wwl2rpsg5nxq3aj7ri6xr672v4qcij6cgjqizax"; + authors = [ + "Jacob Pratt " + "Time contributors" + ]; + dependencies = [ + { + name = "deranged"; + packageId = "deranged"; + usesDefaultFeatures = false; + features = [ "powerfmt" ]; + } + { + name = "itoa"; + packageId = "itoa"; + optional = true; + } + { + name = "num-conv"; + packageId = "num-conv"; + } + { + name = "powerfmt"; + packageId = "powerfmt"; + usesDefaultFeatures = false; + } + { + name = "serde"; + packageId = "serde"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "time-core"; + packageId = "time-core"; + } + { + name = "time-macros"; + packageId = "time-macros"; + optional = true; + } + ]; + devDependencies = [ + { + name = "num-conv"; + packageId = "num-conv"; + } + { + name = "serde"; + packageId = "serde"; + usesDefaultFeatures = false; + features = [ "derive" ]; + } + { + name = "time-macros"; + packageId = "time-macros"; + } + ]; + features = { + "alloc" = [ "serde?/alloc" ]; + "default" = [ "std" ]; + "formatting" = [ "dep:itoa" "std" "time-macros?/formatting" ]; + "large-dates" = [ "time-macros?/large-dates" ]; + "local-offset" = [ "std" "dep:libc" "dep:num_threads" ]; + "macros" = [ "dep:time-macros" ]; + "parsing" = [ "time-macros?/parsing" ]; + "quickcheck" = [ "dep:quickcheck" "alloc" "deranged/quickcheck" ]; + "rand" = [ "dep:rand" "deranged/rand" ]; + "serde" = [ "dep:serde" "time-macros?/serde" "deranged/serde" ]; + "serde-human-readable" = [ "serde" "formatting" "parsing" ]; + "serde-well-known" = [ "serde" "formatting" "parsing" ]; + "std" = [ "alloc" "deranged/std" ]; + "wasm-bindgen" = [ "dep:js-sys" ]; + }; + resolvedDefaultFeatures = [ "alloc" "formatting" "parsing" "std" ]; + }; + "time-core" = rec { + crateName = "time-core"; + version = "0.1.2"; + edition = "2021"; + sha256 = "1wx3qizcihw6z151hywfzzyd1y5dl804ydyxci6qm07vbakpr4pg"; + libName = "time_core"; + authors = [ + "Jacob Pratt " + "Time contributors" + ]; + + }; + "time-macros" = rec { + crateName = "time-macros"; + version = "0.2.18"; + edition = "2021"; + sha256 = "1kqwxvfh2jkpg38fy673d6danh1bhcmmbsmffww3mphgail2l99z"; + procMacro = true; + libName = "time_macros"; + authors = [ + "Jacob Pratt " + "Time contributors" + ]; + dependencies = [ + { + name = "num-conv"; + packageId = "num-conv"; + } + { + name = "time-core"; + packageId = "time-core"; + } + ]; + features = { + }; + resolvedDefaultFeatures = [ "formatting" "parsing" ]; + }; "tinyvec" = rec { crateName = "tinyvec"; version = "1.8.0"; @@ -9149,6 +9527,42 @@ rec { }; resolvedDefaultFeatures = [ "attributes" "default" "log" "std" "tracing-attributes" ]; }; + "tracing-appender" = rec { + crateName = "tracing-appender"; + version = "0.2.3"; + edition = "2018"; + sha256 = "1kq69qyjvb4dxch5c9zgii6cqhy9nkk81z0r4pj3y2nc537fhrim"; + libName = "tracing_appender"; + authors = [ + "Zeki Sherif " + "Tokio Contributors " + ]; + dependencies = [ + { + name = "crossbeam-channel"; + packageId = "crossbeam-channel"; + } + { + name = "thiserror"; + packageId = "thiserror"; + } + { + name = "time"; + packageId = "time"; + usesDefaultFeatures = false; + features = [ "formatting" "parsing" ]; + } + { + name = "tracing-subscriber"; + packageId = "tracing-subscriber"; + usesDefaultFeatures = false; + features = [ "fmt" "std" ]; + } + ]; + features = { + "parking_lot" = [ "dep:parking_lot" ]; + }; + }; "tracing-attributes" = rec { crateName = "tracing-attributes"; version = "0.1.27"; @@ -9341,6 +9755,31 @@ rec { }; resolvedDefaultFeatures = [ "default" "metrics" "smallvec" "tracing-log" ]; }; + "tracing-serde" = rec { + crateName = "tracing-serde"; + version = "0.1.3"; + edition = "2018"; + sha256 = "1qfr0va69djvxqvjrx4vqq7p6myy414lx4w1f6amcn0hfwqj2sxw"; + libName = "tracing_serde"; + authors = [ + "Tokio Contributors " + ]; + dependencies = [ + { + name = "serde"; + packageId = "serde"; + } + { + name = "tracing-core"; + packageId = "tracing-core"; + } + ]; + features = { + "valuable" = [ "valuable_crate" "valuable-serde" "tracing-core/valuable" ]; + "valuable-serde" = [ "dep:valuable-serde" ]; + "valuable_crate" = [ "dep:valuable_crate" ]; + }; + }; "tracing-subscriber" = rec { crateName = "tracing-subscriber"; version = "0.3.18"; @@ -9375,6 +9814,16 @@ rec { usesDefaultFeatures = false; features = [ "std" "unicode-case" "unicode-perl" ]; } + { + name = "serde"; + packageId = "serde"; + optional = true; + } + { + name = "serde_json"; + packageId = "serde_json"; + optional = true; + } { name = "sharded-slab"; packageId = "sharded-slab"; @@ -9408,6 +9857,11 @@ rec { usesDefaultFeatures = false; features = [ "log-tracer" "std" ]; } + { + name = "tracing-serde"; + packageId = "tracing-serde"; + optional = true; + } ]; devDependencies = [ { @@ -9453,7 +9907,7 @@ rec { "valuable-serde" = [ "dep:valuable-serde" ]; "valuable_crate" = [ "dep:valuable_crate" ]; }; - resolvedDefaultFeatures = [ "alloc" "ansi" "default" "env-filter" "fmt" "matchers" "nu-ansi-term" "once_cell" "regex" "registry" "sharded-slab" "smallvec" "std" "thread_local" "tracing" "tracing-log" ]; + resolvedDefaultFeatures = [ "alloc" "ansi" "default" "env-filter" "fmt" "json" "matchers" "nu-ansi-term" "once_cell" "regex" "registry" "serde" "serde_json" "sharded-slab" "smallvec" "std" "thread_local" "tracing" "tracing-log" "tracing-serde" ]; }; "triomphe" = rec { crateName = "triomphe"; @@ -11325,6 +11779,47 @@ rec { "serialization-serde" = [ "transactions" "serde" ]; }; }; + "xattr" = rec { + crateName = "xattr"; + version = "1.3.1"; + edition = "2021"; + sha256 = "0kqxm36w89vc6qcpn6pizlhgjgzq138sx4hdhbv2g6wk4ld4za4d"; + authors = [ + "Steven Allen " + ]; + dependencies = [ + { + name = "libc"; + packageId = "libc"; + target = { target, features }: (("freebsd" == target."os" or null) || ("netbsd" == target."os" or null)); + } + { + name = "linux-raw-sys"; + packageId = "linux-raw-sys"; + usesDefaultFeatures = false; + target = { target, features }: ("linux" == target."os" or null); + features = [ "std" ]; + } + { + name = "rustix"; + packageId = "rustix"; + usesDefaultFeatures = false; + features = [ "fs" "std" ]; + } + ]; + devDependencies = [ + { + name = "rustix"; + packageId = "rustix"; + usesDefaultFeatures = false; + features = [ "net" ]; + } + ]; + features = { + "default" = [ "unsupported" ]; + }; + resolvedDefaultFeatures = [ "default" "unsupported" ]; + }; "xml-rs" = rec { crateName = "xml-rs"; version = "0.8.20"; diff --git a/Cargo.toml b/Cargo.toml index 47f0156c..45442a32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["rust/crd", "rust/operator-binary", "rust/user-info-fetcher"] +members = ["rust/*"] resolver = "2" [workspace.package] @@ -15,8 +15,9 @@ axum = "0.7" built = { version ="0.7", features = ["chrono", "git2"] } clap = "4.5" derivative = "2.2" +flate2 = "1.0" fnv = "1.0" -futures = { version = "0.3", features = ["compat"] } +futures = { version = "0.3" } hyper = "1.3" indoc = "2.0" moka = { version = "0.12", features = ["future"] } @@ -27,11 +28,13 @@ semver = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" snafu = "0.8" -stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.70.0" } +stackable-operator = { git = "https://github.com/stackabletech/operator-rs.git", tag = "stackable-operator-0.71.0" } strum = { version = "0.26", features = ["derive"] } +tar = "0.4" tokio = { version = "1.38", features = ["full"] } tracing = "0.1" url = "2.4" # [patch."https://github.com/stackabletech/operator-rs.git"] # stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" } +# stackable-operator = { path = "../operator-rs/crates/stackable-operator" } diff --git a/crate-hashes.json b/crate-hashes.json index 47279266..b87bddb0 100644 --- a/crate-hashes.json +++ b/crate-hashes.json @@ -1,5 +1,5 @@ { - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.70.0#stackable-operator-derive@0.3.1": "1z4pa8xsh5hlnjizx37y0wv50dm943q1gj78madqzasssr8l8rwa", - "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.70.0#stackable-operator@0.70.0": "1z4pa8xsh5hlnjizx37y0wv50dm943q1gj78madqzasssr8l8rwa", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.71.0#stackable-operator-derive@0.3.1": "0bcpkqy8707yddjcwk5hbzpzjkqrknizvi9mxxjh52vzp6r583hk", + "git+https://github.com/stackabletech/operator-rs.git?tag=stackable-operator-0.71.0#stackable-operator@0.71.0": "0bcpkqy8707yddjcwk5hbzpzjkqrknizvi9mxxjh52vzp6r583hk", "git+https://github.com/stackabletech/product-config.git?tag=0.7.0#product-config@0.7.0": "0gjsm80g6r75pm3824dcyiz4ysq1ka4c1if6k1mjm9cnd5ym0gny" } \ No newline at end of file diff --git a/rust/bundle-builder/Cargo.toml b/rust/bundle-builder/Cargo.toml new file mode 100644 index 00000000..99f4bc20 --- /dev/null +++ b/rust/bundle-builder/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "stackable-opa-bundle-builder" +description = "Builds OPA bundles from Kubernetes ConfigMaps" +version.workspace = true +authors.workspace = true +license.workspace = true +edition.workspace = true +repository.workspace = true +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +axum.workspace = true +clap.workspace = true +flate2.workspace = true +futures.workspace = true +hyper.workspace = true +snafu.workspace = true +stackable-operator.workspace = true +tar.workspace = true +tokio.workspace = true +tracing.workspace = true diff --git a/rust/bundle-builder/src/main.rs b/rust/bundle-builder/src/main.rs new file mode 100644 index 00000000..e1170a23 --- /dev/null +++ b/rust/bundle-builder/src/main.rs @@ -0,0 +1,292 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + num::TryFromIntError, + sync::{Arc, Mutex}, +}; + +use axum::{extract::State, http, response::IntoResponse, routing::get, Router}; +use clap::Parser; +use flate2::write::GzEncoder; +use futures::{ + future::{self, BoxFuture}, + pin_mut, FutureExt, StreamExt, TryFutureExt, +}; +use snafu::{ResultExt, Snafu}; +use stackable_operator::{ + k8s_openapi::api::core::v1::ConfigMap, + kube::{ + api::ObjectMeta, + runtime::{ + reflector::{self, ObjectRef, Store}, + watcher, + }, + }, +}; +use tokio::net::TcpListener; + +const OPERATOR_NAME: &str = "opa.stackable.tech"; +pub const APP_NAME: &str = "opa-bundle-builder"; + +#[derive(clap::Parser)] +pub struct Args { + #[clap(flatten)] + common: stackable_operator::cli::ProductOperatorRun, +} + +type Bundle = Vec; +type BundleFuture = future::Shared>>>; + +#[derive(Clone)] +struct AppState { + bundle: Arc>, +} + +#[derive(Snafu, Debug)] +enum StartupError { + #[snafu(display("failed to initialize Kubernetes client"))] + InitKube { + source: stackable_operator::client::Error, + }, + + #[snafu(display("failed to get listener address"))] + GetListenerAddr { source: std::io::Error }, + + #[snafu(display("failed to register SIGTERM handler"))] + RegisterSigterm { source: std::io::Error }, + + #[snafu(display("failed to bind listener"))] + BindListener { source: std::io::Error }, + + #[snafu(display("failed to run server"))] + RunServer { source: std::io::Error }, +} + +#[tokio::main] +async fn main() -> Result<(), StartupError> { + let args = Args::parse(); + + stackable_operator::logging::initialize_logging( + "OPA_BUNDLE_BUILDER_LOG", + APP_NAME, + args.common.tracing_target, + ); + + let client = stackable_operator::client::create_client(None) + .await + .context(InitKubeSnafu)?; + + let (store, store_w) = reflector::store(); + let rebuild_bundle = || { + tracing::info!("bundle invalidated, will be rebuilt on next request"); + // Even if build_bundle is completely synchronous (currently), + // storing a Future acts as a primitive laziness/debouncing mechanism, + // the bundle will only actually be built once it is requested. + build_bundle(store.clone()) + .inspect_err(|error| { + tracing::error!( + error = error as &dyn std::error::Error, + "failed to rebuild bundle" + ) + }) + .map(Arc::from) + .boxed() + .shared() + }; + let bundle = Arc::new(Mutex::new(rebuild_bundle())); + let reflector = std::pin::pin!(reflector::reflector( + store_w, + watcher( + args.common.watch_namespace.get_api::(&client), + watcher::Config::default().labels(&format!("{OPERATOR_NAME}/bundle")), + ), + ) + .for_each(|ev| async { + let rebuild = match ev { + Ok(watcher::Event::Apply(o)) => { + tracing::info!(object = %ObjectRef::from_obj(&o), "saw updated object"); + true + } + Ok(watcher::Event::Delete(o)) => { + tracing::info!(object = %ObjectRef::from_obj(&o), "saw deleted object"); + true + } + Ok(watcher::Event::Init) => { + tracing::info!("restart initiated"); + false + } + Ok(watcher::Event::InitApply(o)) => { + tracing::info!(object = %ObjectRef::from_obj(&o), "saw updated object (waiting for restart to complete before rebuilding)"); + false + } + Ok(watcher::Event::InitDone) => { + tracing::info!("restart done"); + true + } + Err(error) => { + tracing::error!( + error = &error as &dyn std::error::Error, + "failed to update reflector" + ); + false + } + }; + if rebuild { + tracing::info!("rebuilding bundle"); + *bundle.lock().unwrap() = rebuild_bundle(); + } else { + tracing::debug!("change should have no effect, not rebuilding bundle"); + } + }) + .map(Ok)); + + let shutdown_requested = tokio::signal::ctrl_c().map(|_| ()); + #[cfg(unix)] + let shutdown_requested = { + let mut sigterm = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) + .context(RegisterSigtermSnafu)?; + async move { + let sigterm = sigterm.recv().map(|_| ()); + pin_mut!(shutdown_requested, sigterm); + future::select(shutdown_requested, sigterm).await; + } + }; + + let app = Router::new() + .route("/opa/v1/opa/bundle.tar.gz", get(get_bundle)) + .route("/status", get(get_status)) + .with_state(AppState { + bundle: bundle.clone(), + }); + // FIXME: can we restrict access to localhost? + // kubelet probes run from outside the container netns + let listener = TcpListener::bind("0.0.0.0:3030") + .await + .context(BindListenerSnafu)?; + let address = listener.local_addr().context(GetListenerAddrSnafu)?; + tracing::info!(%address, "listening"); + + let server = std::pin::pin!(async { + axum::serve(listener, app.into_make_service()) + .with_graceful_shutdown(shutdown_requested) + .await + .context(RunServerSnafu) + }); + + future::select(reflector, server).await.factor_first().0 +} + +#[derive(Snafu, Debug)] +#[snafu(module)] +enum BundleError { + #[snafu(display("ConfigMap is missing required metadata"))] + ConfigMapMetadataMissing, + + #[snafu(display("file {file_name:?} in {config_map} is too large ({file_size} bytes)"))] + FileSizeOverflow { + source: TryFromIntError, + config_map: ObjectRef, + file_name: String, + file_size: usize, + }, + + #[snafu(display("failed to add file {file_name:?} from {config_map} to tarball"))] + AddFileToTarball { + source: std::io::Error, + config_map: ObjectRef, + file_name: String, + }, + + #[snafu(display("failed to build tarball"))] + BuildTarball { source: std::io::Error }, +} + +impl BundleError { + fn to_http_response(&self) -> impl IntoResponse { + ( + http::StatusCode::INTERNAL_SERVER_ERROR, + "failed to build bundle, see opa-bundle-builder logs for more details", + ) + } +} + +async fn build_bundle(store: Store) -> Result, BundleError> { + use bundle_error::*; + fn file_header( + config_map: &ObjectRef, + file_name: &str, + data: &[u8], + ) -> Result { + let mut header = tar::Header::new_gnu(); + header.set_mode(0o644); + let file_size = data.len(); + header.set_size( + file_size + .try_into() + .with_context(|_| FileSizeOverflowSnafu { + config_map: config_map.clone(), + file_name, + file_size, + })?, + ); + header.set_entry_type(tar::EntryType::Regular); + header.set_cksum(); + Ok(header) + } + + tracing::info!("building bundle"); + let mut tar = tar::Builder::new(GzEncoder::new(Vec::new(), flate2::Compression::default())); + let mut resource_versions = BTreeMap::::new(); + let mut bundle_file_paths = BTreeSet::::new(); + for cm in store.state() { + let ObjectMeta { + name: Some(cm_ns), + namespace: Some(cm_name), + resource_version: Some(cm_version), + .. + } = &cm.metadata + else { + return ConfigMapMetadataMissingSnafu.fail(); + }; + let cm_ref = ObjectRef::from_obj(&*cm); + for (file_name, data) in cm.data.iter().flatten() { + let mut header = file_header(&cm_ref, file_name, data.as_bytes())?; + let file_path = format!("configmap/{cm_ns}/{cm_name}/{file_name}"); + tar.append_data(&mut header, &file_path, data.as_bytes()) + .with_context(|_| AddFileToTarballSnafu { + config_map: cm_ref.clone(), + file_name, + })?; + bundle_file_paths.insert(file_path); + } + resource_versions.insert(cm_ref.to_string(), cm_version.clone()); + } + let tar = tar + .into_inner() + .context(BuildTarballSnafu)? + .finish() + .context(BuildTarballSnafu)?; + tracing::info!(bundle.files = ?bundle_file_paths, bundle.versions = ?resource_versions, "finished building bundle"); + Ok(tar) +} + +async fn get_status(State(state): State) -> impl IntoResponse { + let bundle = future::Shared::clone(&*state.bundle.lock().unwrap()); + if let Err(err) = bundle.await.as_deref() { + return Err(err.to_http_response()); + } + Ok("ready") +} + +async fn get_bundle(State(state): State) -> impl IntoResponse { + let bundle = future::Shared::clone(&*state.bundle.lock().unwrap()); + Ok(( + [( + http::header::CONTENT_TYPE, + http::HeaderValue::from_static("application/gzip"), + )], + match bundle.await.as_deref() { + Ok(bundle) => bundle.to_vec(), + Err(err) => return Err(err.to_http_response()), + }, + )) +} diff --git a/rust/operator-binary/src/controller.rs b/rust/operator-binary/src/controller.rs index d8921f81..a305d13c 100644 --- a/rust/operator-binary/src/controller.rs +++ b/rust/operator-binary/src/controller.rs @@ -104,19 +104,20 @@ const DEFAULT_CONSOLE_LOG_LEVEL: LogLevel = LogLevel::INFO; const DEFAULT_SERVER_LOG_LEVEL: LogLevel = LogLevel::INFO; const DEFAULT_DECISION_LOG_LEVEL: LogLevel = LogLevel::NONE; -// bundle builder: ~ 5 MB x 2 -// these sizes are needed both for the single file (for multilog, in bytes) as well as the total (for the EmptyDir) +// Bundle builder: ~ 5 MB x 5 +// These sizes are needed both for the single file (for rotation, in bytes) as well as the total (for the EmptyDir). +// +// Ideally, we would rotate the logs by size, but this is currently not supported due to upstream issues. +// Please see https://github.com/stackabletech/opa-operator/issues/606 for more details. const OPA_ROLLING_BUNDLE_BUILDER_LOG_FILE_SIZE_MB: u32 = 5; -const OPA_ROLLING_BUNDLE_BUILDER_LOG_FILE_SIZE_BYTES: u32 = - OPA_ROLLING_BUNDLE_BUILDER_LOG_FILE_SIZE_MB * 1000000; -const OPA_ROLLING_BUNDLE_BUILDER_LOG_FILES: u32 = 2; +const OPA_ROLLING_BUNDLE_BUILDER_LOG_FILES: u32 = 5; const MAX_OPA_BUNDLE_BUILDER_LOG_FILE_SIZE: MemoryQuantity = MemoryQuantity { value: (OPA_ROLLING_BUNDLE_BUILDER_LOG_FILE_SIZE_MB * OPA_ROLLING_BUNDLE_BUILDER_LOG_FILES) as f32, unit: BinaryMultiple::Mebi, }; -// opa logs: ~ 5 MB x 2 -// these sizes are needed both for the single file (for multilog, in bytes) as well as the total (for the EmptyDir) +// OPA logs: ~ 5 MB x 2 +// These sizes are needed both for the single file (for multilog, in bytes) as well as the total (for the EmptyDir). const OPA_ROLLING_LOG_FILE_SIZE_MB: u32 = 5; const OPA_ROLLING_LOG_FILE_SIZE_BYTES: u32 = OPA_ROLLING_LOG_FILE_SIZE_MB * 1000000; const OPA_ROLLING_LOG_FILES: u32 = 2; @@ -134,6 +135,7 @@ const MAX_PREPARE_LOG_FILE_SIZE: MemoryQuantity = MemoryQuantity { pub struct Ctx { pub client: stackable_operator::client::Client, pub product_config: ProductConfigManager, + pub opa_bundle_builder_image: String, pub user_info_fetcher_image: String, } @@ -448,6 +450,7 @@ pub async fn reconcile_opa(opa: Arc, ctx: Arc) -> Result, server_config: &HashMap>, merged_config: &OpaConfig, + opa_bundle_builder_image: &str, user_info_fetcher_image: &str, sa_name: &str, ) -> Result { @@ -746,7 +750,8 @@ fn build_server_rolegroup_daemonset( .resources(merged_config.resources.to_owned().into()); cb_bundle_builder - .image_from_product_image(resolved_product_image) + .image_from_product_image(resolved_product_image) // inherit the pull policy and pull secrets, and then... + .image(opa_bundle_builder_image) // ...override the image .command(vec![ "/bin/bash".to_string(), "-x".to_string(), @@ -763,6 +768,10 @@ fn build_server_rolegroup_daemonset( "OPA_BUNDLE_BUILDER_LOG", bundle_builder_log_level(merged_config).to_string(), ) + .add_env_var( + "OPA_BUNDLE_BUILDER_LOG_DIRECTORY", + format!("{STACKABLE_LOG_DIR}/{bundle_builder_container_name}"), + ) .add_volume_mount(BUNDLES_VOLUME_NAME, BUNDLES_DIR) .add_volume_mount(LOG_VOLUME_NAME, STACKABLE_LOG_DIR) .resources( @@ -1108,18 +1117,15 @@ fn build_bundle_builder_start_command(merged_config: &OpaConfig, container_name: formatdoc! {" {COMMON_BASH_TRAP_FUNCTIONS} prepare_signal_handlers - /stackable/opa-bundle-builder{logging_redirects} & + mkdir -p {STACKABLE_LOG_DIR}/{container_name} + stackable-opa-bundle-builder{logging_redirects} & wait_for_termination $! ", - // Redirects matter! - // We need to watch out, that the following "$!" call returns the PID of the main (opa-bundle-builder) process, - // and not some utility (e.g. multilog or tee) process. - // See https://stackoverflow.com/a/8048493 logging_redirects = if console_logging_off { - format!(" &> >(/stackable/multilog s{OPA_ROLLING_BUNDLE_BUILDER_LOG_FILE_SIZE_BYTES} n{OPA_ROLLING_BUNDLE_BUILDER_LOG_FILES} {STACKABLE_LOG_DIR}/{container_name})") + " > /dev/null" } else { - format!(" &> >(tee >(/stackable/multilog s{OPA_ROLLING_BUNDLE_BUILDER_LOG_FILE_SIZE_BYTES} n{OPA_ROLLING_BUNDLE_BUILDER_LOG_FILES} {STACKABLE_LOG_DIR}/{container_name}))") - }, + "" + } } } diff --git a/rust/operator-binary/src/main.rs b/rust/operator-binary/src/main.rs index 9e573659..b24ed795 100644 --- a/rust/operator-binary/src/main.rs +++ b/rust/operator-binary/src/main.rs @@ -84,7 +84,14 @@ async fn main() -> anyhow::Result<()> { ])?; let client = client::create_client(Some(OPERATOR_NAME.to_string())).await?; - create_controller(client, product_config, watch_namespace, operator_image).await; + create_controller( + client, + product_config, + watch_namespace, + operator_image.clone(), + operator_image, + ) + .await; } }; @@ -98,6 +105,7 @@ async fn create_controller( client: Client, product_config: ProductConfigManager, watch_namespace: WatchNamespace, + opa_bundle_builder_image: String, user_info_fetcher_image: String, ) { let opa_api: Api = watch_namespace.get_api(&client); @@ -117,6 +125,7 @@ async fn create_controller( Arc::new(controller::Ctx { client: client.clone(), product_config, + opa_bundle_builder_image, user_info_fetcher_image, }), ) diff --git a/rust/user-info-fetcher/src/main.rs b/rust/user-info-fetcher/src/main.rs index 9bb737ea..ff1765fc 100644 --- a/rust/user-info-fetcher/src/main.rs +++ b/rust/user-info-fetcher/src/main.rs @@ -58,8 +58,8 @@ enum StartupError { #[snafu(display("failed to register SIGTERM handler"))] RegisterSigterm { source: std::io::Error }, - #[snafu(display("failed to create listener"))] - CreateListener { source: std::io::Error }, + #[snafu(display("failed to bind listener"))] + BindListener { source: std::io::Error }, #[snafu(display("failed to run server"))] RunServer { source: std::io::Error }, @@ -168,7 +168,7 @@ async fn main() -> Result<(), StartupError> { }); let listener = TcpListener::bind("127.0.0.1:9476") .await - .context(CreateListenerSnafu)?; + .context(BindListenerSnafu)?; axum::serve(listener, app.into_make_service()) .with_graceful_shutdown(shutdown_requested)