diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8084f3574..5ee923b6d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -55,14 +55,39 @@ repos: pass_filenames: false files: \.rs$|Cargo\.(toml|lock) - - id: cargo-test-no-default-features - name: cargo-test-no-default-features + - id: cargo-doc-no-default-features + name: cargo-doc-no-default-features language: system - entry: cargo test --no-default-features --workspace + entry: cargo doc --no-default-features --document-private-items stages: [pre-commit, pre-merge-commit] pass_filenames: false files: \.rs$|Cargo\.(toml|lock) + - id: cargo-doc-all-features + name: cargo-doc-all-features + language: system + entry: cargo doc --all-features --document-private-items + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + # As long as we run tests for every contained crate (to test turning off all features), + # we don't need to re-run them here + # - id: cargo-test + # name: cargo-test + # language: system + # entry: cargo test --workspace + # stages: [pre-commit, pre-merge-commit] + # pass_filenames: false + # files: \.rs$|Cargo\.(toml|lock) + # - id: cargo-test-no-default-features + # name: cargo-test-no-default-features + # language: system + # entry: cargo test --no-default-features --workspace + # stages: [pre-commit, pre-merge-commit] + # pass_filenames: false + # files: \.rs$|Cargo\.(toml|lock) + - id: cargo-test-all-features name: cargo-test-all-features language: system @@ -71,6 +96,78 @@ repos: pass_filenames: false files: \.rs$|Cargo\.(toml|lock) + - id: cargo-test-k8s-version-no-default-features + name: cargo-test-k8s-version-no-default-features + language: system + entry: cargo test --no-default-features --package k8s-version + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + - id: cargo-test-stackable-certs-no-default-features + name: cargo-test-stackable-certs-no-default-features + language: system + entry: cargo test --no-default-features --package stackable-certs + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + - id: cargo-test-stackable-operator-no-default-features + name: cargo-test-stackable-operator-no-default-features + language: system + entry: cargo test --no-default-features --package stackable-operator + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + - id: cargo-test-stackable-operator-derive-no-default-features + name: cargo-test-stackable-operator-derive-no-default-features + language: system + entry: cargo test --no-default-features --package stackable-operator-derive + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + - id: cargo-test-stackable-shared-no-default-features + name: cargo-test-stackable-shared-no-default-features + language: system + entry: cargo test --no-default-features --package stackable-shared + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + - id: cargo-test-stackable-telemetry-no-default-features + name: cargo-test-stackable-telemetry-no-default-features + language: system + entry: cargo test --no-default-features --package stackable-telemetry + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + - id: cargo-test-stackable-versioned-no-default-features + name: cargo-test-stackable-versioned-no-default-features + language: system + entry: cargo test --no-default-features --package stackable-versioned + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + - id: cargo-test-stackable-versioned-macros-no-default-features + name: cargo-test-stackable-versioned-macros-no-default-features + language: system + entry: cargo test --no-default-features --package stackable-versioned-macros + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + + - id: cargo-test-stackable-webhook-no-default-features + name: cargo-test-stackable-webhook-no-default-features + language: system + entry: cargo test --no-default-features --package stackable-webhook + stages: [pre-commit, pre-merge-commit] + pass_filenames: false + files: \.rs$|Cargo\.(toml|lock) + - id: cargo-rustfmt name: cargo-rustfmt language: system diff --git a/Cargo.lock b/Cargo.lock index 67f360b32..945ff5cfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -523,6 +523,12 @@ dependencies = [ "syn 2.0.115", ] +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + [[package]] name = "delegate" version = "0.13.5" @@ -1569,6 +1575,7 @@ dependencies = [ "serde_yaml", "thiserror 2.0.18", "tokio", + "tokio-tungstenite", "tokio-util", "tower", "tower-http", @@ -3359,6 +3366,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.18" @@ -3647,6 +3666,23 @@ dependencies = [ "toml", ] +[[package]] +name = "tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.2", + "sha1", + "thiserror 2.0.18", + "utf-8", +] + [[package]] name = "typenum" version = "1.19.0" @@ -3702,6 +3738,12 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8_iter" version = "1.0.4" diff --git a/crates/stackable-operator/CHANGELOG.md b/crates/stackable-operator/CHANGELOG.md index 64d9bde2c..8c3a6ee63 100644 --- a/crates/stackable-operator/CHANGELOG.md +++ b/crates/stackable-operator/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- Added two new crate features: `crds` and `kube-ws` ([#1162]). + +### Fixed + +- BREAKING: Fix compilation failures when not enabling default features ([#1162]). + This is achieved by removing the `clap`, `telemetry` and `versioned` features, which were previously enabled by default. + They have been removed as the stackable-operator code actually always requires them. + +[#1162]: https://github.com/stackabletech/operator-rs/pull/1162 + ## [0.106.2] - 2026-02-26 ### Changed diff --git a/crates/stackable-operator/Cargo.toml b/crates/stackable-operator/Cargo.toml index 4c2181b7e..b26c78f7f 100644 --- a/crates/stackable-operator/Cargo.toml +++ b/crates/stackable-operator/Cargo.toml @@ -8,21 +8,20 @@ edition.workspace = true repository.workspace = true [features] -full = ["certs", "telemetry", "versioned", "time", "webhook", "clap"] -default = ["telemetry", "versioned", "clap"] +default = ["crds"] +full = ["crds", "certs", "time", "webhook", "kube-ws"] -clap = [] +crds = ["dep:stackable-versioned"] certs = ["dep:stackable-certs"] -telemetry = ["dep:stackable-telemetry"] time = ["stackable-shared/time"] -versioned = ["dep:stackable-versioned"] webhook = ["dep:stackable-webhook"] +kube-ws = ["kube/ws"] [dependencies] stackable-certs = { path = "../stackable-certs", optional = true } stackable-operator-derive = { path = "../stackable-operator-derive" } -stackable-shared = { path = "../stackable-shared", features = ["time", "jiff"] } -stackable-telemetry = { path = "../stackable-telemetry", optional = true, features = ["clap"] } +stackable-shared = { path = "../stackable-shared", features = ["jiff"] } +stackable-telemetry = { path = "../stackable-telemetry", features = ["clap"] } stackable-versioned = { path = "../stackable-versioned", optional = true } stackable-webhook = { path = "../stackable-webhook", optional = true } diff --git a/crates/stackable-operator/src/cluster_resources.rs b/crates/stackable-operator/src/cluster_resources.rs index b8ece1137..6bb0474c0 100644 --- a/crates/stackable-operator/src/cluster_resources.rs +++ b/crates/stackable-operator/src/cluster_resources.rs @@ -36,7 +36,6 @@ use crate::{ ResourceRequirementsExt, ResourceRequirementsType, }, }, - crd::listener, deep_merger::{self, ObjectOverrides}, kvp::{ Label, LabelError, Labels, @@ -221,7 +220,8 @@ impl ClusterResource for Service {} impl ClusterResource for ServiceAccount {} impl ClusterResource for RoleBinding {} impl ClusterResource for PodDisruptionBudget {} -impl ClusterResource for listener::v1alpha1::Listener {} +#[cfg(feature = "crds")] +impl ClusterResource for crate::crd::listener::v1alpha1::Listener {} impl ClusterResource for Job { fn pod_spec(&self) -> Option<&PodSpec> { @@ -670,6 +670,13 @@ impl<'a> ClusterResources<'a> { /// /// * `client` - The client which is used to access Kubernetes pub async fn delete_orphaned_resources(self, client: &Client) -> Result<()> { + // We can only delete Listeners in case the "crds" feature is enabled, otherwise it's a NOP. + #[cfg(feature = "crds")] + let delete_listeners = self + .delete_orphaned_resources_of_kind::(client); + #[cfg(not(feature = "crds"))] + let delete_listeners = async { Ok(()) }; + tokio::try_join!( self.delete_orphaned_resources_of_kind::(client), self.delete_orphaned_resources_of_kind::(client), @@ -680,7 +687,7 @@ impl<'a> ClusterResources<'a> { self.delete_orphaned_resources_of_kind::(client), self.delete_orphaned_resources_of_kind::(client), self.delete_orphaned_resources_of_kind::(client), - self.delete_orphaned_resources_of_kind::(client), + delete_listeners )?; Ok(()) diff --git a/crates/stackable-operator/src/eos/mod.rs b/crates/stackable-operator/src/eos/mod.rs index 7e732c175..2dc5d94e1 100644 --- a/crates/stackable-operator/src/eos/mod.rs +++ b/crates/stackable-operator/src/eos/mod.rs @@ -9,35 +9,34 @@ use tracing::{Level, instrument}; /// /// Additionally, this struct can be used as operator CLI arguments. This functionality is only /// available if the feature `clap` is enabled. -#[cfg_attr(feature = "clap", derive(clap::Args))] -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, clap::Args)] pub struct EndOfSupportOptions { /// The end-of-support check mode. Currently, only "offline" is supported. - #[cfg_attr(feature = "clap", arg( + #[arg( long = "eos-check-mode", env = "EOS_CHECK_MODE", default_value_t = EndOfSupportCheckMode::default(), value_enum - ))] + )] pub check_mode: EndOfSupportCheckMode, /// The interval in which the end-of-support check should run. - #[cfg_attr(feature = "clap", arg( + #[arg( long = "eos-interval", env = "EOS_INTERVAL", default_value_t = Self::default_interval() - ))] + )] pub interval: Duration, /// If the end-of-support check should be disabled entirely. - #[cfg_attr(feature = "clap", arg(long = "eos-disabled", env = "EOS_DISABLED"))] + #[arg(long = "eos-disabled", env = "EOS_DISABLED")] pub disabled: bool, /// The support duration (how long the operator should be considered supported after /// it's built-date). /// /// This field is currently not exposed as a CLI argument or environment variable. - #[cfg_attr(feature = "clap", arg(skip = Self::default_support_duration()))] + #[arg(skip = Self::default_support_duration())] pub support_duration: Duration, } @@ -55,8 +54,7 @@ impl EndOfSupportOptions { } } -#[cfg_attr(feature = "clap", derive(clap::ValueEnum))] -#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[derive(Clone, Debug, Default, PartialEq, Eq, clap::ValueEnum)] pub enum EndOfSupportCheckMode { #[default] Offline, diff --git a/crates/stackable-operator/src/lib.rs b/crates/stackable-operator/src/lib.rs index c73e72143..46616252c 100644 --- a/crates/stackable-operator/src/lib.rs +++ b/crates/stackable-operator/src/lib.rs @@ -14,6 +14,7 @@ pub mod commons; pub mod config; pub mod constants; pub mod cpu; +#[cfg(feature = "crds")] pub mod crd; pub mod deep_merger; pub mod eos; @@ -42,9 +43,8 @@ pub use schemars; pub use stackable_certs as certs; pub use stackable_shared as shared; pub use stackable_shared::{crd::CustomResourceExt, yaml::YamlSchema}; -#[cfg(feature = "telemetry")] pub use stackable_telemetry as telemetry; -#[cfg(feature = "versioned")] +#[cfg(feature = "crds")] pub use stackable_versioned as versioned; #[cfg(feature = "webhook")] pub use stackable_webhook as webhook; diff --git a/crates/stackable-operator/src/utils/cluster_info.rs b/crates/stackable-operator/src/utils/cluster_info.rs index a7d7a813f..fdd3c2b71 100644 --- a/crates/stackable-operator/src/utils/cluster_info.rs +++ b/crates/stackable-operator/src/utils/cluster_info.rs @@ -15,16 +15,13 @@ pub struct KubernetesClusterInfo { pub cluster_domain: DomainName, } -#[cfg_attr( - feature = "clap", - derive(clap::Parser), - command(next_help_heading = "Cluster Options") -)] +#[derive(clap::Parser)] +#[command(next_help_heading = "Cluster Options")] #[derive(Debug, PartialEq, Eq)] pub struct KubernetesClusterInfoOptions { /// Kubernetes cluster domain, usually this is `cluster.local`. // We are not using a default value here, as we query the cluster if it is not specified. - #[cfg_attr(feature = "clap", arg(long, env))] + #[arg(long, env)] pub kubernetes_cluster_domain: Option, /// Name of the Kubernetes Node that the operator is running on. @@ -32,7 +29,7 @@ pub struct KubernetesClusterInfoOptions { /// Note that when running the operator on Kubernetes we recommend to use the /// [downward API](https://kubernetes.io/docs/concepts/workloads/pods/downward-api/) /// to let Kubernetes project the namespace as the `KUBERNETES_NODE_NAME` env variable. - #[cfg_attr(feature = "clap", arg(long, env))] + #[arg(long, env)] pub kubernetes_node_name: String, } diff --git a/crates/stackable-telemetry/CHANGELOG.md b/crates/stackable-telemetry/CHANGELOG.md index 5a16748fb..c61d81b33 100644 --- a/crates/stackable-telemetry/CHANGELOG.md +++ b/crates/stackable-telemetry/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Fixed + +- BREAKING: Fix compilation failures when not enabling default features ([#1162]). + +[#1162]: https://github.com/stackabletech/operator-rs/pull/1162 + ## [0.6.1] - 2025-07-10 ### Changed diff --git a/crates/stackable-telemetry/src/tracing/mod.rs b/crates/stackable-telemetry/src/tracing/mod.rs index 4262c1f46..c50f3285a 100644 --- a/crates/stackable-telemetry/src/tracing/mod.rs +++ b/crates/stackable-telemetry/src/tracing/mod.rs @@ -8,8 +8,6 @@ use std::{ops::Not, path::PathBuf}; -#[cfg_attr(feature = "clap", cfg(doc))] -use clap; use opentelemetry::trace::TracerProvider; use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge; use opentelemetry_otlp::{ExporterBuildError, LogExporter, SpanExporter}; @@ -125,7 +123,7 @@ pub enum Error { /// ``` /// /// Also see the documentation for [`TelemetryOptions`] which details how it can be used as CLI -/// arguments via [`clap`]. Additionally see [this section](#environment-variables-and-cli-arguments) +/// arguments via `clap`. Additionally see [this section](#environment-variables-and-cli-arguments) /// in the docs for a full list of environment variables and CLI arguments used by the pre-configured /// instance. /// @@ -148,7 +146,7 @@ pub enum Error { /// /// #[tokio::main] /// async fn main() -> Result<(), Error> { -/// // This can come from a Clap argument for example. The enabled builder +/// // This can come from a `clap` argument for example. The enabled builder /// // function below allows enabling/disabling certain subscribers during /// // runtime. /// let otlp_log_flag = false; diff --git a/crates/stackable-webhook/Cargo.toml b/crates/stackable-webhook/Cargo.toml index ca4bb8e7a..7c7ad3603 100644 --- a/crates/stackable-webhook/Cargo.toml +++ b/crates/stackable-webhook/Cargo.toml @@ -35,7 +35,7 @@ x509-cert.workspace = true [dev-dependencies] # Only needed for doc tests -stackable-operator = { path = "../stackable-operator" } +stackable-operator = { path = "../stackable-operator", features = ["crds"] } clap.workspace = true [lints] diff --git a/crates/xtask/Cargo.toml b/crates/xtask/Cargo.toml index b095a7313..b64675e9f 100644 --- a/crates/xtask/Cargo.toml +++ b/crates/xtask/Cargo.toml @@ -4,7 +4,7 @@ edition = "2024" publish = false [dependencies] -stackable-operator = { path = "../stackable-operator" } +stackable-operator = { path = "../stackable-operator", features = ["crds"] } clap.workspace = true paste.workspace = true