sync check in batch stategy to match AllowMutableSchedulingDirectives and AllowMutablePodResources

This commit is contained in:
Kevin Hannon
2026-01-07 12:29:51 -05:00
parent 0f4705e12e
commit 986020d6bd
2 changed files with 69 additions and 1 deletions

View File

@@ -192,7 +192,7 @@ func validationOptionsForJob(newJob, oldJob *batch.Job) batchvalidation.JobValid
notStarted := oldJob.Status.StartTime == nil
opts.AllowMutableSchedulingDirectives = suspended && notStarted
if utilfeature.DefaultFeatureGate.Enabled(features.MutablePodResourcesForSuspendedJobs) {
opts.AllowMutablePodResources = batchvalidation.IsConditionTrue(oldJob.Status.Conditions, batch.JobSuspended) && oldJob.Status.Active == 0
opts.AllowMutablePodResources = suspended && batchvalidation.IsConditionTrue(oldJob.Status.Conditions, batch.JobSuspended) && oldJob.Status.Active == 0
}
if utilfeature.DefaultFeatureGate.Enabled(features.MutableSchedulingDirectivesForSuspendedJobs) {
opts.AllowMutableSchedulingDirectives = suspended && batchvalidation.IsConditionTrue(oldJob.Status.Conditions, batch.JobSuspended) && oldJob.Status.Active == 0

View File

@@ -1447,6 +1447,40 @@ func TestJobStrategy_ValidateUpdate_MutablePodResources(t *testing.T) {
{Type: field.ErrorTypeInvalid, Field: "spec.template.spec"},
},
},
"feature gate enabled - job resuming (suspend=false) but JobSuspended condition still true - resource updates rejected": {
enableFeatureGate: true,
job: &batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "myjob",
Namespace: metav1.NamespaceDefault,
ResourceVersion: "0",
},
Spec: batch.JobSpec{
Selector: validSelector,
Template: validPodTemplateSpec,
ManualSelector: ptr.To(true),
Parallelism: ptr.To[int32](1),
Suspend: ptr.To(false),
},
Status: batch.JobStatus{
Active: 0,
Conditions: []batch.JobCondition{
{
Type: batch.JobSuspended,
Status: api.ConditionStatus(metav1.ConditionTrue),
},
},
},
},
update: func(job *batch.Job) {
job.Spec.Template.Spec.Containers[0].Resources.Requests = api.ResourceList{
api.ResourceCPU: resource.MustParse("200m"),
}
},
wantErrs: field.ErrorList{
{Type: field.ErrorTypeInvalid, Field: "spec.template"},
},
},
}
for name, tc := range cases {
@@ -4251,6 +4285,40 @@ func TestJobStrategy_ValidateUpdate_MutableSchedulingDirectives(t *testing.T) {
{Type: field.ErrorTypeInvalid, Field: "spec.template"},
},
},
"feature gate enabled - job resuming (suspend=false) but JobSuspended condition still true - scheduling directives update rejected": {
enableFeatureGate: true,
job: &batch.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "myjob",
Namespace: metav1.NamespaceDefault,
ResourceVersion: "0",
},
Spec: batch.JobSpec{
Selector: validSelector,
Template: validPodTemplateSpec,
ManualSelector: ptr.To(true),
Parallelism: ptr.To[int32](1),
Suspend: ptr.To(false),
},
Status: batch.JobStatus{
Active: 0,
Conditions: []batch.JobCondition{
{
Type: batch.JobSuspended,
Status: api.ConditionStatus(metav1.ConditionTrue),
},
},
},
},
update: func(job *batch.Job) {
job.Spec.Template.Spec.NodeSelector = map[string]string{
"key": "value",
}
},
wantErrs: field.ErrorList{
{Type: field.ErrorTypeInvalid, Field: "spec.template"},
},
},
}
for name, tc := range cases {