From deaeabfba2a90f63b38bd09745679ba2f1400c57 Mon Sep 17 00:00:00 2001 From: Niladri Halder Date: Sat, 1 Feb 2025 21:29:27 +0000 Subject: [PATCH] feat(upgrade): add initContainer block updates for csi-node,jaeger.collector,loki Signed-off-by: Niladri Halder --- k8s/upgrade/src/common/constants.rs | 3 + k8s/upgrade/src/common/error.rs | 25 +++++++- k8s/upgrade/src/helm/chart.rs | 75 ++++++++++++++++++----- k8s/upgrade/src/helm/values.rs | 94 +++++++++++++++++++++++++++-- 4 files changed, 177 insertions(+), 20 deletions(-) diff --git a/k8s/upgrade/src/common/constants.rs b/k8s/upgrade/src/common/constants.rs index 0b962f87d..2af27a990 100644 --- a/k8s/upgrade/src/common/constants.rs +++ b/k8s/upgrade/src/common/constants.rs @@ -60,3 +60,6 @@ pub(crate) const TWO_DOT_SEVEN_DOT_TWO: Version = Version::new(2, 7, 2); /// Version value for 2.7.3. pub(crate) const TWO_DOT_SEVEN_DOT_THREE: Version = Version::new(2, 7, 3); + +/// Version value for 2.8.0. +pub(crate) const TWO_DOT_EIGHT: Version = Version::new(2, 8, 0); diff --git a/k8s/upgrade/src/common/error.rs b/k8s/upgrade/src/common/error.rs index 0491d6938..da64464d4 100644 --- a/k8s/upgrade/src/common/error.rs +++ b/k8s/upgrade/src/common/error.rs @@ -520,12 +520,35 @@ pub enum Error { }, /// Error in serializing base.jaeger.agent.initContainers. - #[snafu(display("Failed to serialize .base.jaeger.agent.initContainer {object:?}: {source}",))] + #[snafu(display("Failed to serialize .base.jaeger.agent.initContainer {object:?}: {source}"))] SerializeJaegerAgentInitContainerToJson { source: serde_json::Error, object: Container, }, + /// Error in serializing base.jaeger.collector.initContainers. + #[snafu(display( + "Failed to serialize .base.jaeger.collector.initContainer {object:?}: {source}", + ))] + SerializeJaegerCollectorInitContainerToJson { + source: serde_json::Error, + object: Container, + }, + + #[snafu(display( + "Failed to serialize .csi.node.initContainers.containers {object:?}: {source}" + ))] + SerializeCsiNodeInitContainersToJson { + source: serde_json::Error, + object: Container, + }, + + #[snafu(display("Failed to serialize .loki-stack.loki.initContainers {object:?}: {source}"))] + SerializeLokiInitContainersToJson { + source: serde_json::Error, + object: Container, + }, + /// Error for when there are too many io-engine Pods in one single node; #[snafu(display("Too many io-engine Pods in Node '{node_name}'"))] TooManyIoEnginePods { node_name: String }, diff --git a/k8s/upgrade/src/helm/chart.rs b/k8s/upgrade/src/helm/chart.rs index af5b47aba..8c7998c04 100644 --- a/k8s/upgrade/src/helm/chart.rs +++ b/k8s/upgrade/src/helm/chart.rs @@ -221,6 +221,10 @@ impl CoreValues { self.csi.node_nvme_io_timeout() } + pub(crate) fn csi_node_init_containers(&self) -> &[Container] { + self.csi.csi_node_init_containers() + } + /// This returns the value of the removed key for CSI socket mount path. pub(crate) fn deprecated_node_csi_mount_path(&self) -> &str { self.csi.deprecated_node_csi_mount_path() @@ -231,6 +235,10 @@ impl CoreValues { self.loki_stack.loki_image_tag() } + pub(crate) fn loki_stack_loki_init_containers(&self) -> &[Container] { + self.loki_stack.loki_init_containers() + } + /// This is a getter for the promtail scrapeConfigs. pub(crate) fn loki_stack_promtail_scrape_configs(&self) -> &str { self.loki_stack.promtail_scrape_configs() @@ -348,6 +356,11 @@ impl CoreValues { self.base.jaeger_agent_init_container() } + /// This is the array of containers associated with jaeger collector initContainers. + pub(crate) fn base_jaeger_collector_init_container(&self) -> &[Container] { + self.base.jaeger_collector_init_container() + } + /// Retrieves the image tag of the Jaeger operator. /// Useful when updating the Jaeger operator dependency chart to ensure the new chart uses the updated image tag. pub(crate) fn jaeger_operator_image_tag(&self) -> &str { @@ -418,6 +431,11 @@ impl Base { fn jaeger_agent_init_container(&self) -> &[Container] { self.jaeger.agent_init_container() } + + /// This returns the array of kubernetes initContainer objects for jaeger collector. + fn jaeger_collector_init_container(&self) -> &[Container] { + self.jaeger.collector_init_container() + } } /// This is used to deserialize the .base.initRestContainer object. @@ -434,7 +452,7 @@ impl InitRestContainer { } /// This is used to deserialize various 'containers' yaml objects. -#[derive(Deserialize)] +#[derive(Default, Deserialize)] struct GenericContainers { /// Container config. containers: Vec, @@ -447,6 +465,21 @@ impl GenericContainers { } } +/// This is used to deserialize various 'initContainer' yaml objects. +#[derive(Default, Deserialize)] +#[serde(rename_all(deserialize = "camelCase"))] +struct GenericInitContainer { + /// InitContainer config. + init_container: Vec, +} + +impl GenericInitContainer { + /// This returns the init containers from the '.initContainer' item. + fn init_container(&self) -> &[Container] { + self.init_container.as_slice() + } +} + /// This is used to deserialize the yaml object 'agents.core'. #[derive(Deserialize)] struct Core { @@ -664,6 +697,10 @@ impl Csi { fn deprecated_node_csi_mount_path(&self) -> &str { self.node.deprecated_plugin_mount_path() } + + fn csi_node_init_containers(&self) -> &[Container] { + self.node.init_containers() + } } /// This contains the image tags for the CSI sidecar containers. @@ -721,10 +758,13 @@ impl CsiImage { /// This is used to deserialize the yaml object 'csi.node'. #[derive(Deserialize)] +#[serde(rename_all(deserialize = "camelCase"))] struct CsiNode { nvme: CsiNodeNvme, #[serde(default, rename(deserialize = "pluginMounthPath"))] deprecated_plugin_mount_path: String, + #[serde(default)] + init_containers: GenericContainers, } impl CsiNode { @@ -737,6 +777,10 @@ impl CsiNode { fn deprecated_plugin_mount_path(&self) -> &str { self.deprecated_plugin_mount_path.as_str() } + + fn init_containers(&self) -> &[Container] { + self.init_containers.containers() + } } /// This is used to deserialize the yaml object 'csi.node.nvme'. @@ -790,6 +834,10 @@ impl LokiStack { self.loki.image_tag() } + fn loki_init_containers(&self) -> &[Container] { + self.loki.init_containers() + } + /// This is a getter for the initContainer array from promtail chart v6.13.1. fn promtail_init_container(&self) -> Vec { self.promtail.init_container() @@ -931,15 +979,20 @@ impl Logstash { /// This is used to deserialize the YAML object 'loki-stack.loki'. #[derive(Default, Deserialize)] -#[serde(default)] +#[serde(default, rename_all(deserialize = "camelCase"))] struct Loki { image: GenericImage, + init_containers: Vec, } impl Loki { fn image_tag(&self) -> &str { self.image.tag() } + + fn init_containers(&self) -> &[Container] { + self.init_containers.as_slice() + } } /// This is used to deserialize the yaml object 'loki-stack.prometheus'. @@ -1231,7 +1284,9 @@ impl LocalpvProvisionerHelperPod { /// This is used to deserialize the '.jaeger' yaml object. #[derive(Deserialize)] struct Jaeger { - agent: JaegerAgent, + agent: GenericInitContainer, + #[serde(default)] + collector: GenericInitContainer, } impl Jaeger { @@ -1239,19 +1294,9 @@ impl Jaeger { fn agent_init_container(&self) -> &[Container] { self.agent.init_container() } -} -/// This is used to deserialize the '.jaeger.agent' yaml object. -#[derive(Deserialize)] -#[serde(rename_all(deserialize = "camelCase"))] -struct JaegerAgent { - init_container: Vec, -} - -impl JaegerAgent { - /// This returns the init containers from the base jaeger agent. - fn init_container(&self) -> &[Container] { - self.init_container.as_slice() + fn collector_init_container(&self) -> &[Container] { + self.collector.init_container() } } diff --git a/k8s/upgrade/src/helm/values.rs b/k8s/upgrade/src/helm/values.rs index e855ffdbb..30417151f 100644 --- a/k8s/upgrade/src/helm/values.rs +++ b/k8s/upgrade/src/helm/values.rs @@ -1,15 +1,18 @@ use crate::{ common::{ constants::{ - KUBE_API_PAGE_SIZE, TWO_DOT_FIVE, TWO_DOT_FOUR, TWO_DOT_ONE, TWO_DOT_O_RC_ONE, - TWO_DOT_SEVEN_DOT_THREE, TWO_DOT_SEVEN_DOT_TWO, TWO_DOT_SIX, TWO_DOT_THREE, + KUBE_API_PAGE_SIZE, TWO_DOT_EIGHT, TWO_DOT_FIVE, TWO_DOT_FOUR, TWO_DOT_ONE, + TWO_DOT_O_RC_ONE, TWO_DOT_SEVEN_DOT_THREE, TWO_DOT_SEVEN_DOT_TWO, TWO_DOT_SIX, + TWO_DOT_THREE, }, error::{ DeserializePromtailExtraConfig, ListCrds, Result, SemverParse, SerializeBaseInitContainersToJson, SerializeBaseInitCoreContainersToJson, SerializeBaseInitHaNodeContainersToJson, SerializeBaseInitRestContainerToJson, - SerializeJaegerAgentInitContainerToJson, SerializePromtailConfigClientToJson, - SerializePromtailExtraConfigToJson, SerializePromtailInitContainerToJson, + SerializeCsiNodeInitContainersToJson, SerializeJaegerAgentInitContainerToJson, + SerializeJaegerCollectorInitContainerToJson, SerializeLokiInitContainersToJson, + SerializePromtailConfigClientToJson, SerializePromtailExtraConfigToJson, + SerializePromtailInitContainerToJson, }, file::write_to_tempfile, kube::client as KubeClient, @@ -502,6 +505,89 @@ where )?; } + // Special-case values for 2.8.0. + if source_version.ge(&two_dot_o_rc_one) && source_version.lt(&TWO_DOT_EIGHT) { + let image_tag_to_remove = String::from("busybox:latest"); + // if base.jaeger.collector.initContainer elements contain the image key + if source_values + .base_jaeger_collector_init_container() + .iter() + .filter_map(|container| container.image.clone()) + .collect::>() + .contains(&image_tag_to_remove) + { + let jaeger_collector_init_container_key = + YamlKey::try_from(".base.jaeger.collector.initContainer")?; + + yq.delete_object( + jaeger_collector_init_container_key.clone(), + upgrade_values_file.path(), + )?; + + for container in target_values.base_jaeger_collector_init_container() { + let container_val = serde_json::to_string(container).context( + SerializeJaegerCollectorInitContainerToJson { + object: container.clone(), + }, + )?; + yq.append_to_array( + jaeger_collector_init_container_key.clone(), + container_val, + upgrade_values_file.path(), + )?; + } + } + + let container_to_replace = String::from("nvme-tcp-probe"); + if source_values + .csi_node_init_containers() + .iter() + .map(|container| container.name.clone()) + .collect::>() + .contains(&container_to_replace) + { + let csi_node_init_containers_key = + YamlKey::try_from(".csi.node.initContainers.containers")?; + + yq.delete_object( + csi_node_init_containers_key.clone(), + upgrade_values_file.path(), + )?; + + for container in target_values.csi_node_init_containers() { + let container_val = serde_json::to_string(container).context( + SerializeCsiNodeInitContainersToJson { + object: container.clone(), + }, + )?; + yq.append_to_array( + csi_node_init_containers_key.clone(), + container_val, + upgrade_values_file.path(), + )?; + } + } + + { + let loki_init_containers = YamlKey::try_from(".loki-stack.loki.initContainers")?; + + yq.delete_object(loki_init_containers.clone(), upgrade_values_file.path())?; + + for container in target_values.loki_stack_loki_init_containers() { + let container_val = serde_json::to_string(container).context( + SerializeLokiInitContainersToJson { + object: container.clone(), + }, + )?; + yq.append_to_array( + loki_init_containers.clone(), + container_val, + upgrade_values_file.path(), + )?; + } + } + } + // Default options. // Image tag is set because the high_priority file is the user's source options file. // The target's image tag needs to be set for PRODUCT upgrade.