Skip to content

Commit 0298137

Browse files
fix: Keep the "none" version label on unversioned role-group resources (#892)
1 parent 1a7799c commit 0298137

3 files changed

Lines changed: 29 additions & 10 deletions

File tree

‎CHANGELOG.md‎

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

7775
## [26.7.0] - 2026-07-21
7876

‎rust/operator-binary/src/controller/build/container.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,7 @@ pub(crate) fn containers_and_volumes(inputs: &RoleGroupInputs) -> Result<Contain
188188
.add_volume_mount(&*LISTENER_VOLUME_NAME, LISTENER_VOLUME_DIR)
189189
.expect("The mount paths are statically defined and there should be no duplicates.");
190190

191-
// Used for PVC templates, which cannot be modified once they are deployed. The version
192-
// label is omitted so the labels stay stable across version upgrades.
191+
// The PVC template is immutable once deployed, so its labels must stay stable.
193192
let unversioned_recommended_labels =
194193
recommended_labels_for_unversioned_role_group_resources(
195194
cluster,

‎rust/operator-binary/src/controller/build/mod.rs‎

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::{
44
collections::{BTreeMap, HashSet},
55
marker::PhantomData,
6+
str::FromStr,
67
};
78

89
use snafu::{ResultExt, Snafu};
@@ -19,7 +20,7 @@ use stackable_operator::{
1920
kvp::label,
2021
types::{
2122
kubernetes::SecretKey,
22-
operator::{RoleGroupName, RoleName},
23+
operator::{ProductVersion, RoleGroupName, RoleName},
2324
},
2425
},
2526
};
@@ -55,6 +56,10 @@ pub mod resource;
5556
pub mod role_group;
5657
pub mod security;
5758

59+
// Placeholder value for the `app.kubernetes.io/version` label on resources whose labels are
60+
// immutable once deployed. See `recommended_labels_for_unversioned_role_group_resources`.
61+
stackable_operator::constant!(UNVERSIONED_PRODUCT_VERSION: ProductVersion = "none");
62+
5863
/// Returns an [`ObjectMetaBuilder`] pre-filled with the cluster's namespace, an owner
5964
/// reference back to the cluster, the resource `name` and the given `recommended_labels`.
6065
///
@@ -114,14 +119,25 @@ pub(crate) fn recommended_labels_for_role_group_resources(
114119
)
115120
}
116121

122+
/// The recommended labels for role-group resources that carry no product version.
123+
///
124+
/// The `app.kubernetes.io/version` label is set to the placeholder `none` rather than being
125+
/// omitted, because that is what operator versions up to 26.7 wrote. Omitting it would change the
126+
/// `volumeClaimTemplates` of already deployed StatefulSets, and since those templates are
127+
/// immutable, Kubernetes rejects the update and the operator can no longer reconcile the
128+
/// StatefulSet.
129+
///
130+
/// This is also why `label::recommended_labels_for_unversioned_role_group_resources`, which drops
131+
/// the label entirely, is not used here.
117132
pub(crate) fn recommended_labels_for_unversioned_role_group_resources(
118133
cluster: &ValidatedCluster,
119134
role_name: &RoleName,
120135
role_group_name: &RoleGroupName,
121136
) -> Labels {
122-
label::recommended_labels_for_unversioned_role_group_resources(
137+
label::recommended_labels_for_role_group_resources(
123138
&cluster.name,
124139
&PRODUCT_NAME,
140+
&UNVERSIONED_PRODUCT_VERSION,
125141
&OPERATOR_NAME,
126142
&CONTROLLER_NAME,
127143
role_name,
@@ -483,7 +499,7 @@ mod tests {
483499
use strum::IntoEnumIterator;
484500

485501
use super::{
486-
KubernetesResources, Prepared, SecretKey, build,
502+
KubernetesResources, Prepared, SecretKey, UNVERSIONED_PRODUCT_VERSION, build,
487503
container::{
488504
DRUID_CONFIG_VOLUME_NAME, HDFS_CONFIG_VOLUME_NAME, LOG_CONFIG_VOLUME_NAME,
489505
LOG_VOLUME_NAME, RW_CONFIG_VOLUME_NAME,
@@ -752,6 +768,12 @@ spec:
752768
.expect("the ConfigMap has data")
753769
}
754770

771+
#[test]
772+
fn test_constants() {
773+
// Test that dereferencing the constant does not panic.
774+
let _ = *UNVERSIONED_PRODUCT_VERSION;
775+
}
776+
755777
/// A pod's `volumes` are an ordered list: reordering them changes the pod template of every
756778
/// running StatefulSet and so restarts its pods. Pinned on the fixture that has every
757779
/// optional volume: the operator-managed volumes first, the Historical segment cache after

0 commit comments

Comments
 (0)