diff --git a/pkg/resourceinterpreter/defaultinterpreter/prune/prune.go b/pkg/resourceinterpreter/defaultinterpreter/prune/prune.go index 9ac31ba0b..3710f9d4d 100644 --- a/pkg/resourceinterpreter/defaultinterpreter/prune/prune.go +++ b/pkg/resourceinterpreter/defaultinterpreter/prune/prune.go @@ -14,7 +14,7 @@ import ( // RemoveIrrelevantField used to remove fields that generated by kube-apiserver and no need(or can't) propagate to // member clusters. -func RemoveIrrelevantField(workload *unstructured.Unstructured) error { +func RemoveIrrelevantField(workload *unstructured.Unstructured, extraHooks ...func(*unstructured.Unstructured)) error { // populated by the kubernetes. unstructured.RemoveNestedField(workload.Object, "metadata", "creationTimestamp") @@ -63,9 +63,10 @@ func RemoveIrrelevantField(workload *unstructured.Unstructured) error { if err != nil { return err } - if job.Spec.ManualSelector == nil || !*job.Spec.ManualSelector { - return removeGenerateSelectorOfJob(workload) + if err = removeGenerateSelectorOfJob(workload); err != nil { + return err + } } } @@ -83,6 +84,9 @@ func RemoveIrrelevantField(workload *unstructured.Unstructured) error { } } + for i := range extraHooks { + extraHooks[i](workload) + } return nil } @@ -121,3 +125,16 @@ func removeGenerateSelectorOfJob(workload *unstructured.Unstructured) error { } return nil } + +// RemoveJobTTLSeconds removes the '.spec.ttlSecondsAfterFinished' from a Job. +// The reason for removing it is that the Job propagated by Karmada probably be automatically deleted +// from member clusters(by 'ttl-after-finished' controller in member clusters). That will cause a conflict if +// Karmada tries to re-create it. See https://github.com/karmada-io/karmada/issues/2197 for more details. +// +// It is recommended to enable the `ttl-after-finished` controller in the Karmada control plane. +// See https://karmada.io/docs/administrator/configuration/configure-controllers#ttl-after-finished for more details. +func RemoveJobTTLSeconds(workload *unstructured.Unstructured) { + if workload.GetKind() == util.JobKind { + unstructured.RemoveNestedField(workload.Object, "spec", "ttlSecondsAfterFinished") + } +} diff --git a/pkg/webhook/work/mutating.go b/pkg/webhook/work/mutating.go index 6dd8da8b3..c6882de16 100644 --- a/pkg/webhook/work/mutating.go +++ b/pkg/webhook/work/mutating.go @@ -43,7 +43,7 @@ func (a *MutatingAdmission) Handle(ctx context.Context, req admission.Request) a return admission.Errored(http.StatusInternalServerError, err) } - err = prune.RemoveIrrelevantField(workloadObj) + err = prune.RemoveIrrelevantField(workloadObj, prune.RemoveJobTTLSeconds) if err != nil { klog.Errorf("Failed to remove irrelevant field for work(%s): %v", work.Name, err) return admission.Errored(http.StatusInternalServerError, err)