diff --git a/CHANGELOG.md b/CHANGELOG.md index bc484788..84864572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ All notable changes to this project will be documented in this file. 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]). -- Make operations infallible where dependent on static inputs ([#869]). +- Make operations infallible where dependent on static inputs ([#869], [#874]). ### Fixed @@ -43,6 +43,7 @@ All notable changes to this project will be documented in this file. [#865]: https://github.com/stackabletech/druid-operator/pull/865 [#867]: https://github.com/stackabletech/druid-operator/pull/867 [#869]: https://github.com/stackabletech/druid-operator/pull/869 +[#874]: https://github.com/stackabletech/druid-operator/pull/874 ## [26.7.0] - 2026-07-21 diff --git a/rust/operator-binary/src/controller/build/resource/statefulset.rs b/rust/operator-binary/src/controller/build/resource/statefulset.rs index b92e7c85..4b9a5b40 100644 --- a/rust/operator-binary/src/controller/build/resource/statefulset.rs +++ b/rust/operator-binary/src/controller/build/resource/statefulset.rs @@ -130,11 +130,9 @@ pub fn build_rolegroup_statefulset( let druid_tls_security = &cluster.cluster_config.druid_tls_security; let druid_auth_config = &cluster.cluster_config.druid_auth_config; // prepare container builder - let prepare_container_name = Container::Prepare.to_container_name(); - let mut cb_prepare = new_container_builder(&prepare_container_name); + let mut cb_prepare = new_container_builder(Container::Prepare.name()); // druid container builder - let druid_container_name = Container::Druid.to_container_name(); - let mut cb_druid = new_container_builder(&druid_container_name); + let mut cb_druid = new_container_builder(Container::Druid.name()); // init pod builder let mut pb = PodBuilder::new(); pb.affinity(&merged_rolegroup_config.affinity); @@ -158,7 +156,7 @@ pub fn build_rolegroup_statefulset( // otherwise the output of the following commands will not be captured! prepare_container_commands.push(product_logging::framework::capture_shell_output( STACKABLE_LOG_DIR, - prepare_container_name.as_ref(), + Container::Prepare.name().as_ref(), log_config, )); } @@ -362,7 +360,7 @@ pub fn build_rolegroup_statefulset( // config volume; the validated aggregator address comes from the up-front `ValidatedLogging`. if let Some(vector_log_config) = &merged_rolegroup_config.logging.vector_container { pb.add_container(vector_container( - &Container::Vector.to_container_name(), + Container::Vector.name(), resolved_product_image, vector_log_config, &resource_names, diff --git a/rust/operator-binary/src/crd/mod.rs b/rust/operator-binary/src/crd/mod.rs index 0ebf8b23..30832298 100644 --- a/rust/operator-binary/src/crd/mod.rs +++ b/rust/operator-binary/src/crd/mod.rs @@ -497,11 +497,20 @@ pub enum Container { Vector, } +// Typed container names. They must match the strum `Display` (kebab-case) of the variants above, +// which is pinned by a unit test. +constant!(DRUID_CONTAINER_NAME: ContainerName = "druid"); +constant!(PREPARE_CONTAINER_NAME: ContainerName = "prepare"); +constant!(VECTOR_CONTAINER_NAME: ContainerName = "vector"); + impl Container { - /// Returns the typed container name for this container. - pub fn to_container_name(&self) -> ContainerName { - ContainerName::from_str(&self.to_string()) - .expect("a Container always serializes to a valid container name") + /// The typed container name of this variant. + pub fn name(&self) -> &'static ContainerName { + match self { + Container::Druid => &DRUID_CONTAINER_NAME, + Container::Prepare => &PREPARE_CONTAINER_NAME, + Container::Vector => &VECTOR_CONTAINER_NAME, + } } } @@ -901,10 +910,20 @@ pub fn build_string_list(strings: &[String]) -> String { #[cfg(test)] mod tests { use stackable_operator::versioned::test_utils::RoundtripTestData; + use strum::IntoEnumIterator; use super::*; use crate::crd::v1alpha1; + /// The typed container names returned by `name` must agree with the strum `Display` + /// of `Container`, which the logging configuration still uses as the per-container key. + #[test] + fn container_names_match_display() { + for container in Container::iter() { + assert_eq!(container.name().to_string(), container.to_string()); + } + } + #[test] fn test_constants() { // Test that dereferencing the constants does not panic. @@ -916,6 +935,9 @@ mod tests { let _ = *COOKIE_PASSPHRASE_ENV; let _ = *COOKIE_PASSPHRASE_SECRET_KEY; let _ = *DRUID_DEFAULT_LISTENER_CLASS; + let _ = *DRUID_CONTAINER_NAME; + let _ = *PREPARE_CONTAINER_NAME; + let _ = *VECTOR_CONTAINER_NAME; } impl RoundtripTestData for v1alpha1::DruidClusterSpec {