in pkg/webhooks/admission/jobs/validate/admit_job.go [220:268]
func validateJobUpdate(old, new *v1alpha1.Job) error {
var totalReplicas int32
for _, task := range new.Spec.Tasks {
if task.Replicas < 0 {
return fmt.Errorf("'replicas' must be >= 0 in task: %s", task.Name)
}
if task.MinAvailable != nil && *task.MinAvailable > task.Replicas {
return fmt.Errorf("'minAvailable' must be <= 'replicas' in task: %s;", task.Name)
}
// count replicas
totalReplicas += task.Replicas
}
if new.Spec.MinAvailable > totalReplicas {
return fmt.Errorf("job 'minAvailable' must not be greater than total replicas")
}
if new.Spec.MinAvailable < 0 {
return fmt.Errorf("job 'minAvailable' must be >= 0")
}
if len(old.Spec.Tasks) != len(new.Spec.Tasks) {
return fmt.Errorf("job updates may not add or remove tasks")
}
// other fields under spec are not allowed to mutate
new.Spec.MinAvailable = old.Spec.MinAvailable
new.Spec.PriorityClassName = old.Spec.PriorityClassName
for i := range new.Spec.Tasks {
new.Spec.Tasks[i].Replicas = old.Spec.Tasks[i].Replicas
new.Spec.Tasks[i].MinAvailable = old.Spec.Tasks[i].MinAvailable
}
// job controller will update the pvc name if not provided
for i := range new.Spec.Volumes {
if new.Spec.Volumes[i].VolumeClaim != nil {
new.Spec.Volumes[i].VolumeClaimName = ""
}
}
for i := range old.Spec.Volumes {
if old.Spec.Volumes[i].VolumeClaim != nil {
old.Spec.Volumes[i].VolumeClaimName = ""
}
}
if !apiequality.Semantic.DeepEqual(new.Spec, old.Spec) {
return fmt.Errorf("job updates may not change fields other than `minAvailable`, `tasks[*].replicas under spec`")
}
return nil
}