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 @@ -42,11 +42,8 @@ All notable changes to this project will be documented in this file.
environment variables by name, so an override replaces the operator's value instead of
producing a duplicated entry whose precedence depended on Kubernetes' duplicate-name
handling ([#1011]).
- 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).
Broker StatefulSets created by older operator versions cannot be updated in place: after the
operator upgrade, delete each broker StatefulSet so that the operator immediately recreates it
with the new labels ([#1011]).
- Remove the `app.kubernetes.io/component` and `app.kubernetes.io/role-group` labels from the
resources they don't apply to ([#1011], [#1052]).
- Make operations infallible where dependent on static inputs ([#1017]).
- Internal operator refactoring: build each role group through per-role modules (brokers,
controllers) and a shared role group builder, with the broker and controller configuration held
Expand Down Expand Up @@ -103,6 +100,7 @@ All notable changes to this project will be documented in this file.
[#1046]: https://github.com/stackabletech/kafka-operator/pull/1046
[#1047]: https://github.com/stackabletech/kafka-operator/pull/1047
[#1049]: https://github.com/stackabletech/kafka-operator/pull/1049
[#1052]: https://github.com/stackabletech/kafka-operator/pull/1052

## [26.7.0] - 2026-07-21

Expand Down
29 changes: 25 additions & 4 deletions rust/operator-binary/src/controller/build/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Builders that assemble Kubernetes resources for kafka rolegroups.

use std::marker::PhantomData;
use std::{marker::PhantomData, str::FromStr};

use snafu::{ResultExt, Snafu};
use stackable_operator::{
Expand All @@ -10,7 +10,7 @@ use stackable_operator::{
policy::v1::PodDisruptionBudget,
},
kvp::Labels,
v2::kvp::label,
v2::{kvp::label, types::operator::ProductVersion},
};
use strum::IntoEnumIterator;

Expand Down Expand Up @@ -40,6 +40,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");

#[derive(Snafu, Debug)]
pub enum Error {
#[snafu(display("failed to build broker role group {role_group}"))]
Expand Down Expand Up @@ -195,14 +199,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 @@ -231,7 +246,7 @@ mod tests {
use strum::IntoEnumIterator;

use super::{
build,
UNVERSIONED_PRODUCT_VERSION, build,
kerberos::KERBEROS_VOLUME_NAME,
properties::ConfigFileName,
role_group::controller::QUORUM_MANAGER_CONTAINER_NAME,
Expand Down Expand Up @@ -452,6 +467,12 @@ mod tests {
)
}

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

#[test]
fn build_succeeds_when_every_kraft_role_group_is_scaled_to_zero() {
let kafka = minimal_kafka(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,7 @@ fn volume_claim_templates(
role_group_name: &RoleGroupName,
config: &ValidatedBrokerConfig,
) -> Vec<PersistentVolumeClaim> {
// 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 templates are immutable once deployed, so their labels must stay stable.
let unversioned_recommended_labels =
recommended_labels_for_unversioned_role_group_resources(cluster, &ROLE, role_group_name);

Expand Down
Loading