Skip to content

Commit efbb209

Browse files
committed
ignore jobs on reapply, merge instead of apply for existing objects
1 parent 36ebe5e commit efbb209

File tree

1 file changed

+50
-8
lines changed
  • rust/stackable-cockpit/src/utils/k8s

1 file changed

+50
-8
lines changed

rust/stackable-cockpit/src/utils/k8s/client.rs

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use snafu::{OptionExt, ResultExt, Snafu};
1515
use stackable_operator::{commons::listener::Listener, kvp::Labels};
1616
use tokio::sync::RwLock;
1717
use tracing::{Span, info, instrument};
18-
use tracing_indicatif::span_ext::IndicatifSpanExt as _;
18+
use tracing_indicatif::{indicatif_println, span_ext::IndicatifSpanExt as _};
1919

2020
#[cfg(doc)]
2121
use crate::utils::k8s::ListParamsExt;
@@ -114,6 +114,7 @@ impl Client {
114114

115115
// TODO (Techassi): Impl IntoIterator for Labels
116116
let labels: BTreeMap<String, String> = labels.into();
117+
let mut failed_manifests = Vec::new();
117118

118119
for manifest in serde_yaml::Deserializer::from_str(manifests) {
119120
let mut object = DynamicObject::deserialize(manifest).context(DeserializeYamlSnafu)?;
@@ -144,13 +145,54 @@ impl Client {
144145
}
145146
};
146147

147-
api.patch(
148-
&object.name_any(),
149-
&PatchParams::apply("stackablectl"),
150-
&Patch::Apply(object),
151-
)
152-
.await
153-
.context(KubeClientPatchSnafu)?;
148+
if let Some(existing_object) = api
149+
.get_opt(&object.name_any())
150+
.await
151+
.context(KubeClientFetchSnafu)?
152+
{
153+
object.metadata.resource_version = existing_object.resource_version();
154+
155+
match api
156+
.patch(
157+
&object.name_any(),
158+
&PatchParams::apply("stackablectl"),
159+
&Patch::Merge(object.clone()),
160+
)
161+
.await
162+
{
163+
Ok(result) => result,
164+
Err(e) => {
165+
// If re-applying a Job fails due to immutability, print out the failed manifests instead of erroring out,
166+
// so the user can decide if the existing Job needs a deletion and recreation
167+
if resource.kind == *"Job" && e.to_string().contains("field is immutable") {
168+
failed_manifests.push(format!(
169+
"{kind} {object_name}",
170+
kind = resource.kind,
171+
object_name = object.name_any().clone()
172+
));
173+
object
174+
} else {
175+
indicatif_println!(
176+
"{object_name} {object:?}",
177+
object_name = &object.name_any()
178+
);
179+
return Err(e).context(KubeClientPatchSnafu);
180+
}
181+
}
182+
};
183+
} else {
184+
api.patch(
185+
&object.name_any(),
186+
&PatchParams::apply("stackablectl"),
187+
&Patch::Apply(object.clone()),
188+
)
189+
.await
190+
.context(KubeClientPatchSnafu)?;
191+
}
192+
}
193+
194+
if !failed_manifests.is_empty() {
195+
indicatif_println!("Failed manifests due to immutability: {failed_manifests:?}");
154196
}
155197

156198
Ok(())

0 commit comments

Comments
 (0)