Skip to content

Commit 5a59aaa

Browse files
committed
chore: Add demo/stack labels if applicable
1 parent 127b790 commit 5a59aaa

9 files changed

Lines changed: 156 additions & 59 deletions

File tree

rust/operator-binary/src/container.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use stackable_operator::{
3737
apimachinery::pkg::util::intstr::IntOrString,
3838
},
3939
kube::{ResourceExt, core::ObjectMeta},
40-
kvp::Labels,
40+
kvp::{LabelExt, Labels},
4141
product_logging::{
4242
self,
4343
framework::{
@@ -428,13 +428,19 @@ impl ContainerConfig {
428428
.unwrap();
429429

430430
let pvcs = vec![
431-
node.resources.storage.data.build_pvc(
432-
ContainerConfig::DATA_VOLUME_MOUNT_NAME,
433-
Some(vec!["ReadWriteOnce"]),
434-
),
431+
node.resources
432+
.storage
433+
.data
434+
.build_pvc(
435+
ContainerConfig::DATA_VOLUME_MOUNT_NAME,
436+
Some(vec!["ReadWriteOnce"]),
437+
)
438+
.add_labels(labels.clone())
439+
.to_owned(),
435440
PersistentVolumeClaim {
436441
metadata: ObjectMeta {
437442
name: Some(LISTENER_VOLUME_NAME.to_string()),
443+
labels: Some(labels.clone().into()),
438444
..listener.metadata.unwrap()
439445
},
440446
spec: Some(listener.spec),
@@ -444,14 +450,24 @@ impl ContainerConfig {
444450

445451
Ok(pvcs)
446452
}
447-
AnyNodeConfig::Journal(node) => Ok(vec![node.resources.storage.data.build_pvc(
448-
ContainerConfig::DATA_VOLUME_MOUNT_NAME,
449-
Some(vec!["ReadWriteOnce"]),
450-
)]),
453+
AnyNodeConfig::Journal(node) => Ok(vec![
454+
node.resources
455+
.storage
456+
.data
457+
.build_pvc(
458+
ContainerConfig::DATA_VOLUME_MOUNT_NAME,
459+
Some(vec!["ReadWriteOnce"]),
460+
)
461+
.add_labels(labels.clone())
462+
.to_owned(),
463+
]),
451464
AnyNodeConfig::Data(node) => Ok(DataNodeStorageConfig {
452465
pvcs: node.resources.storage.clone(),
453466
}
454-
.build_pvcs()),
467+
.build_pvcs()
468+
.into_iter()
469+
.map(|mut pvc| pvc.add_labels(labels.clone()).to_owned())
470+
.collect()),
455471
}
456472
}
457473

rust/operator-binary/src/crd/storage.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,11 @@ fn default_number_of_datanode_pvcs() -> Option<u16> {
156156
Some(1)
157157
}
158158

159-
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
159+
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize, Default)]
160160
#[serde(rename_all = "PascalCase")]
161161
pub enum HdfsStorageType {
162162
Archive,
163+
#[default]
163164
Disk,
164165
#[serde(rename = "SSD")]
165166
Ssd,
@@ -169,12 +170,6 @@ pub enum HdfsStorageType {
169170

170171
impl Atomic for HdfsStorageType {}
171172

172-
impl Default for HdfsStorageType {
173-
fn default() -> Self {
174-
Self::Disk
175-
}
176-
}
177-
178173
impl HdfsStorageType {
179174
pub fn as_hdfs_config_literal(&self) -> &str {
180175
match self {

rust/operator-binary/src/discovery.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use stackable_operator::{
44
commons::product_image_selection::ResolvedProductImage,
55
k8s_openapi::api::core::v1::ConfigMap,
66
kube::{ResourceExt, runtime::reflector::ObjectRef},
7+
kvp::{LabelError, Labels},
78
utils::cluster_info::KubernetesClusterInfo,
89
};
910

@@ -15,6 +16,7 @@ use crate::{
1516
constants::{CORE_SITE_XML, HDFS_SITE_XML},
1617
v1alpha1,
1718
},
19+
labels::add_stackable_labels,
1820
security::kerberos,
1921
};
2022

@@ -39,6 +41,9 @@ pub enum Error {
3941
source: stackable_operator::builder::meta::Error,
4042
},
4143

44+
#[snafu(display("failed to build stackable label"))]
45+
BuildStackableLabel { source: LabelError },
46+
4247
#[snafu(display("failed to build security discovery config map"))]
4348
BuildSecurityDiscoveryConfigMap { source: kerberos::Error },
4449
}
@@ -66,6 +71,10 @@ pub fn build_discovery_configmap(
6671
"discovery",
6772
))
6873
.context(ObjectMetaSnafu)?
74+
.with_labels(
75+
add_stackable_labels(Labels::new(), hdfs.metadata.labels.clone())
76+
.context(BuildStackableLabelSnafu)?,
77+
)
6978
.build();
7079

7180
ConfigMapBuilder::new()

rust/operator-binary/src/event.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub fn build_invalid_replica_message(
6060
Some(format!(
6161
"{role_name}: only has {replicas} replicas configured, it is strongly recommended to use at least [{min_replicas}]"
6262
))
63-
} else if !role.replicas_can_be_even() && replicas % 2 == 0 {
63+
} else if !role.replicas_can_be_even() && replicas.is_multiple_of(2) {
6464
Some(format!(
6565
"{role_name}: currently has an even number of replicas [{replicas}], but should always have an odd number to ensure quorum"
6666
))

rust/operator-binary/src/hdfs_controller.rs

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ use crate::{
6363
},
6464
discovery::{self, build_discovery_configmap},
6565
event::{build_invalid_replica_message, publish_warning_event},
66+
labels::add_stackable_labels,
6667
operations::{
6768
graceful_shutdown::{self, add_graceful_shutdown_config},
6869
pdb::add_pdbs,
@@ -222,6 +223,9 @@ pub enum Error {
222223
#[snafu(display("failed to build cluster resources label"))]
223224
BuildClusterResourcesLabel { source: LabelError },
224225

226+
#[snafu(display("failed to build stackable label"))]
227+
BuildStackableLabel { source: LabelError },
228+
225229
#[snafu(display("failed to build role-group volume claim templates from config"))]
226230
BuildRoleGroupVolumeClaimTemplates { source: container::Error },
227231

@@ -320,9 +324,13 @@ pub async fn reconcile_hdfs(
320324
let (rbac_sa, rbac_rolebinding) = build_rbac_resources(
321325
hdfs,
322326
APP_NAME,
323-
cluster_resources
324-
.get_required_labels()
325-
.context(BuildClusterResourcesLabelSnafu)?,
327+
add_stackable_labels(
328+
cluster_resources
329+
.get_required_labels()
330+
.context(BuildClusterResourcesLabelSnafu)?,
331+
hdfs.metadata.labels.clone(),
332+
)
333+
.context(BuildStackableLabelSnafu)?,
326334
)
327335
.context(BuildRbacResourcesSnafu)?;
328336

@@ -383,12 +391,6 @@ pub async fn reconcile_hdfs(
383391
}
384392

385393
for (rolegroup_name, rolegroup_config) in group_config.iter() {
386-
let merged_config = role
387-
.merged_config(hdfs, rolegroup_name)
388-
.context(ConfigMergeSnafu)?;
389-
390-
let env_overrides = rolegroup_config.get(&PropertyNameKind::Env);
391-
392394
let rolegroup_ref = hdfs.rolegroup_ref(role_name, rolegroup_name);
393395

394396
let rg_service =
@@ -398,6 +400,26 @@ pub async fn reconcile_hdfs(
398400
rolegroup_metrics_service(hdfs, &role, &rolegroup_ref, &resolved_product_image)
399401
.context(BuildServiceSnafu)?;
400402

403+
let rg_service_name = rg_service.name_any();
404+
let rg_metrics_service_name = rg_metrics_service.name_any();
405+
406+
cluster_resources
407+
.add(client, rg_service)
408+
.await
409+
.with_context(|_| ApplyRoleGroupServiceSnafu {
410+
name: rg_service_name,
411+
})?;
412+
cluster_resources
413+
.add(client, rg_metrics_service)
414+
.await
415+
.with_context(|_| ApplyRoleGroupServiceSnafu {
416+
name: rg_metrics_service_name,
417+
})?;
418+
419+
let merged_config = role
420+
.merged_config(hdfs, rolegroup_name)
421+
.context(ConfigMergeSnafu)?;
422+
401423
// We need to split the creation and the usage of the "metadata" variable in two statements.
402424
// to avoid the compiler error "E0716 (temporary value dropped while borrowed)".
403425
let mut metadata = ObjectMetaBuilder::new();
@@ -415,7 +437,11 @@ pub async fn reconcile_hdfs(
415437
&rolegroup_ref.role,
416438
&rolegroup_ref.role_group,
417439
))
418-
.context(ObjectMetaSnafu)?;
440+
.context(ObjectMetaSnafu)?
441+
.with_labels(
442+
add_stackable_labels(Labels::new(), hdfs.metadata.labels.clone())
443+
.context(BuildStackableLabelSnafu)?,
444+
);
419445

420446
let rg_configmap = rolegroup_config_map(
421447
hdfs,
@@ -429,6 +455,17 @@ pub async fn reconcile_hdfs(
429455
&hdfs_opa_config,
430456
)?;
431457

458+
let rg_configmap_name = rg_configmap.name_any();
459+
460+
cluster_resources
461+
.add(client, rg_configmap.clone())
462+
.await
463+
.with_context(|_| ApplyRoleGroupConfigMapSnafu {
464+
name: rg_configmap_name,
465+
})?;
466+
467+
let env_overrides = rolegroup_config.get(&PropertyNameKind::Env);
468+
432469
let rg_statefulset = rolegroup_statefulset(
433470
hdfs,
434471
&client.kubernetes_cluster_info,
@@ -442,29 +479,6 @@ pub async fn reconcile_hdfs(
442479
&rbac_sa,
443480
)?;
444481

445-
let rg_service_name = rg_service.name_any();
446-
let rg_metrics_service_name = rg_metrics_service.name_any();
447-
448-
cluster_resources
449-
.add(client, rg_service)
450-
.await
451-
.with_context(|_| ApplyRoleGroupServiceSnafu {
452-
name: rg_service_name,
453-
})?;
454-
cluster_resources
455-
.add(client, rg_metrics_service)
456-
.await
457-
.with_context(|_| ApplyRoleGroupServiceSnafu {
458-
name: rg_metrics_service_name,
459-
})?;
460-
let rg_configmap_name = rg_configmap.name_any();
461-
cluster_resources
462-
.add(client, rg_configmap.clone())
463-
.await
464-
.with_context(|_| ApplyRoleGroupConfigMapSnafu {
465-
name: rg_configmap_name,
466-
})?;
467-
468482
// Note: The StatefulSet needs to be applied after all ConfigMaps and Secrets it mounts
469483
// to prevent unnecessary Pod restarts.
470484
// See https://github.com/stackabletech/commons-operator/issues/111 for details.
@@ -865,7 +879,11 @@ fn rolegroup_statefulset(
865879
env_overrides,
866880
&hdfs.spec.cluster_config.zookeeper_config_map_name,
867881
namenode_podrefs,
868-
&rolegroup_selector_labels,
882+
&add_stackable_labels(
883+
rolegroup_selector_labels.clone(),
884+
hdfs.metadata.labels.clone(),
885+
)
886+
.context(BuildStackableLabelSnafu)?,
869887
)
870888
.context(FailedToCreateContainerAndVolumeConfigurationSnafu)?;
871889

@@ -881,8 +899,15 @@ fn rolegroup_statefulset(
881899
}
882900

883901
// The same comment regarding labels is valid here as it is for the ContainerConfig::add_containers_and_volumes() call above.
884-
let pvcs = ContainerConfig::volume_claim_templates(merged_config, &rolegroup_selector_labels)
885-
.context(BuildRoleGroupVolumeClaimTemplatesSnafu)?;
902+
let pvcs = ContainerConfig::volume_claim_templates(
903+
merged_config,
904+
&add_stackable_labels(
905+
rolegroup_selector_labels.clone(),
906+
hdfs.metadata.labels.clone(),
907+
)
908+
.context(BuildStackableLabelSnafu)?,
909+
)
910+
.context(BuildRoleGroupVolumeClaimTemplatesSnafu)?;
886911

887912
let statefulset_spec = StatefulSetSpec {
888913
pod_management_policy: Some("OrderedReady".to_string()),

rust/operator-binary/src/labels.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use std::collections::BTreeMap;
2+
3+
use stackable_operator::kvp::{Label, LabelError, Labels};
4+
5+
/// Add Stackable stack/demo labels to the provided Labels if present in the cluster labels
6+
///
7+
/// These Stackable labels are used, for example, by stackablectl to delete stack/demo resources
8+
/// The "stackable.tech/vendor" label is already added by [`ObjectMetaBuilder::with_recommended_labels()`]
9+
pub(crate) fn add_stackable_labels(
10+
mut labels: Labels,
11+
cluster_labels: Option<BTreeMap<String, String>>,
12+
) -> Result<Labels, LabelError> {
13+
if let Some(cluster_labels) = cluster_labels {
14+
for (key, value) in cluster_labels {
15+
match key.as_str() {
16+
"stackable.tech/stack" | "stackable.tech/demo" => {
17+
labels.insert(Label::try_from((key, value))?);
18+
}
19+
_ => {}
20+
}
21+
}
22+
}
23+
24+
Ok(labels)
25+
}

rust/operator-binary/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ mod discovery;
4848
mod event;
4949
mod hdfs_clusterrolebinding_nodes_controller;
5050
mod hdfs_controller;
51+
mod labels;
5152
mod operations;
5253
mod product_logging;
5354
mod security;

rust/operator-binary/src/operations/pdb.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ use std::cmp::{max, min};
22

33
use snafu::{ResultExt, Snafu};
44
use stackable_operator::{
5-
builder::pdb::PodDisruptionBudgetBuilder, client::Client, cluster_resources::ClusterResources,
6-
commons::pdb::PdbConfig, kube::ResourceExt,
5+
builder::pdb::PodDisruptionBudgetBuilder,
6+
client::Client,
7+
cluster_resources::ClusterResources,
8+
commons::pdb::PdbConfig,
9+
kube::ResourceExt,
10+
kvp::{LabelError, LabelExt, Labels},
711
};
812

913
use crate::{
1014
OPERATOR_NAME,
1115
crd::{HdfsNodeRole, constants::APP_NAME, v1alpha1},
1216
hdfs_controller::RESOURCE_MANAGER_HDFS_CONTROLLER,
17+
labels::add_stackable_labels,
1318
};
1419

1520
#[derive(Snafu, Debug)]
@@ -25,6 +30,9 @@ pub enum Error {
2530
source: stackable_operator::cluster_resources::Error,
2631
name: String,
2732
},
33+
34+
#[snafu(display("failed to build stackable label"))]
35+
BuildStackableLabel { source: LabelError },
2836
}
2937

3038
pub async fn add_pdbs(
@@ -45,7 +53,7 @@ pub async fn add_pdbs(
4553
),
4654
HdfsNodeRole::Journal => max_unavailable_journal_nodes(),
4755
});
48-
let pdb = PodDisruptionBudgetBuilder::new_with_role(
56+
let mut pdb = PodDisruptionBudgetBuilder::new_with_role(
4957
hdfs,
5058
APP_NAME,
5159
&role.to_string(),
@@ -57,6 +65,12 @@ pub async fn add_pdbs(
5765
})?
5866
.with_max_unavailable(max_unavailable)
5967
.build();
68+
69+
pdb.add_labels(
70+
add_stackable_labels(Labels::new(), hdfs.metadata.labels.clone())
71+
.context(BuildStackableLabelSnafu)?,
72+
);
73+
6074
let pdb_name = pdb.name_any();
6175
cluster_resources
6276
.add(client, pdb)

0 commit comments

Comments
 (0)