Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@ All notable changes to this project will be documented in this file.
variables set by the operator. In particular, `CONTAINERDEBUG_LOG_DIRECTORY` and the
authentication-related environment variables can now be overridden, whereas previously the
operator's values always took precedence ([#865]).
- BREAKING: Remove the `app.kubernetes.io/component` and `app.kubernetes.io/role-group` labels
from the resources they don't apply to (previously set to `none` or a placeholder value).
StatefulSets created by older operator versions cannot be updated in place: after the
operator upgrade, delete each broker, coordinator and router StatefulSet so that the operator
immediately recreates it with the new labels ([#865]).
- Remove the `app.kubernetes.io/component` and `app.kubernetes.io/role-group` labels from the
resources they don't apply to ([#865], [#892]).
- Make operations infallible where dependent on static inputs ([#869], [#874]).
- Internal operator refactoring: build each role group through per-role modules (brokers,
coordinators, historicals, middle managers, routers) and a shared role group builder, with
Expand Down Expand Up @@ -73,6 +70,7 @@ All notable changes to this project will be documented in this file.
[#888]: https://github.com/stackabletech/druid-operator/pull/888
[#889]: https://github.com/stackabletech/druid-operator/pull/889
[#891]: https://github.com/stackabletech/druid-operator/pull/891
[#892]: https://github.com/stackabletech/druid-operator/pull/892

## [26.7.0] - 2026-07-21

Expand Down
3 changes: 1 addition & 2 deletions rust/operator-binary/src/controller/build/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,7 @@ pub(crate) fn containers_and_volumes(inputs: &RoleGroupInputs) -> Result<Contain
.add_volume_mount(&*LISTENER_VOLUME_NAME, LISTENER_VOLUME_DIR)
.expect("The mount paths are statically defined and there should be no duplicates.");

// Used for PVC templates, which cannot be modified once they are deployed. The version
// label is omitted so the labels stay stable across version upgrades.
// The PVC template is immutable once deployed, so its labels must stay stable.
let unversioned_recommended_labels =
recommended_labels_for_unversioned_role_group_resources(
cluster,
Expand Down
28 changes: 25 additions & 3 deletions rust/operator-binary/src/controller/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::{
collections::{BTreeMap, HashSet},
marker::PhantomData,
str::FromStr,
};

use snafu::{ResultExt, Snafu};
Expand All @@ -19,7 +20,7 @@ use stackable_operator::{
kvp::label,
types::{
kubernetes::SecretKey,
operator::{RoleGroupName, RoleName},
operator::{ProductVersion, RoleGroupName, RoleName},
},
},
};
Expand Down Expand Up @@ -55,6 +56,10 @@ pub mod resource;
pub mod role_group;
pub mod security;

// Placeholder value for the `app.kubernetes.io/version` label on resources whose labels are
// immutable once deployed. See `recommended_labels_for_unversioned_role_group_resources`.
stackable_operator::constant!(UNVERSIONED_PRODUCT_VERSION: ProductVersion = "none");

/// Returns an [`ObjectMetaBuilder`] pre-filled with the cluster's namespace, an owner
/// reference back to the cluster, the resource `name` and the given `recommended_labels`.
///
Expand Down Expand Up @@ -114,14 +119,25 @@ pub(crate) fn recommended_labels_for_role_group_resources(
)
}

/// The recommended labels for role-group resources that carry no product version.
///
/// The `app.kubernetes.io/version` label is set to the placeholder `none` rather than being
/// omitted, because that is what operator versions up to 26.7 wrote. Omitting it would change the
/// `volumeClaimTemplates` of already deployed StatefulSets, and since those templates are
/// immutable, Kubernetes rejects the update and the operator can no longer reconcile the
/// StatefulSet.
///
/// This is also why `label::recommended_labels_for_unversioned_role_group_resources`, which drops
/// the label entirely, is not used here.
pub(crate) fn recommended_labels_for_unversioned_role_group_resources(
cluster: &ValidatedCluster,
role_name: &RoleName,
role_group_name: &RoleGroupName,
) -> Labels {
label::recommended_labels_for_unversioned_role_group_resources(
label::recommended_labels_for_role_group_resources(
&cluster.name,
&PRODUCT_NAME,
&UNVERSIONED_PRODUCT_VERSION,
&OPERATOR_NAME,
&CONTROLLER_NAME,
role_name,
Expand Down Expand Up @@ -483,7 +499,7 @@ mod tests {
use strum::IntoEnumIterator;

use super::{
KubernetesResources, Prepared, SecretKey, build,
KubernetesResources, Prepared, SecretKey, UNVERSIONED_PRODUCT_VERSION, build,
container::{
DRUID_CONFIG_VOLUME_NAME, HDFS_CONFIG_VOLUME_NAME, LOG_CONFIG_VOLUME_NAME,
LOG_VOLUME_NAME, RW_CONFIG_VOLUME_NAME,
Expand Down Expand Up @@ -752,6 +768,12 @@ spec:
.expect("the ConfigMap has data")
}

#[test]
fn test_constants() {
// Test that dereferencing the constant does not panic.
let _ = *UNVERSIONED_PRODUCT_VERSION;
}

/// A pod's `volumes` are an ordered list: reordering them changes the pod template of every
/// running StatefulSet and so restarts its pods. Pinned on the fixture that has every
/// optional volume: the operator-managed volumes first, the Historical segment cache after
Expand Down
Loading