From b609faf3a02fe717409af392a8a7e94829be4fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Skocze=C5=84?= Date: Fri, 5 Jun 2026 12:46:40 +0000 Subject: [PATCH 1/3] Remove WorkloadAwarePreemption feature gates references from API --- pkg/apis/scheduling/types.go | 18 ------- .../k8s.io/api/scheduling/v1alpha3/types.go | 50 +++++-------------- 2 files changed, 13 insertions(+), 55 deletions(-) diff --git a/pkg/apis/scheduling/types.go b/pkg/apis/scheduling/types.go index f2ce3037b3d..a878afe92b4 100644 --- a/pkg/apis/scheduling/types.go +++ b/pkg/apis/scheduling/types.go @@ -215,10 +215,7 @@ type PodGroupTemplate struct { // DisruptionMode defines the mode in which a given PodGroup can be disrupted. // One of Single, All. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional DisruptionMode *DisruptionMode @@ -226,10 +223,7 @@ type PodGroupTemplate struct { // a pod group created from this template. If no priority class is specified, admission // control can set this to the global default priority class if it exists. Otherwise, // pod groups created from this template will have the priority set to zero. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional PriorityClassName string @@ -238,10 +232,7 @@ type PodGroupTemplate struct { // Priority Admission Controller is enabled, it prevents users from setting this field. // The admission controller populates this field from PriorityClassName. // The higher the value, the higher the priority. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional Priority *int32 } @@ -437,10 +428,7 @@ type PodGroupSpec struct { // Controllers are expected to fill this field by copying it from a PodGroupTemplate. // One of Single, All. Defaults to Single if unset. // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional DisruptionMode *DisruptionMode @@ -450,10 +438,7 @@ type PodGroupSpec struct { // (i.e. if no priority class is specified, admission control can set this to the global default // priority class if it exists. Otherwise, the pod group's priority will be zero). // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional PriorityClassName string @@ -463,10 +448,7 @@ type PodGroupSpec struct { // controller populates this field from PriorityClassName. // The higher the value, the higher the priority. // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional Priority *int32 } diff --git a/staging/src/k8s.io/api/scheduling/v1alpha3/types.go b/staging/src/k8s.io/api/scheduling/v1alpha3/types.go index c3bfee0a002..c33db445b9b 100644 --- a/staging/src/k8s.io/api/scheduling/v1alpha3/types.go +++ b/staging/src/k8s.io/api/scheduling/v1alpha3/types.go @@ -164,27 +164,19 @@ type PodGroupTemplate struct { // DisruptionMode defines the mode in which a given PodGroup can be disrupted. // One of Single, All. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:optional DisruptionMode *DisruptionMode `json:"disruptionMode,omitempty" protobuf:"bytes,5,opt,name=disruptionMode"` // PriorityClassName indicates the priority that should be considered when scheduling // a pod group created from this template. If no priority class is specified, admission // control can set this to the global default priority class if it exists. Otherwise, // pod groups created from this template will have the priority set to zero. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:format=k8s-long-name + // +k8s:optional + // +k8s:format=k8s-long-name PriorityClassName string `json:"priorityClassName,omitempty" protobuf:"bytes,6,opt,name=priorityClassName"` // Priority is the value of priority of pod groups created from this template. Various @@ -192,14 +184,10 @@ type PodGroupTemplate struct { // Priority Admission Controller is enabled, it prevents users from setting this field. // The admission controller populates this field from PriorityClassName. // The higher the value, the higher the priority. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:maximum=1000000000 # HighestUserDefinablePriority + // +k8s:optional + // +k8s:maximum=1000000000 # HighestUserDefinablePriority Priority *int32 `json:"priority,omitempty" protobuf:"varint,7,opt,name=priority"` } @@ -427,15 +415,11 @@ type PodGroupSpec struct { // Controllers are expected to fill this field by copying it from a PodGroupTemplate. // One of Single, All. Defaults to Single if unset. // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +default={"single": {}} // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + // +k8s:optional + // +k8s:immutable DisruptionMode *DisruptionMode `json:"disruptionMode,omitempty" protobuf:"bytes,5,opt,name=disruptionMode"` // PriorityClassName defines the priority that should be considered when scheduling this pod group. @@ -444,15 +428,11 @@ type PodGroupSpec struct { // (i.e. if no priority class is specified, admission control can set this to the global default // priority class if it exists. Otherwise, the pod group's priority will be zero). // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:format=k8s-long-name - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + // +k8s:optional + // +k8s:immutable + // +k8s:format=k8s-long-name PriorityClassName string `json:"priorityClassName,omitempty" protobuf:"bytes,6,opt,name=priorityClassName"` // Priority is the value of priority of this pod group. Various system components @@ -461,15 +441,11 @@ type PodGroupSpec struct { // controller populates this field from PriorityClassName. // The higher the value, the higher the priority. // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:maximum=1000000000 # HighestUserDefinablePriority + // +k8s:optional + // +k8s:immutable + // +k8s:maximum=1000000000 # HighestUserDefinablePriority Priority *int32 `json:"priority,omitempty" protobuf:"varint,7,opt,name=priority"` } From 5b94a58696941654d00635a50da0c9613c44a469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Skocze=C5=84?= Date: Fri, 5 Jun 2026 12:48:11 +0000 Subject: [PATCH 2/3] Update API codegen --- api/openapi-spec/swagger.json | 12 +-- ...__scheduling.k8s.io__v1alpha3_openapi.json | 12 +-- .../v1alpha3/zz_generated.validations.go | 76 ++++--------------- pkg/generated/openapi/zz_generated.openapi.go | 12 +-- .../api/scheduling/v1alpha3/generated.proto | 50 ++++-------- .../v1alpha3/types_swagger_doc_generated.go | 12 +-- .../zz_generated.validations.v1alpha3_test.go | 3 - .../zz_generated.validations.v1alpha3_test.go | 3 - 8 files changed, 51 insertions(+), 129 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 26afcd767ab..cc8f9902885 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -20001,19 +20001,19 @@ "properties": { "disruptionMode": { "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha3.DisruptionMode", - "description": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Single, All. Defaults to Single if unset. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled." + "description": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Single, All. Defaults to Single if unset. This field is immutable." }, "podGroupTemplateRef": { "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha3.PodGroupTemplateReference", "description": "PodGroupTemplateRef references an optional PodGroup template within other object (e.g. Workload) that was used to create the PodGroup. This field is immutable." }, "priority": { - "description": "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "description": "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable.", "format": "int32", "type": "integer" }, "priorityClassName": { - "description": "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "description": "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable.", "type": "string" }, "resourceClaims": { @@ -20080,19 +20080,19 @@ "properties": { "disruptionMode": { "$ref": "#/definitions/io.k8s.api.scheduling.v1alpha3.DisruptionMode", - "description": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Single, All. This field is available only when the WorkloadAwarePreemption feature gate is enabled." + "description": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Single, All." }, "name": { "description": "Name is a unique identifier for the PodGroupTemplate within the Workload. It must be a DNS label. This field is immutable.", "type": "string" }, "priority": { - "description": "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "description": "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.", "format": "int32", "type": "integer" }, "priorityClassName": { - "description": "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "description": "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero.", "type": "string" }, "resourceClaims": { diff --git a/api/openapi-spec/v3/apis__scheduling.k8s.io__v1alpha3_openapi.json b/api/openapi-spec/v3/apis__scheduling.k8s.io__v1alpha3_openapi.json index ae2d30f70fb..3fbfa8b5db2 100644 --- a/api/openapi-spec/v3/apis__scheduling.k8s.io__v1alpha3_openapi.json +++ b/api/openapi-spec/v3/apis__scheduling.k8s.io__v1alpha3_openapi.json @@ -241,7 +241,7 @@ "default": { "single": {} }, - "description": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Single, All. Defaults to Single if unset. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled." + "description": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Single, All. Defaults to Single if unset. This field is immutable." }, "podGroupTemplateRef": { "allOf": [ @@ -252,12 +252,12 @@ "description": "PodGroupTemplateRef references an optional PodGroup template within other object (e.g. Workload) that was used to create the PodGroup. This field is immutable." }, "priority": { - "description": "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "description": "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable.", "format": "int32", "type": "integer" }, "priorityClassName": { - "description": "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "description": "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable.", "type": "string" }, "resourceClaims": { @@ -337,7 +337,7 @@ "$ref": "#/components/schemas/io.k8s.api.scheduling.v1alpha3.DisruptionMode" } ], - "description": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Single, All. This field is available only when the WorkloadAwarePreemption feature gate is enabled." + "description": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Single, All." }, "name": { "default": "", @@ -345,12 +345,12 @@ "type": "string" }, "priority": { - "description": "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "description": "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.", "format": "int32", "type": "integer" }, "priorityClassName": { - "description": "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "description": "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero.", "type": "string" }, "resourceClaims": { diff --git a/pkg/apis/scheduling/v1alpha3/zz_generated.validations.go b/pkg/apis/scheduling/v1alpha3/zz_generated.validations.go index f124919fb8c..32d0b6fc4a8 100644 --- a/pkg/apis/scheduling/v1alpha3/zz_generated.validations.go +++ b/pkg/apis/scheduling/v1alpha3/zz_generated.validations.go @@ -722,19 +722,12 @@ func Validate_PodGroupSpec( } // call field-attached validations earlyReturn := false - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.ForbiddenPointer).MarkShortCircuit(); len(e) != 0 { + if e := validate.Immutable(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, // optional fields with default values are effectively required - validate.RequiredPointer).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.Immutable).MarkShortCircuit(); len(e) != 0 { + // optional fields with default values are effectively required + if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } @@ -765,24 +758,17 @@ func Validate_PodGroupSpec( } // call field-attached validations earlyReturn := false - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.ForbiddenValue).MarkShortCircuit(); len(e) != 0 { + if e := validate.Immutable(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.Immutable).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { return // do not proceed } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.LongName); len(e) != 0 { + if e := validate.LongName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { errs = append(errs, e...) } return @@ -807,27 +793,17 @@ func Validate_PodGroupSpec( } // call field-attached validations earlyReturn := false - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.ForbiddenPointer).MarkShortCircuit(); len(e) != 0 { + if e := validate.Immutable(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { errs = append(errs, e...) earlyReturn = true } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.Immutable).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { return // do not proceed } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, - func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int32) field.ErrorList { - return validate.Maximum(ctx, op, fldPath, obj, oldObj, 1000000000) - }); len(e) != 0 { + if e := validate.Maximum(ctx, op, fldPath, obj, oldObj, 1000000000); len(e) != 0 { errs = append(errs, e...) } return @@ -1091,14 +1067,7 @@ func Validate_PodGroupTemplate( } // call field-attached validations earlyReturn := false - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.ForbiddenPointer).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { @@ -1128,20 +1097,13 @@ func Validate_PodGroupTemplate( } // call field-attached validations earlyReturn := false - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.ForbiddenValue).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.OptionalValue).MarkShortCircuit(); len(e) != 0 { + if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { return // do not proceed } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.LongName); len(e) != 0 { + if e := validate.LongName(ctx, op, fldPath, obj, oldObj); len(e) != 0 { errs = append(errs, e...) } return @@ -1166,23 +1128,13 @@ func Validate_PodGroupTemplate( } // call field-attached validations earlyReturn := false - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.ForbiddenPointer).MarkShortCircuit(); len(e) != 0 { - errs = append(errs, e...) - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", false, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { - earlyReturn = true - } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, validate.OptionalPointer).MarkShortCircuit(); len(e) != 0 { + if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkShortCircuit(); len(e) != 0 { earlyReturn = true } if earlyReturn { return // do not proceed } - if e := validate.IfOption(ctx, op, fldPath, obj, oldObj, "WorkloadAwarePreemption", true, - func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int32) field.ErrorList { - return validate.Maximum(ctx, op, fldPath, obj, oldObj, 1000000000) - }); len(e) != 0 { + if e := validate.Maximum(ctx, op, fldPath, obj, oldObj, 1000000000); len(e) != 0 { errs = append(errs, e...) } return diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 4a1803abad1..4c4a0dffba3 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -54303,21 +54303,21 @@ func schema_k8sio_api_scheduling_v1alpha3_PodGroupSpec(ref common.ReferenceCallb }, "disruptionMode": { SchemaProps: spec.SchemaProps{ - Description: "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Single, All. Defaults to Single if unset. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + Description: "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Single, All. Defaults to Single if unset. This field is immutable.", Default: map[string]interface{}{"single": map[string]interface{}{}}, Ref: ref(schedulingv1alpha3.DisruptionMode{}.OpenAPIModelName()), }, }, "priorityClassName": { SchemaProps: spec.SchemaProps{ - Description: "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + Description: "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable.", Type: []string{"string"}, Format: "", }, }, "priority": { SchemaProps: spec.SchemaProps{ - Description: "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + Description: "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable.", Type: []string{"integer"}, Format: "int32", }, @@ -54445,20 +54445,20 @@ func schema_k8sio_api_scheduling_v1alpha3_PodGroupTemplate(ref common.ReferenceC }, "disruptionMode": { SchemaProps: spec.SchemaProps{ - Description: "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Single, All. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + Description: "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Single, All.", Ref: ref(schedulingv1alpha3.DisruptionMode{}.OpenAPIModelName()), }, }, "priorityClassName": { SchemaProps: spec.SchemaProps{ - Description: "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + Description: "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero.", Type: []string{"string"}, Format: "", }, }, "priority": { SchemaProps: spec.SchemaProps{ - Description: "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + Description: "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.", Type: []string{"integer"}, Format: "int32", }, diff --git a/staging/src/k8s.io/api/scheduling/v1alpha3/generated.proto b/staging/src/k8s.io/api/scheduling/v1alpha3/generated.proto index e73ec1c14d9..41968ae13ae 100644 --- a/staging/src/k8s.io/api/scheduling/v1alpha3/generated.proto +++ b/staging/src/k8s.io/api/scheduling/v1alpha3/generated.proto @@ -269,15 +269,11 @@ message PodGroupSpec { // Controllers are expected to fill this field by copying it from a PodGroupTemplate. // One of Single, All. Defaults to Single if unset. // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +default={"single": {}} // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + // +k8s:optional + // +k8s:immutable optional DisruptionMode disruptionMode = 5; // PriorityClassName defines the priority that should be considered when scheduling this pod group. @@ -286,15 +282,11 @@ message PodGroupSpec { // (i.e. if no priority class is specified, admission control can set this to the global default // priority class if it exists. Otherwise, the pod group's priority will be zero). // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:format=k8s-long-name - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable + // +k8s:optional + // +k8s:immutable + // +k8s:format=k8s-long-name optional string priorityClassName = 6; // Priority is the value of priority of this pod group. Various system components @@ -303,15 +295,11 @@ message PodGroupSpec { // controller populates this field from PriorityClassName. // The higher the value, the higher the priority. // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:immutable - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:maximum=1000000000 # HighestUserDefinablePriority + // +k8s:optional + // +k8s:immutable + // +k8s:maximum=1000000000 # HighestUserDefinablePriority optional int32 priority = 7; } @@ -407,27 +395,19 @@ message PodGroupTemplate { // DisruptionMode defines the mode in which a given PodGroup can be disrupted. // One of Single, All. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional + // +k8s:optional optional DisruptionMode disruptionMode = 5; // PriorityClassName indicates the priority that should be considered when scheduling // a pod group created from this template. If no priority class is specified, admission // control can set this to the global default priority class if it exists. Otherwise, // pod groups created from this template will have the priority set to zero. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:format=k8s-long-name + // +k8s:optional + // +k8s:format=k8s-long-name optional string priorityClassName = 6; // Priority is the value of priority of pod groups created from this template. Various @@ -435,14 +415,10 @@ message PodGroupTemplate { // Priority Admission Controller is enabled, it prevents users from setting this field. // The admission controller populates this field from PriorityClassName. // The higher the value, the higher the priority. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. // - // +featureGate=WorkloadAwarePreemption // +optional - // +k8s:ifDisabled("WorkloadAwarePreemption")=+k8s:forbidden - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:optional - // +k8s:ifEnabled("WorkloadAwarePreemption")=+k8s:maximum=1000000000 # HighestUserDefinablePriority + // +k8s:optional + // +k8s:maximum=1000000000 # HighestUserDefinablePriority optional int32 priority = 7; } diff --git a/staging/src/k8s.io/api/scheduling/v1alpha3/types_swagger_doc_generated.go b/staging/src/k8s.io/api/scheduling/v1alpha3/types_swagger_doc_generated.go index 90b3e1f1259..de5c2623078 100644 --- a/staging/src/k8s.io/api/scheduling/v1alpha3/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/scheduling/v1alpha3/types_swagger_doc_generated.go @@ -129,9 +129,9 @@ var map_PodGroupSpec = map[string]string{ "schedulingPolicy": "SchedulingPolicy defines the scheduling policy for this instance of the PodGroup. Controllers are expected to fill this field by copying it from a PodGroupTemplate. This field is immutable.", "schedulingConstraints": "SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroup. Controllers are expected to fill this field by copying it from a PodGroupTemplate. This field is immutable. This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled.", "resourceClaims": "ResourceClaims defines which ResourceClaims may be shared among Pods in the group. Pods consume the devices allocated to a PodGroup's claim by defining a claim in its own Spec.ResourceClaims that matches the PodGroup's claim exactly. The claim must have the same name and refer to the same ResourceClaim or ResourceClaimTemplate.\n\nThis is an alpha-level field and requires that the DRAWorkloadResourceClaims feature gate is enabled.\n\nThis field is immutable.", - "disruptionMode": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Single, All. Defaults to Single if unset. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", - "priorityClassName": "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", - "priority": "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "disruptionMode": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. Controllers are expected to fill this field by copying it from a PodGroupTemplate. One of Single, All. Defaults to Single if unset. This field is immutable.", + "priorityClassName": "PriorityClassName defines the priority that should be considered when scheduling this pod group. Controllers are expected to fill this field by copying it from a PodGroupTemplate. Otherwise, it is validated and resolved similarly to the PriorityClassName on PodGroupTemplate (i.e. if no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, the pod group's priority will be zero). This field is immutable.", + "priority": "Priority is the value of priority of this pod group. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is immutable.", } func (PodGroupSpec) SwaggerDoc() map[string]string { @@ -154,9 +154,9 @@ var map_PodGroupTemplate = map[string]string{ "schedulingPolicy": "SchedulingPolicy defines the scheduling policy for this PodGroupTemplate.", "schedulingConstraints": "SchedulingConstraints defines optional scheduling constraints (e.g. topology) for this PodGroupTemplate. This field is only available when the TopologyAwareWorkloadScheduling feature gate is enabled.", "resourceClaims": "ResourceClaims defines which ResourceClaims may be shared among Pods in the group. Pods consume the devices allocated to a PodGroup's claim by defining a claim in its own Spec.ResourceClaims that matches the PodGroup's claim exactly. The claim must have the same name and refer to the same ResourceClaim or ResourceClaimTemplate.\n\nThis is an alpha-level field and requires that the DRAWorkloadResourceClaims feature gate is enabled.\n\nThis field is immutable.", - "disruptionMode": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Single, All. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", - "priorityClassName": "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", - "priority": "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. This field is available only when the WorkloadAwarePreemption feature gate is enabled.", + "disruptionMode": "DisruptionMode defines the mode in which a given PodGroup can be disrupted. One of Single, All.", + "priorityClassName": "PriorityClassName indicates the priority that should be considered when scheduling a pod group created from this template. If no priority class is specified, admission control can set this to the global default priority class if it exists. Otherwise, pod groups created from this template will have the priority set to zero.", + "priority": "Priority is the value of priority of pod groups created from this template. Various system components use this field to find the priority of the pod group. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority.", } func (PodGroupTemplate) SwaggerDoc() map[string]string { diff --git a/test/declarative_validation/scheduling/podgroup/zz_generated.validations.v1alpha3_test.go b/test/declarative_validation/scheduling/podgroup/zz_generated.validations.v1alpha3_test.go index dd945c1ad4f..955cb58a0c7 100644 --- a/test/declarative_validation/scheduling/podgroup/zz_generated.validations.v1alpha3_test.go +++ b/test/declarative_validation/scheduling/podgroup/zz_generated.validations.v1alpha3_test.go @@ -31,7 +31,6 @@ func init() { schema.GroupVersionKind{Group: "scheduling.k8s.io", Version: "v1alpha3", Kind: "PodGroup"}, coverage.FieldRules{ "spec.disruptionMode": { - {ErrorType: "FieldValueForbidden"}, {ErrorType: "FieldValueInvalid", Origin: "immutable"}, {ErrorType: "FieldValueInvalid", Origin: "union"}, {ErrorType: "FieldValueRequired"}, @@ -49,12 +48,10 @@ func init() { {ErrorType: "FieldValueRequired"}, }, "spec.priority": { - {ErrorType: "FieldValueForbidden"}, {ErrorType: "FieldValueInvalid", Origin: "immutable"}, {ErrorType: "FieldValueInvalid", Origin: "maximum"}, }, "spec.priorityClassName": { - {ErrorType: "FieldValueForbidden"}, {ErrorType: "FieldValueInvalid", Origin: "format=k8s-long-name"}, {ErrorType: "FieldValueInvalid", Origin: "immutable"}, }, diff --git a/test/declarative_validation/scheduling/workload/zz_generated.validations.v1alpha3_test.go b/test/declarative_validation/scheduling/workload/zz_generated.validations.v1alpha3_test.go index d865f802ef5..54885cdd777 100644 --- a/test/declarative_validation/scheduling/workload/zz_generated.validations.v1alpha3_test.go +++ b/test/declarative_validation/scheduling/workload/zz_generated.validations.v1alpha3_test.go @@ -53,7 +53,6 @@ func init() { {ErrorType: "FieldValueDuplicate"}, }, "spec.podGroupTemplates[*].disruptionMode": { - {ErrorType: "FieldValueForbidden"}, {ErrorType: "FieldValueInvalid", Origin: "union"}, }, "spec.podGroupTemplates[*].name": { @@ -61,11 +60,9 @@ func init() { {ErrorType: "FieldValueRequired"}, }, "spec.podGroupTemplates[*].priority": { - {ErrorType: "FieldValueForbidden"}, {ErrorType: "FieldValueInvalid", Origin: "maximum"}, }, "spec.podGroupTemplates[*].priorityClassName": { - {ErrorType: "FieldValueForbidden"}, {ErrorType: "FieldValueInvalid", Origin: "format=k8s-long-name"}, }, "spec.podGroupTemplates[*].resourceClaims": { From 54ca619d4b3c31665d92868439118a4740c994a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Skocze=C5=84?= Date: Fri, 5 Jun 2026 12:48:52 +0000 Subject: [PATCH 3/3] Merge GangScheduling and WorkloadAwarePreemption feature gates into GenericWorkload --- pkg/features/kube_features.go | 24 --- .../podgroup/storage/storage_test.go | 3 + pkg/registry/scheduling/podgroup/strategy.go | 48 ------ .../scheduling/podgroup/strategy_test.go | 140 ++++------------- pkg/registry/scheduling/workload/strategy.go | 48 ------ .../scheduling/workload/strategy_test.go | 75 ++------- .../apis/config/v1/default_plugins.go | 2 +- .../apis/config/v1/default_plugins_test.go | 4 +- .../backend/queue/scheduling_queue_test.go | 10 -- pkg/scheduler/eventhandlers.go | 2 +- .../defaultpreemption/default_preemption.go | 21 +-- .../default_preemption_test.go | 74 +++------ .../framework/plugins/feature/feature.go | 4 - .../gangscheduling/gangscheduling_test.go | 4 +- .../preemption/podgrouppreemption.go | 2 +- pkg/scheduler/framework/runtime/framework.go | 2 +- .../framework/runtime/framework_test.go | 4 +- pkg/scheduler/schedule_one_podgroup.go | 2 +- pkg/scheduler/schedule_one_podgroup_test.go | 69 ++++----- pkg/scheduler/scheduler.go | 2 - pkg/scheduler/scheduler_test.go | 10 +- pkg/scheduler/util/utils.go | 3 +- plugin/pkg/admission/priority/admission.go | 2 +- .../pkg/admission/priority/admission_test.go | 112 +++++++------- .../scheduling/v1alpha3/podgroupspec.go | 6 - .../scheduling/v1alpha3/podgrouptemplate.go | 6 - .../reference/feature_list.md | 2 - .../reference/versioned_feature_list.yaml | 12 -- .../podgroup/declarative_validation_test.go | 142 +++++------------- .../workload/declarative_validation_test.go | 112 +++----------- test/e2e/scheduling/gang_scheduling.go | 2 +- test/integration/dra/dra.go | 3 +- .../scheduler/podgroup/podgroup_test.go | 95 ++---------- .../podgroup/queueing/queueing_test.go | 2 - .../topology_aware_scheduling/tas_test.go | 16 +- .../preemption/podgrouppreemption_test.go | 4 +- test/integration/scheduler/queueing/queue.go | 13 +- .../gangscheduling/performance-config.yaml | 1 - .../podgroup/tas/performance-config.yaml | 1 - 39 files changed, 250 insertions(+), 834 deletions(-) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 0b451a26dbe..0273e34a0b4 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -368,11 +368,6 @@ const ( // If enabled, it allows passing --service-account-signing-endpoint flag to configure external signer. ExternalServiceAccountTokenSigner featuregate.Feature = "ExternalServiceAccountTokenSigner" - // owner: @erictune @wojtek-t - // - // Enables support for gang scheduling in kube-scheduler. - GangScheduling featuregate.Feature = "GangScheduling" - // owner: @erictune @wojtek-t // // Enables support for generic Workload API. @@ -1163,13 +1158,6 @@ const ( // Enables support for joining Windows containers to a hosts' network namespace. WindowsHostNetwork featuregate.Feature = "WindowsHostNetwork" - // owner: @wojtek-t - // kep: https://kep.k8s.io/5710 - // - // Enables support for workload-aware preemption in pod group scheduling cycle - // and related PodGroup and Workload API fields. - WorkloadAwarePreemption featuregate.Feature = "WorkloadAwarePreemption" - // owner: @helayoty @mm4tt @wojtek-t // kep: https://kep.k8s.io/5547 // @@ -1412,10 +1400,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, }, - GangScheduling: { - {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, - }, - GenericWorkload: { {Version: version.MustParse("1.35"), Default: false, PreRelease: featuregate.Alpha}, }, @@ -2035,10 +2019,6 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Deprecated}, }, - WorkloadAwarePreemption: { - {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, - }, - WorkloadWithJob: { {Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Alpha}, }, @@ -2345,8 +2325,6 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature ExternalServiceAccountTokenSigner: {}, - GangScheduling: {GenericWorkload}, - GenericWorkload: {}, GitRepoVolumeDriver: {}, @@ -2593,8 +2571,6 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature WindowsHostNetwork: {}, - WorkloadAwarePreemption: {GangScheduling}, - WorkloadWithJob: {GenericWorkload}, apiextensionsfeatures.CRDObservedGenerationTracking: {}, diff --git a/pkg/registry/scheduling/podgroup/storage/storage_test.go b/pkg/registry/scheduling/podgroup/storage/storage_test.go index d849df1a1cc..116de3f27c9 100644 --- a/pkg/registry/scheduling/podgroup/storage/storage_test.go +++ b/pkg/registry/scheduling/podgroup/storage/storage_test.go @@ -71,6 +71,9 @@ func validNewPodGroup() *scheduling.PodGroup { MinCount: 5, }, }, + DisruptionMode: &scheduling.DisruptionMode{ + Single: &scheduling.SingleDisruptionMode{}, + }, }, } } diff --git a/pkg/registry/scheduling/podgroup/strategy.go b/pkg/registry/scheduling/podgroup/strategy.go index 21b2ef466ce..94bb10751e8 100644 --- a/pkg/registry/scheduling/podgroup/strategy.go +++ b/pkg/registry/scheduling/podgroup/strategy.go @@ -83,9 +83,6 @@ func (*podGroupStrategy) DeclarativeValidationConfig(ctx context.Context, obj, o if utilfeature.DefaultFeatureGate.Enabled(features.DRAWorkloadResourceClaims) { opts = append(opts, string(features.DRAWorkloadResourceClaims)) } - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) { - opts = append(opts, string(features.WorkloadAwarePreemption)) - } return rest.DeclarativeValidationConfig{Options: opts} } @@ -176,9 +173,6 @@ func dropDisabledPodGroupFields(podGroup, oldPodGroup *scheduling.PodGroup) { func dropDisabledPodGroupSpecFields(podGroupSpec, oldPodGroupSpec *scheduling.PodGroupSpec) { dropDisabledSchedulingConstraintsFields(podGroupSpec, oldPodGroupSpec) dropDisabledDRAWorkloadResourceClaimsFields(podGroupSpec, oldPodGroupSpec) - dropDisabledDisruptionModeField(podGroupSpec, oldPodGroupSpec) - dropDisabledPriorityClassNameField(podGroupSpec, oldPodGroupSpec) - dropDisabledPriorityField(podGroupSpec, oldPodGroupSpec) } func dropDisabledPodGroupStatusFields(newPodGroup, oldPodGroup *scheduling.PodGroup) { @@ -214,36 +208,6 @@ func dropDisabledDRAWorkloadResourceClaimsFields(podGroupSpec, oldPodGroupSpec * podGroupSpec.ResourceClaims = nil } -// dropDisabledDisruptionModeField removes the DisruptionMode field unless it is -// already used in the old PodGroup spec. -func dropDisabledDisruptionModeField(podGroupSpec, oldPodGroupSpec *scheduling.PodGroupSpec) { - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) || disruptionModeInUse(oldPodGroupSpec) { - // No need to drop anything. - return - } - podGroupSpec.DisruptionMode = nil -} - -// dropDisabledPriorityClassNameField removes the PriorityClassName field unless -// it is already used in the old PodGroup spec. -func dropDisabledPriorityClassNameField(podGroupSpec, oldPodGroupSpec *scheduling.PodGroupSpec) { - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) || priorityClassNameInUse(oldPodGroupSpec) { - // No need to drop anything. - return - } - podGroupSpec.PriorityClassName = "" -} - -// dropDisabledPriorityField removes the Priority field unless it is already used -// in the old PodGroup spec. -func dropDisabledPriorityField(podGroupSpec, oldPodGroupSpec *scheduling.PodGroupSpec) { - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) || priorityInUse(oldPodGroupSpec) { - // No need to drop anything. - return - } - podGroupSpec.Priority = nil -} - func schedulingConstraintsInUse(podGroupSpec *scheduling.PodGroupSpec) bool { return podGroupSpec != nil && podGroupSpec.SchedulingConstraints != nil } @@ -251,15 +215,3 @@ func schedulingConstraintsInUse(podGroupSpec *scheduling.PodGroupSpec) bool { func draWorkloadResourceClaimsInUse(podGroupSpec *scheduling.PodGroupSpec) bool { return podGroupSpec != nil && len(podGroupSpec.ResourceClaims) > 0 } - -func disruptionModeInUse(podGroupSpec *scheduling.PodGroupSpec) bool { - return podGroupSpec != nil && podGroupSpec.DisruptionMode != nil -} - -func priorityClassNameInUse(podGroupSpec *scheduling.PodGroupSpec) bool { - return podGroupSpec != nil && podGroupSpec.PriorityClassName != "" -} - -func priorityInUse(podGroupSpec *scheduling.PodGroupSpec) bool { - return podGroupSpec != nil && podGroupSpec.Priority != nil -} diff --git a/pkg/registry/scheduling/podgroup/strategy_test.go b/pkg/registry/scheduling/podgroup/strategy_test.go index 493b4d5d897..d36a52d1048 100644 --- a/pkg/registry/scheduling/podgroup/strategy_test.go +++ b/pkg/registry/scheduling/podgroup/strategy_test.go @@ -52,6 +52,9 @@ var podGroup = &scheduling.PodGroup{ MinCount: 5, }, }, + DisruptionMode: &scheduling.DisruptionMode{ + Single: &scheduling.SingleDisruptionMode{}, + }, }, } @@ -67,14 +70,6 @@ func podGroupWithSchedulingConstraints(keys ...string) *scheduling.PodGroup { return pg } -func podGroupWithDisruptionModeSingle() *scheduling.PodGroup { - pg := podGroup.DeepCopy() - pg.Spec.DisruptionMode = &scheduling.DisruptionMode{ - Single: &scheduling.SingleDisruptionMode{}, - } - return pg -} - func podGroupWithDisruptionModeAll() *scheduling.PodGroup { pg := podGroup.DeepCopy() pg.Spec.DisruptionMode = &scheduling.DisruptionMode{ @@ -129,7 +124,6 @@ func TestStrategyCreate(t *testing.T) { obj *scheduling.PodGroup expectObj *scheduling.PodGroup enableTopologyAwareScheduling bool - enableWorkloadAwarePreemption bool expectValidationError string }{ "simple": { @@ -198,84 +192,53 @@ func TestStrategyCreate(t *testing.T) { obj: podGroupWithSchedulingConstraints("foo-"), expectObj: podGroup, }, - "workload aware preemption disabled - drop disruption mode": { - obj: podGroupWithDisruptionModeSingle(), - expectObj: podGroup, + "disruption mode all": { + obj: podGroupWithDisruptionModeAll(), + expectObj: podGroupWithDisruptionModeAll(), }, - "workload aware preemption enabled - preserve disruption mode (pod)": { - obj: podGroupWithDisruptionModeSingle(), - expectObj: podGroupWithDisruptionModeSingle(), - enableWorkloadAwarePreemption: true, + "both disruption modes set": { + obj: podGroupWithDisruptionModeBoth(), + expectValidationError: "must specify exactly one of", }, - "workload aware preemption enabled - preserve disruption mode (pod group)": { - obj: podGroupWithDisruptionModeAll(), - expectObj: podGroupWithDisruptionModeAll(), - enableWorkloadAwarePreemption: true, - }, - "workload aware preemption enabled - both disruption modes set": { - obj: podGroupWithDisruptionModeBoth(), - enableWorkloadAwarePreemption: true, - expectValidationError: "must specify exactly one of", - }, - "workload aware preemption disabled - drop priorityClassName": { + "invalid priorityClassName": { obj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() - pg.Spec.PriorityClassName = "high-priority" - return pg - }(), - expectObj: podGroup, - }, - "workload aware preemption enabled - invalid priorityClassName": { - obj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() + pg := podGroup.DeepCopy() pg.Spec.PriorityClassName = "invalid/priority/class/name" return pg }(), - enableWorkloadAwarePreemption: true, - expectValidationError: subdomainNameError, + expectValidationError: subdomainNameError, }, - "workload aware preemption enabled - preserve priorityClassName": { + "priorityClassName set": { obj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() + pg := podGroup.DeepCopy() pg.Spec.PriorityClassName = "high-priority" return pg }(), expectObj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() + pg := podGroup.DeepCopy() pg.Spec.PriorityClassName = "high-priority" return pg }(), - enableWorkloadAwarePreemption: true, }, - "workload aware preemption disabled - drop priority": { + "priority set": { obj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() - pg.Spec.Priority = new(int32(1000)) - return pg - }(), - expectObj: podGroup, - }, - "workload aware preemption enabled - preserve priority": { - obj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() + pg := podGroup.DeepCopy() pg.Spec.Priority = new(int32(1000)) return pg }(), expectObj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() + pg := podGroup.DeepCopy() pg.Spec.Priority = new(int32(1000)) return pg }(), - enableWorkloadAwarePreemption: true, }, - "workload aware preemption enabled - too high priority": { + "too high priority": { obj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() + pg := podGroup.DeepCopy() pg.Spec.Priority = new(int32(scheduling.HighestUserDefinablePriority + 1)) return pg }(), - enableWorkloadAwarePreemption: true, - expectValidationError: maximumError, + expectValidationError: maximumError, }, } @@ -284,8 +247,6 @@ func TestStrategyCreate(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, features.TopologyAwareWorkloadScheduling: tc.enableTopologyAwareScheduling, - features.GangScheduling: tc.enableWorkloadAwarePreemption, - features.WorkloadAwarePreemption: tc.enableWorkloadAwarePreemption, }) podGroup := tc.obj.DeepCopy() @@ -327,7 +288,6 @@ func TestStrategyUpdate(t *testing.T) { oldObj *scheduling.PodGroup newObj *scheduling.PodGroup enableTopologyAwareScheduling bool - enableWorkloadAwarePreemption bool expectValidationError string }{ "no changes": { @@ -410,62 +370,28 @@ func TestStrategyUpdate(t *testing.T) { newObj: podGroupWithSchedulingConstraints("foobar"), expectValidationError: forbiddenError, }, - "disruption mode update, workload aware preemption disabled": { - oldObj: podGroupWithDisruptionModeSingle(), + "changing disruption mode not allowed": { + oldObj: podGroup, newObj: podGroupWithDisruptionModeAll(), - expectValidationError: forbiddenError, + expectValidationError: fieldImmutableError, }, - "disruption mode update, workload aware preemption enabled": { - oldObj: podGroupWithDisruptionModeSingle(), - newObj: podGroupWithDisruptionModeAll(), - enableWorkloadAwarePreemption: true, - expectValidationError: fieldImmutableError, - }, - "priority class name update, workload aware preemption disabled": { - oldObj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() - pg.Spec.PriorityClassName = "low-priority" - return pg - }(), + "changing priority class name not allowed": { + oldObj: podGroup, newObj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() + pg := podGroup.DeepCopy() pg.Spec.PriorityClassName = "high-priority" return pg }(), - expectValidationError: forbiddenError, + expectValidationError: fieldImmutableError, }, - "priority class name update, workload aware preemption enabled": { - oldObj: podGroupWithDisruptionModeSingle(), + "changing priority not allowed": { + oldObj: podGroup, newObj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() - pg.Spec.PriorityClassName = "high-priority" - return pg - }(), - enableWorkloadAwarePreemption: true, - expectValidationError: fieldImmutableError, - }, - "priority update, workload aware preemption disabled": { - oldObj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() - pg.Spec.Priority = new(int32(1000)) - return pg - }(), - newObj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() + pg := podGroup.DeepCopy() pg.Spec.Priority = new(int32(2000)) return pg }(), - expectValidationError: forbiddenError, - }, - "priority update, workload aware preemption enabled": { - oldObj: podGroupWithDisruptionModeSingle(), - newObj: func() *scheduling.PodGroup { - pg := podGroupWithDisruptionModeSingle() - pg.Spec.Priority = new(int32(2000)) - return pg - }(), - enableWorkloadAwarePreemption: true, - expectValidationError: fieldImmutableError, + expectValidationError: fieldImmutableError, }, } @@ -474,8 +400,6 @@ func TestStrategyUpdate(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, features.TopologyAwareWorkloadScheduling: tc.enableTopologyAwareScheduling, - features.GangScheduling: tc.enableWorkloadAwarePreemption, - features.WorkloadAwarePreemption: tc.enableWorkloadAwarePreemption, }) podGroup := tc.oldObj.DeepCopy() newPodGroup := tc.newObj.DeepCopy() diff --git a/pkg/registry/scheduling/workload/strategy.go b/pkg/registry/scheduling/workload/strategy.go index 2bcdbd54af6..02b515353a9 100644 --- a/pkg/registry/scheduling/workload/strategy.go +++ b/pkg/registry/scheduling/workload/strategy.go @@ -62,9 +62,6 @@ func (workloadStrategy) DeclarativeValidationConfig(ctx context.Context, obj, ol if utilfeature.DefaultFeatureGate.Enabled(features.DRAWorkloadResourceClaims) { opts = append(opts, string(features.DRAWorkloadResourceClaims)) } - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) { - opts = append(opts, string(features.WorkloadAwarePreemption)) - } return rest.DeclarativeValidationConfig{Options: opts} } @@ -127,9 +124,6 @@ func dropDisabledPodGroupTemplatesFields(templates, oldTemplates []scheduling.Po template := &templates[i] dropDisabledSchedulingConstraintsFields(template, oldTemplate) dropDisabledDRAWorkloadResourceClaimsFields(template, oldTemplate) - dropDisabledDisruptionModeField(template, oldTemplate) - dropDisabledPriorityClassNameField(template, oldTemplate) - dropDisabledPriorityField(template, oldTemplate) } } @@ -151,36 +145,6 @@ func dropDisabledDRAWorkloadResourceClaimsFields(template, oldTemplate *scheduli template.ResourceClaims = nil } -// dropDisabledDisruptionModeField removes the DisruptionMode field from a template -// unless it is already used in the old template. -func dropDisabledDisruptionModeField(template, oldTemplate *scheduling.PodGroupTemplate) { - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) || disruptionModeInUse(oldTemplate) { - // No need to drop anything. - return - } - template.DisruptionMode = nil -} - -// dropDisabledPriorityClassNameField removes the PriorityClassName field from a template -// unless it is already used in the old template. -func dropDisabledPriorityClassNameField(template, oldTemplate *scheduling.PodGroupTemplate) { - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) || priorityClassNameInUse(oldTemplate) { - // No need to drop anything. - return - } - template.PriorityClassName = "" -} - -// dropDisabledPriorityField removes the Priority field from a template unless it is -// already used in the old template. -func dropDisabledPriorityField(template, oldTemplate *scheduling.PodGroupTemplate) { - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) || priorityInUse(oldTemplate) { - // No need to drop anything. - return - } - template.Priority = nil -} - func schedulingConstraintsInUse(pgt *scheduling.PodGroupTemplate) bool { return pgt != nil && pgt.SchedulingConstraints != nil } @@ -188,15 +152,3 @@ func schedulingConstraintsInUse(pgt *scheduling.PodGroupTemplate) bool { func draWorkloadResourceClaimsInUse(pgt *scheduling.PodGroupTemplate) bool { return pgt != nil && len(pgt.ResourceClaims) > 0 } - -func disruptionModeInUse(pgt *scheduling.PodGroupTemplate) bool { - return pgt != nil && pgt.DisruptionMode != nil -} - -func priorityClassNameInUse(pgt *scheduling.PodGroupTemplate) bool { - return pgt != nil && pgt.PriorityClassName != "" -} - -func priorityInUse(pgt *scheduling.PodGroupTemplate) bool { - return pgt != nil && pgt.Priority != nil -} diff --git a/pkg/registry/scheduling/workload/strategy_test.go b/pkg/registry/scheduling/workload/strategy_test.go index 1182aaa01b6..ae8236c0e60 100644 --- a/pkg/registry/scheduling/workload/strategy_test.go +++ b/pkg/registry/scheduling/workload/strategy_test.go @@ -87,7 +87,6 @@ func TestStrategyCreate(t *testing.T) { obj *scheduling.Workload expectObj *scheduling.Workload enableTopologyAwareScheduling bool - enableWorkloadAwarePreemption bool expectValidationError string }{ "simple": { @@ -156,41 +155,31 @@ func TestStrategyCreate(t *testing.T) { enableTopologyAwareScheduling: true, expectValidationError: requiredError, }, - "workload aware preemption disabled - drop disruption mode": { + "disruption mode single": { obj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{Single: &scheduling.SingleDisruptionMode{}} return w }(), - expectObj: workload, - }, - "workload aware preemption enabled - preserve disruption mode (pod)": { - obj: func() *scheduling.Workload { - w := workload.DeepCopy() - w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{Single: &scheduling.SingleDisruptionMode{}} - return w - }(), - enableWorkloadAwarePreemption: true, expectObj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{Single: &scheduling.SingleDisruptionMode{}} return w }(), }, - "workload aware preemption enabled - preserve disruption mode (pod group)": { + "disruption mode all": { obj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{All: &scheduling.AllDisruptionMode{}} return w }(), - enableWorkloadAwarePreemption: true, expectObj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{All: &scheduling.AllDisruptionMode{}} return w }(), }, - "workload aware preemption enabled - both disruption modes set": { + "both disruption modes set": { obj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{ @@ -199,38 +188,27 @@ func TestStrategyCreate(t *testing.T) { } return w }(), - enableWorkloadAwarePreemption: true, - expectValidationError: "must specify exactly one of", + expectValidationError: "must specify exactly one of", }, - "workload aware preemption enabled - preserve priorityClassName": { + "priorityClassName set": { obj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].PriorityClassName = "high-priority" return w }(), - enableWorkloadAwarePreemption: true, expectObj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].PriorityClassName = "high-priority" return w }(), }, - "workload aware preemption disabled - drop priorityClassName": { - obj: func() *scheduling.Workload { - w := workload.DeepCopy() - w.Spec.PodGroupTemplates[0].PriorityClassName = "high-priority" - return w - }(), - expectObj: workload, - }, - "workload aware preemption enabled - invalid priorityClassName": { + "invalid priorityClassName": { obj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].PriorityClassName = "invalid/priority/class/name" return w }(), - enableWorkloadAwarePreemption: true, - expectValidationError: subdomainNameError, + expectValidationError: subdomainNameError, }, } @@ -241,8 +219,6 @@ func TestStrategyCreate(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, features.TopologyAwareWorkloadScheduling: tc.enableTopologyAwareScheduling, - features.GangScheduling: tc.enableWorkloadAwarePreemption, - features.WorkloadAwarePreemption: tc.enableWorkloadAwarePreemption, }) Strategy.PrepareForCreate(ctx, workload) @@ -275,7 +251,6 @@ func TestStrategyUpdate(t *testing.T) { oldObj *scheduling.Workload newObj *scheduling.Workload enableTopologyAwareScheduling bool - enableWorkloadAwarePreemption bool expectValidationError string expectWorkload *scheduling.Workload }{ @@ -479,30 +454,16 @@ func TestStrategyUpdate(t *testing.T) { enableTopologyAwareScheduling: true, expectValidationError: fieldImmutableError, }, - "disruption mode update, workload aware preemption disabled": { - oldObj: func() *scheduling.Workload { - w := workload.DeepCopy() - w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{All: &scheduling.AllDisruptionMode{}} - return w - }(), - newObj: func() *scheduling.Workload { - w := workload.DeepCopy() - w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{Single: &scheduling.SingleDisruptionMode{}} - return w - }(), - expectValidationError: fieldImmutableError, - }, - "disruption mode update, workload aware preemption enabled": { + "changing disruption mode": { oldObj: workload, newObj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].DisruptionMode = &scheduling.DisruptionMode{Single: &scheduling.SingleDisruptionMode{}} return w }(), - enableWorkloadAwarePreemption: true, - expectValidationError: fieldImmutableError, + expectValidationError: fieldImmutableError, }, - "priorityClassName update, workload aware preemption disabled": { + "changing priorityClassName": { oldObj: func() *scheduling.Workload { w := workload.DeepCopy() w.Spec.PodGroupTemplates[0].PriorityClassName = "high-priority" @@ -515,20 +476,6 @@ func TestStrategyUpdate(t *testing.T) { }(), expectValidationError: fieldImmutableError, }, - "priorityClassName update, workload aware preemption enabled": { - oldObj: func() *scheduling.Workload { - w := workload.DeepCopy() - w.Spec.PodGroupTemplates[0].PriorityClassName = "high-priority" - return w - }(), - newObj: func() *scheduling.Workload { - w := workload.DeepCopy() - w.Spec.PodGroupTemplates[0].PriorityClassName = "low-priority" - return w - }(), - enableWorkloadAwarePreemption: true, - expectValidationError: fieldImmutableError, - }, } for name, tc := range testCases { @@ -536,8 +483,6 @@ func TestStrategyUpdate(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, features.TopologyAwareWorkloadScheduling: tc.enableTopologyAwareScheduling, - features.GangScheduling: tc.enableWorkloadAwarePreemption, - features.WorkloadAwarePreemption: tc.enableWorkloadAwarePreemption, }) oldWorkload := tc.oldObj.DeepCopy() newWorkload := tc.newObj.DeepCopy() diff --git a/pkg/scheduler/apis/config/v1/default_plugins.go b/pkg/scheduler/apis/config/v1/default_plugins.go index 9475cdfd7b6..373001316c6 100644 --- a/pkg/scheduler/apis/config/v1/default_plugins.go +++ b/pkg/scheduler/apis/config/v1/default_plugins.go @@ -64,7 +64,7 @@ func applyFeatureGates(config *v1.Plugins) { if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { applyDynamicResources(config) } - if utilfeature.DefaultFeatureGate.Enabled(features.GangScheduling) { + if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) { applyGangScheduling(config) } if utilfeature.DefaultFeatureGate.Enabled(features.TopologyAwareWorkloadScheduling) { diff --git a/pkg/scheduler/apis/config/v1/default_plugins_test.go b/pkg/scheduler/apis/config/v1/default_plugins_test.go index 35b668fdfba..17c032606eb 100644 --- a/pkg/scheduler/apis/config/v1/default_plugins_test.go +++ b/pkg/scheduler/apis/config/v1/default_plugins_test.go @@ -164,9 +164,8 @@ func TestApplyFeatureGates(t *testing.T) { }, }, { - name: "Feature gate GangScheduling enabled", + name: "Feature gate GenericWorkload enabled", features: map[featuregate.Feature]bool{ - features.GangScheduling: true, features.GenericWorkload: true, }, wantConfig: &v1.Plugins{ @@ -226,6 +225,7 @@ func TestApplyFeatureGates(t *testing.T) { {Name: names.ImageLocality, Weight: ptr.To[int32](1)}, {Name: names.DefaultBinder}, {Name: names.NodeDeclaredFeatures}, + {Name: names.GangScheduling}, {Name: names.TopologyPlacementGenerator}, {Name: names.PodGroupPodsCount, Weight: ptr.To[int32](1)}, }, diff --git a/pkg/scheduler/backend/queue/scheduling_queue_test.go b/pkg/scheduler/backend/queue/scheduling_queue_test.go index 10188414689..b1871e7512e 100644 --- a/pkg/scheduler/backend/queue/scheduling_queue_test.go +++ b/pkg/scheduler/backend/queue/scheduling_queue_test.go @@ -1021,7 +1021,6 @@ func Test_InFlightPods(t *testing.T) { t.Run(fmt.Sprintf("%s (genericWorkloadEnabled: %v)", test.name, genericWorkloadEnabled), func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: genericWorkloadEnabled, - features.GangScheduling: true, }) logger, ctx := ktesting.NewTestContext(t) ctx, cancel := context.WithCancel(ctx) @@ -1392,7 +1391,6 @@ func TestPriorityQueue_Pop(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: tt.genericWorkloadEnabled, - features.GangScheduling: tt.genericWorkloadEnabled, features.SchedulerPopFromBackoffQ: tt.popFromBackoffQEnabled, }) @@ -6132,7 +6130,6 @@ func TestAddPodGroupMember(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) _, ctx := ktesting.NewTestContext(t) @@ -6333,7 +6330,6 @@ func TestDeletePodGroupMember(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) logger, ctx := ktesting.NewTestContext(t) @@ -6517,7 +6513,6 @@ func TestUpdatePodGroupMember(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) _, ctx := ktesting.NewTestContext(t) @@ -6682,7 +6677,6 @@ func TestActivatePodGroupMember(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) logger, ctx := ktesting.NewTestContext(t) @@ -6845,7 +6839,6 @@ func TestMoveAllToActiveOrBackoffQueuePodGroupMember(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) logger, ctx := ktesting.NewTestContext(t) @@ -6989,7 +6982,6 @@ func TestFlushBackoffQCompletedPodGroupMember(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) logger, ctx := ktesting.NewTestContext(t) @@ -7092,7 +7084,6 @@ func TestFlushUnschedulableEntitiesLeftoverPodGroupMember(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) logger, ctx := ktesting.NewTestContext(t) @@ -7266,7 +7257,6 @@ func TestAddUnschedulablePodIfNotPresentPodGroupMember(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) logger, ctx := ktesting.NewTestContext(t) diff --git a/pkg/scheduler/eventhandlers.go b/pkg/scheduler/eventhandlers.go index e1c45346a25..304f4d3406f 100644 --- a/pkg/scheduler/eventhandlers.go +++ b/pkg/scheduler/eventhandlers.go @@ -212,7 +212,7 @@ func (sched *Scheduler) addPodToSchedulingQueue(pod *v1.Pod) { logger.V(3).Info("Add event for unscheduled pod", "pod", klog.KObj(pod)) sched.Cache.AddPodGroupMember(pod) sched.SchedulingQueue.Add(klog.NewContext(context.Background(), logger), pod) - if utilfeature.DefaultFeatureGate.Enabled(features.GangScheduling) { + if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) { sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventUnscheduledPodAdd, nil, pod, nil) } } diff --git a/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go b/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go index 97dadb9652f..55ed16e3071 100644 --- a/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go +++ b/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go @@ -113,10 +113,8 @@ func New(_ context.Context, dpArgs runtime.Object, fh fwk.Handle, fts feature.Fe pl.Executor = preemption.NewExecutor(fh, fts) pl.Evaluator = preemption.NewEvaluator(Name, fh, &pl, pl.Executor) - if pl.fts.EnableWorkloadAwarePreemption || pl.fts.EnableTopologyAwareWorkloadScheduling { + if pl.fts.EnableGenericWorkload { pl.pgLister = fh.SharedInformerFactory().Scheduling().V1alpha3().PodGroups().Lister() - } - if pl.fts.EnableWorkloadAwarePreemption { pl.podGroupEvaluator = preemption.NewPodGroupEvaluator(fh, pl.Executor) } @@ -138,19 +136,8 @@ func (pl *DefaultPreemption) PostFilter(ctx context.Context, state fwk.CycleStat metrics.PreemptionAttempts.Inc() }() - if pod.Spec.SchedulingGroup != nil && pl.fts.EnableTopologyAwareWorkloadScheduling { - pg, err := pl.pgLister.PodGroups(pod.Namespace).Get(*pod.Spec.SchedulingGroup.PodGroupName) - if err != nil { - return nil, fwk.NewStatus(fwk.Unschedulable, "preemption: pod group for pod not found") - } - if pg.Spec.SchedulingConstraints != nil { - // When TAS is enabled, the default preemption logic needs to be disabled to avoid performing preemption multiple times for each topology option. - // The TAS-compatible preemption logic will be implemented in Delayed Preemption KEP 4671 or Workload-aware preemption KEP 5710 features. - return nil, fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to placement-based pod group scheduling limitation") - } - } - if pod.Spec.SchedulingGroup != nil && pl.fts.EnableWorkloadAwarePreemption { - // When WAP is enabled, the default preemption logic needs to be disabled for pod group scheduling to avoid performing preemption in pod by pod cycle + if pod.Spec.SchedulingGroup != nil && pl.fts.EnableGenericWorkload { + // When GenericWorkload is enabled, the default preemption logic needs to be disabled for pod group scheduling to avoid performing preemption in pod by pod cycle // of pod group scheduling. Instead the WAP will be called to perform preemption for the entire pod group. return nil, fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to workload aware preemption enabled") } @@ -167,7 +154,7 @@ func (pl *DefaultPreemption) PreEnqueue(ctx context.Context, p *v1.Pod) *fwk.Sta if !pl.fts.EnableAsyncPreemption { return nil } - if p.Spec.SchedulingGroup != nil && pl.fts.EnableWorkloadAwarePreemption { + if p.Spec.SchedulingGroup != nil && pl.fts.EnableGenericWorkload { pg, err := pl.pgLister.PodGroups(p.Namespace).Get(*p.Spec.SchedulingGroup.PodGroupName) // If the pg is not found do not block the pod. It's not a default preemption responsibility // to block pods from pod group without pg from entering the queue. diff --git a/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption_test.go b/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption_test.go index 58a028c88b2..f6d1df61913 100644 --- a/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption_test.go +++ b/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption_test.go @@ -409,31 +409,12 @@ func TestPostFilter(t *testing.T) { filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{ "node1": fwk.NewStatus(fwk.Unschedulable), }, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)), - features: feature.Features{EnableTopologyAwareWorkloadScheduling: true}, + features: feature.Features{EnableGenericWorkload: true, EnableTopologyAwareWorkloadScheduling: true}, wantResult: nil, - wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to placement-based pod group scheduling limitation"), + wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to workload aware preemption enabled"), }, { - name: "pod with SchedulingGroup with TAS with scheduling constraint enabled should not preempt even when WAP is enabled", - pod: st.MakePod().Name("p-with-podgroup").Namespace(v1.NamespaceDefault).PodGroupName("foo").Priority(highPriority).Obj(), - pods: []*v1.Pod{ - st.MakePod().Name("p1").UID("p1").Namespace(v1.NamespaceDefault).Node("node1").Obj(), - }, - nodes: []*v1.Node{ - st.MakeNode().Name("node1").Capacity(onePodRes).Obj(), - }, - podGroups: []*v1alpha3.PodGroup{ - st.MakePodGroup().Name("foo").Namespace(v1.NamespaceDefault).TopologyKey("rack").Obj(), - }, - filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{ - "node1": fwk.NewStatus(fwk.Unschedulable), - }, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)), - features: feature.Features{EnableTopologyAwareWorkloadScheduling: true, EnableWorkloadAwarePreemption: true}, - wantResult: nil, - wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to placement-based pod group scheduling limitation"), - }, - { - name: "pod with SchedulingGroup with TAS without scheduling constraint enabled should preempt", + name: "pod with SchedulingGroup with TAS without scheduling constraint enabled should not preempt", pod: st.MakePod().Name("p-with-podgroup").Namespace(v1.NamespaceDefault).PodGroupName("foo").Priority(highPriority).Obj(), pods: []*v1.Pod{ st.MakePod().Name("p1").UID("p1").Namespace(v1.NamespaceDefault).Node("node1").Obj(), @@ -447,31 +428,12 @@ func TestPostFilter(t *testing.T) { filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{ "node1": fwk.NewStatus(fwk.Unschedulable), }, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)), - features: feature.Features{EnableTopologyAwareWorkloadScheduling: true}, - wantResult: framework.NewPostFilterResultWithNominatedNode("node1"), - wantStatus: fwk.NewStatus(fwk.Success), - }, - { - name: "pod with SchedulingGroup with TAS with WAP enabled should not preempt", - pod: st.MakePod().Name("p-with-podgroup").Namespace(v1.NamespaceDefault).PodGroupName("foo").Priority(highPriority).Obj(), - pods: []*v1.Pod{ - st.MakePod().Name("p1").UID("p1").Namespace(v1.NamespaceDefault).Node("node1").Obj(), - }, - nodes: []*v1.Node{ - st.MakeNode().Name("node1").Capacity(onePodRes).Obj(), - }, - podGroups: []*v1alpha3.PodGroup{ - st.MakePodGroup().Name("foo").Namespace(v1.NamespaceDefault).Obj(), - }, - filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{ - "node1": fwk.NewStatus(fwk.Unschedulable), - }, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)), - features: feature.Features{EnableTopologyAwareWorkloadScheduling: true, EnableWorkloadAwarePreemption: true}, + features: feature.Features{EnableGenericWorkload: true, EnableTopologyAwareWorkloadScheduling: true}, wantResult: nil, wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to workload aware preemption enabled"), }, { - name: "pod with SchedulingGroup with WAP enabled should not preempt", + name: "pod with SchedulingGroup should not preempt", pod: st.MakePod().Name("p-with-podgroup").PodGroupName("foo").Priority(highPriority).Obj(), pods: []*v1.Pod{ st.MakePod().Name("p1").UID("p1").Namespace(v1.NamespaceDefault).Node("node1").Obj(), @@ -482,12 +444,12 @@ func TestPostFilter(t *testing.T) { filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{ "node1": fwk.NewStatus(fwk.Unschedulable), }, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)), - features: feature.Features{EnableWorkloadAwarePreemption: true}, + features: feature.Features{EnableGenericWorkload: true}, wantResult: nil, wantStatus: fwk.NewStatus(fwk.Unschedulable, "preemption: not eligible due to workload aware preemption enabled"), }, { - name: "pod with SchedulingGroup with TAS and WAP disabled should preempt", + name: "pod with SchedulingGroup with GenericWorkload and TAS disabled should preempt", pod: st.MakePod().Name("p-with-podgroup").PodGroupName("foo").Priority(highPriority).Obj(), pods: []*v1.Pod{ st.MakePod().Name("p1").UID("p1").Namespace(v1.NamespaceDefault).Node("node1").Obj(), @@ -498,7 +460,7 @@ func TestPostFilter(t *testing.T) { filteredNodesStatuses: framework.NewNodeToStatus(map[string]*fwk.Status{ "node1": fwk.NewStatus(fwk.Unschedulable), }, fwk.NewStatus(fwk.UnschedulableAndUnresolvable)), - features: feature.Features{EnableTopologyAwareWorkloadScheduling: false, EnableWorkloadAwarePreemption: false}, + features: feature.Features{EnableGenericWorkload: false, EnableTopologyAwareWorkloadScheduling: false}, wantResult: framework.NewPostFilterResultWithNominatedNode("node1"), wantStatus: fwk.NewStatus(fwk.Success), }, @@ -2508,47 +2470,47 @@ func TestPreEnqueue(t *testing.T) { wantStatus: nil, }, { - name: "WAP enabled, pod in same PodGroup, returns UnschedulableAndUnresolvable", + name: "GenericWorkload enabled, pod in same PodGroup, returns UnschedulableAndUnresolvable", podToTriggerPreemption: st.MakePod().Name("p").UID("p").Namespace(v1.NamespaceDefault).PodGroupName("pg1").Priority(highPriority).Obj(), podToCheck: st.MakePod().Name("p_other").UID("p_other").Namespace(v1.NamespaceDefault).PodGroupName("pg1").Priority(highPriority).Obj(), pgs: []*v1alpha3.PodGroup{ st.MakePodGroup().Name("pg1").UID("pg1").Namespace(v1.NamespaceDefault).Priority(highPriority).Obj(), }, - features: feature.Features{EnableAsyncPreemption: true, EnableWorkloadAwarePreemption: true}, + features: feature.Features{EnableAsyncPreemption: true, EnableGenericWorkload: true}, expectPreemption: true, wantStatus: fwk.NewStatus(fwk.UnschedulableAndUnresolvable, "waiting for the preemption for this pod group to be finished"), }, { - name: "WAP disabled, pod in same PodGroup, returns nil", + name: "GenericWorkload disabled, pod in same PodGroup, returns nil", podToTriggerPreemption: st.MakePod().Name("p").UID("p").Namespace(v1.NamespaceDefault).PodGroupName("pg1").Priority(highPriority).Obj(), podToCheck: st.MakePod().Name("p_other").UID("p_other").Namespace(v1.NamespaceDefault).PodGroupName("pg1").Priority(highPriority).Obj(), pgs: []*v1alpha3.PodGroup{ st.MakePodGroup().Name("pg1").UID("pg1").Namespace(v1.NamespaceDefault).Obj(), }, - features: feature.Features{EnableAsyncPreemption: true, EnableWorkloadAwarePreemption: false}, + features: feature.Features{EnableAsyncPreemption: true, EnableGenericWorkload: false}, expectPreemption: true, wantStatus: nil, }, { - name: "WAP enabled, pod in different PodGroup, returns nil", + name: "GenericWorkload enabled, pod in different PodGroup, returns nil", podToTriggerPreemption: st.MakePod().Name("p").UID("p").Namespace(v1.NamespaceDefault).PodGroupName("pg1").Priority(highPriority).Obj(), podToCheck: st.MakePod().Name("p_other").UID("p_other").Namespace(v1.NamespaceDefault).PodGroupName("pg2").Priority(highPriority).Obj(), pgs: []*v1alpha3.PodGroup{ st.MakePodGroup().Name("pg1").UID("pg1").Namespace(v1.NamespaceDefault).Priority(highPriority).Obj(), st.MakePodGroup().Name("pg2").UID("pg2").Namespace(v1.NamespaceDefault).Priority(highPriority).Obj(), }, - features: feature.Features{EnableAsyncPreemption: true, EnableWorkloadAwarePreemption: true}, + features: feature.Features{EnableAsyncPreemption: true, EnableGenericWorkload: true}, expectPreemption: true, wantStatus: nil, }, { - name: "WAP enabled, pod group not found, returns nil", + name: "GenericWorkload enabled, pod group not found, returns nil", podToTriggerPreemption: st.MakePod().Name("p").UID("p").Namespace(v1.NamespaceDefault).PodGroupName("pg1").Priority(highPriority).Obj(), podToCheck: st.MakePod().Name("p_other").UID("p_other").Namespace(v1.NamespaceDefault).PodGroupName("pg_missing").Priority(highPriority).Obj(), pgs: []*v1alpha3.PodGroup{ st.MakePodGroup().Name("pg1").UID("pg1").Namespace(v1.NamespaceDefault).Priority(highPriority).Obj(), }, - features: feature.Features{EnableAsyncPreemption: true, EnableWorkloadAwarePreemption: true}, + features: feature.Features{EnableAsyncPreemption: true, EnableGenericWorkload: true}, expectPreemption: false, wantStatus: nil, }, @@ -2631,7 +2593,7 @@ func TestPreEnqueue(t *testing.T) { // Trigger preemption. Given custom PreemptPod implementation, the async preemption will not finish until // finishPreemption is closed. - if tt.features.EnableWorkloadAwarePreemption && tt.podToTriggerPreemption.Spec.SchedulingGroup != nil { + if tt.features.EnableGenericWorkload && tt.podToTriggerPreemption.Spec.SchedulingGroup != nil { pg, err := informerFactory.Scheduling().V1alpha3().PodGroups().Lister().PodGroups(tt.podToTriggerPreemption.Namespace).Get(*tt.podToTriggerPreemption.Spec.SchedulingGroup.PodGroupName) if err != nil { t.Fatalf("could not find pg: %v", err) @@ -2699,7 +2661,7 @@ func TestDefaultPreemption_PodGroupPostFilter_ErrorWrapping(t *testing.T) { } features := feature.Features{ - EnableWorkloadAwarePreemption: true, + EnableGenericWorkload: true, } pl, err := New(ctx, getDefaultDefaultPreemptionArgs(), f, features) if err != nil { diff --git a/pkg/scheduler/framework/plugins/feature/feature.go b/pkg/scheduler/framework/plugins/feature/feature.go index fd9f152630e..31828b18206 100644 --- a/pkg/scheduler/framework/plugins/feature/feature.go +++ b/pkg/scheduler/framework/plugins/feature/feature.go @@ -47,12 +47,10 @@ type Features struct { EnablePodLevelResources bool EnableStorageCapacityScoring bool EnableNodeDeclaredFeatures bool - EnableGangScheduling bool EnableGenericWorkload bool EnableTaintTolerationComparisonOperators bool EnableInPlacePodLevelResourcesVerticalScaling bool EnableTopologyAwareWorkloadScheduling bool - EnableWorkloadAwarePreemption bool } // NewSchedulerFeaturesFromGates copies the current state of the feature gates into the struct. @@ -79,12 +77,10 @@ func NewSchedulerFeaturesFromGates(featureGate featuregate.FeatureGate) Features EnableDRAPartitionableDevices: featureGate.Enabled(features.DRAPartitionableDevices), EnableStorageCapacityScoring: featureGate.Enabled(features.StorageCapacityScoring), EnableNodeDeclaredFeatures: featureGate.Enabled(features.NodeDeclaredFeatures), - EnableGangScheduling: featureGate.Enabled(features.GangScheduling), EnableGenericWorkload: featureGate.Enabled(features.GenericWorkload), EnableTaintTolerationComparisonOperators: featureGate.Enabled(features.TaintTolerationComparisonOperators), EnableInPlacePodLevelResourcesVerticalScaling: featureGate.Enabled(features.InPlacePodLevelResourcesVerticalScaling), EnableTopologyAwareWorkloadScheduling: featureGate.Enabled(features.TopologyAwareWorkloadScheduling), EnableDRANodeAllocatableResources: featureGate.Enabled(features.DRANodeAllocatableResources), - EnableWorkloadAwarePreemption: featureGate.Enabled(features.WorkloadAwarePreemption), } } diff --git a/pkg/scheduler/framework/plugins/gangscheduling/gangscheduling_test.go b/pkg/scheduler/framework/plugins/gangscheduling/gangscheduling_test.go index 1adcda36808..6fabafb5644 100644 --- a/pkg/scheduler/framework/plugins/gangscheduling/gangscheduling_test.go +++ b/pkg/scheduler/framework/plugins/gangscheduling/gangscheduling_test.go @@ -305,7 +305,7 @@ func TestGangSchedulingFlow(t *testing.T) { } cache.AddPodGroupMember(tt.pod) - p, err := New(ctx, nil, fh, feature.Features{EnableGangScheduling: true}) + p, err := New(ctx, nil, fh, feature.Features{EnableGenericWorkload: true}) if err != nil { t.Fatalf("Failed to create plugin: %v", err) } @@ -612,7 +612,7 @@ func TestPlacementFeasible(t *testing.T) { t.Fatalf("Failed to create framework: %v", err) } - p, err := New(ctx, nil, fh, feature.Features{EnableGangScheduling: true}) + p, err := New(ctx, nil, fh, feature.Features{EnableGenericWorkload: true}) if err != nil { t.Fatalf("Failed to create plugin: %v", err) } diff --git a/pkg/scheduler/framework/preemption/podgrouppreemption.go b/pkg/scheduler/framework/preemption/podgrouppreemption.go index f252359360a..72c5256ae07 100644 --- a/pkg/scheduler/framework/preemption/podgrouppreemption.go +++ b/pkg/scheduler/framework/preemption/podgrouppreemption.go @@ -320,7 +320,7 @@ func (ev *PodGroupEvaluator) getPodPriority(p *v1.Pod) int32 { // // 1. Priority: Higher priority units are always more important. // -// 2. Workload Type (if WorkloadAwarePreemption is enabled): +// 2. Workload Type: // Atomic workloads (PodGroups) are considered more important than individual Pods // of the same priority. // diff --git a/pkg/scheduler/framework/runtime/framework.go b/pkg/scheduler/framework/runtime/framework.go index 0b09a502f62..5f68362ca69 100644 --- a/pkg/scheduler/framework/runtime/framework.go +++ b/pkg/scheduler/framework/runtime/framework.go @@ -476,7 +476,7 @@ func NewFramework(ctx context.Context, r Registry, profile *config.KubeScheduler } // Put default preemption as the only PodGroupPostFilterPlugin - if utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) { + if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) { if dp, ok := f.pluginsMap[names.DefaultPreemption]; ok { if _, ok := dp.(framework.PodGroupPostFilterPlugin); ok { f.podGroupPostFilterPlugins = append(f.podGroupPostFilterPlugins, dp.(framework.PodGroupPostFilterPlugin)) diff --git a/pkg/scheduler/framework/runtime/framework_test.go b/pkg/scheduler/framework/runtime/framework_test.go index f4decf70d29..027f0b458db 100644 --- a/pkg/scheduler/framework/runtime/framework_test.go +++ b/pkg/scheduler/framework/runtime/framework_test.go @@ -865,9 +865,7 @@ func TestPodGroupPostFilterPlugins(t *testing.T) { t.Run(tc.name, func(t *testing.T) { if tc.featureGate { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ - features.GenericWorkload: true, - features.GangScheduling: true, - features.WorkloadAwarePreemption: true, + features.GenericWorkload: true, }) } diff --git a/pkg/scheduler/schedule_one_podgroup.go b/pkg/scheduler/schedule_one_podgroup.go index 6974b5fb713..9292ab3ad61 100644 --- a/pkg/scheduler/schedule_one_podgroup.go +++ b/pkg/scheduler/schedule_one_podgroup.go @@ -193,7 +193,7 @@ func (sched *Scheduler) podGroupCycle(ctx context.Context, schedFwk framework.Fr // Run workload aware preemption if required. If the preemption is successful, // we need to put the pods from pod group back into the scheduling queue. - if sched.workloadAwarePreemptionEnabled && result.status.Code() == fwk.Unschedulable { + if result.status.Code() == fwk.Unschedulable { pgPostFilterResult, status := sched.runWorkloadAwarePreemption(ctx, schedFwk, podGroupCycleState, podGroupInfo) if status.IsSuccess() { result.waitingOnPreemption = true diff --git a/pkg/scheduler/schedule_one_podgroup_test.go b/pkg/scheduler/schedule_one_podgroup_test.go index 60843048be3..d263f7a2e6f 100644 --- a/pkg/scheduler/schedule_one_podgroup_test.go +++ b/pkg/scheduler/schedule_one_podgroup_test.go @@ -466,13 +466,12 @@ func TestPodGroupCycle_FillsPodResultsOnFewerResults(t *testing.T) { var lock sync.Mutex sched := &Scheduler{ - Profiles: profile.Map{"test-scheduler": schedFwk}, - SchedulingQueue: internalqueue.NewTestQueue(ctx, nil), - Cache: cache, - client: client, - podGroupLister: podGroupLister, - nodeInfoSnapshot: internalcache.NewEmptySnapshot(), - workloadAwarePreemptionEnabled: false, + Profiles: profile.Map{"test-scheduler": schedFwk}, + SchedulingQueue: internalqueue.NewTestQueue(ctx, nil), + Cache: cache, + client: client, + podGroupLister: podGroupLister, + nodeInfoSnapshot: internalcache.NewEmptySnapshot(), FailureHandler: func(ctx context.Context, fwk framework.Framework, p *framework.QueuedPodInfo, status *fwk.Status, ni *fwk.NominatingInfo, start time.Time) { lock.Lock() defer lock.Unlock() @@ -525,25 +524,25 @@ func TestPodGroupCycle_FillsPodResultsOnFewerResults(t *testing.T) { func TestPodGroupCycle_PodGroupPostFilter(t *testing.T) { tests := []struct { name string - wapFeatureGateEnabled bool + genericWorkloadEnabled bool postFilterPlugin string expectedPodGroupPostFilterCalled bool }{ { - name: "runs pod group post filter when WAP is enabled and DefaultPreemption is registered", - wapFeatureGateEnabled: true, + name: "runs pod group post filter when GenericWorkload is enabled and DefaultPreemption is registered", + genericWorkloadEnabled: true, postFilterPlugin: "DefaultPreemption", expectedPodGroupPostFilterCalled: true, }, { - name: "disables pod group post filter when WAP feature gate is disabled", - wapFeatureGateEnabled: false, + name: "disables pod group post filter when GenericWorkload feature gate is disabled", + genericWorkloadEnabled: false, postFilterPlugin: "DefaultPreemption", expectedPodGroupPostFilterCalled: false, }, { name: "disables pod group post filter when DefaultPreemption is not registered", - wapFeatureGateEnabled: true, + genericWorkloadEnabled: true, postFilterPlugin: "FakePodGroupPlugin", expectedPodGroupPostFilterCalled: false, }, @@ -551,11 +550,8 @@ func TestPodGroupCycle_PodGroupPostFilter(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Enable feature gates featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ - features.GenericWorkload: true, - features.WorkloadAwarePreemption: tt.wapFeatureGateEnabled, - features.GangScheduling: true, + features.GenericWorkload: tt.genericWorkloadEnabled, }) testPodGroup := st.MakePodGroup().Name("pg").Namespace("default").Obj() @@ -645,13 +641,13 @@ func TestPodGroupCycle_PodGroupPostFilter(t *testing.T) { cache.AddNode(logger, testNode) sched := &Scheduler{ - Profiles: profile.Map{"test-scheduler": schedFwk}, - SchedulingQueue: internalqueue.NewTestQueue(ctx, nil), - Cache: cache, - client: client, - podGroupLister: podGroupLister, - nodeInfoSnapshot: internalcache.NewEmptySnapshot(), - workloadAwarePreemptionEnabled: tt.wapFeatureGateEnabled, + Profiles: profile.Map{"test-scheduler": schedFwk}, + SchedulingQueue: internalqueue.NewTestQueue(ctx, nil), + Cache: cache, + client: client, + podGroupLister: podGroupLister, + nodeInfoSnapshot: internalcache.NewEmptySnapshot(), + genericWorkloadEnabled: tt.genericWorkloadEnabled, FailureHandler: func(ctx context.Context, fwk framework.Framework, p *framework.QueuedPodInfo, status *fwk.Status, ni *fwk.NominatingInfo, start time.Time) { }, } @@ -2674,7 +2670,6 @@ func TestPlacementCycleStateLifecycle(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.TopologyAwareWorkloadScheduling: true, features.GenericWorkload: true, - features.GangScheduling: true, }) // A single scenario exercises both isolation and continuity: @@ -2884,11 +2879,8 @@ func TestRunWorkloadAwarePreemption(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Enable feature gate before framework initialization featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ - features.GenericWorkload: true, - features.WorkloadAwarePreemption: tt.pluginsRegistered, - features.GangScheduling: true, + features.GenericWorkload: true, }) logger, ctx := ktesting.NewTestContext(t) @@ -2980,11 +2972,7 @@ func TestRunWorkloadAwarePreemption(t *testing.T) { } func TestPodGroupCycle_NominatedNodes(t *testing.T) { - featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ - features.GenericWorkload: true, - features.WorkloadAwarePreemption: true, - features.GangScheduling: true, - }) + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.GenericWorkload, true) testPodGroup := st.MakePodGroup().Name("pg").Namespace("default").Obj() p1 := st.MakePod().Name("p1").UID("p1").PodGroupName("pg").SchedulerName("test-scheduler").Obj() @@ -3056,13 +3044,12 @@ func TestPodGroupCycle_NominatedNodes(t *testing.T) { cache := internalcache.New(ctx, nil, true) sched := &Scheduler{ - Profiles: profile.Map{"test-scheduler": schedFwk}, - Cache: cache, - nodeInfoSnapshot: internalcache.NewEmptySnapshot(), - podGroupLister: podGroupLister, - workloadAwarePreemptionEnabled: true, - client: client, - SchedulingQueue: internalqueue.NewTestQueue(ctx, nil), + Profiles: profile.Map{"test-scheduler": schedFwk}, + Cache: cache, + nodeInfoSnapshot: internalcache.NewEmptySnapshot(), + podGroupLister: podGroupLister, + client: client, + SchedulingQueue: internalqueue.NewTestQueue(ctx, nil), } // Mock SchedulePod to return Unschedulable initially, and success on subsequent calls diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go index 06de7f02cef..a802365abb6 100644 --- a/pkg/scheduler/scheduler.go +++ b/pkg/scheduler/scheduler.go @@ -121,7 +121,6 @@ type Scheduler struct { nominatedNodeNameForExpectationEnabled bool genericWorkloadEnabled bool - workloadAwarePreemptionEnabled bool } func (sched *Scheduler) applyDefaultHandlers() { @@ -455,7 +454,6 @@ func New(ctx context.Context, nominatedNodeNameForExpectationEnabled: feature.DefaultFeatureGate.Enabled(features.NominatedNodeNameForExpectation), podGroupLister: podGroupLister, genericWorkloadEnabled: feature.DefaultFeatureGate.Enabled(features.GenericWorkload), - workloadAwarePreemptionEnabled: feature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption), } sched.NextEntity = podQueue.Pop sched.applyDefaultHandlers() diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go index bffe5e0f4db..b4d497b41f4 100644 --- a/pkg/scheduler/scheduler_test.go +++ b/pkg/scheduler/scheduler_test.go @@ -844,7 +844,7 @@ func Test_UnionedGVKs(t *testing.T) { enableInPlacePodVerticalScaling bool enableDynamicResourceAllocation bool enableNodeDeclaredFeatures bool - enableGangScheduling bool + enableGenericWorkload bool }{ { name: "filter without EnqueueExtensions plugin", @@ -896,7 +896,7 @@ func Test_UnionedGVKs(t *testing.T) { fwk.DeviceClass: fwk.All, fwk.PodGroup: fwk.All, }, - enableGangScheduling: true, + enableGenericWorkload: true, enableInPlacePodVerticalScaling: true, enableDynamicResourceAllocation: true, }, @@ -1055,7 +1055,7 @@ func Test_UnionedGVKs(t *testing.T) { fwk.ResourceSlice: fwk.All - fwk.Delete, fwk.PodGroup: fwk.Add, }, - enableGangScheduling: true, + enableGenericWorkload: true, enableInPlacePodVerticalScaling: true, enableDynamicResourceAllocation: true, }, @@ -1080,11 +1080,9 @@ func Test_UnionedGVKs(t *testing.T) { } } } else { - featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.NodeDeclaredFeatures, tt.enableNodeDeclaredFeatures) featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.NodeDeclaredFeatures: tt.enableNodeDeclaredFeatures, - features.GenericWorkload: tt.enableGangScheduling, - features.GangScheduling: tt.enableGangScheduling, + features.GenericWorkload: tt.enableGenericWorkload, }) } featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ diff --git a/pkg/scheduler/util/utils.go b/pkg/scheduler/util/utils.go index 74979020a40..7ef08b45d19 100644 --- a/pkg/scheduler/util/utils.go +++ b/pkg/scheduler/util/utils.go @@ -279,7 +279,6 @@ func PodGroupPriority(pg *schedulingv1alpha3.PodGroup) int32 { } // When priority of a pod group is nil, it means it was created at a time // that there was no global default priority class and the priority class - // name of the pod group was empty (or when the WorkloadAwarePreemption - // feature gate was disabled). So, we resolve to the static default priority. + // name of the pod group was empty. So, we resolve to the static default priority. return 0 } diff --git a/plugin/pkg/admission/priority/admission.go b/plugin/pkg/admission/priority/admission.go index 91101f4f533..b23092d7ece 100644 --- a/plugin/pkg/admission/priority/admission.go +++ b/plugin/pkg/admission/priority/admission.go @@ -194,7 +194,7 @@ func (p *Plugin) admitPod(a admission.Attributes) error { // admitPodGroup makes sure a new pod group does not set spec.Priority field. It also makes sure that // the PriorityClassName exists if it is provided and resolves the pod group priority from the PriorityClassName. func (p *Plugin) admitPodGroup(attributes admission.Attributes) error { - if !utilfeature.DefaultFeatureGate.Enabled(features.WorkloadAwarePreemption) { + if !utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) { return nil } diff --git a/plugin/pkg/admission/priority/admission_test.go b/plugin/pkg/admission/priority/admission_test.go index bc1b08e7f6d..f48205586b9 100644 --- a/plugin/pkg/admission/priority/admission_test.go +++ b/plugin/pkg/admission/priority/admission_test.go @@ -812,40 +812,40 @@ func TestAdmitPodGroup(t *testing.T) { } testCases := []struct { - name string - priorityClasses []*scheduling.PriorityClass - preparePodGroup *scheduling.PodGroup - operation admission.Operation - expectedPriorityClass string - expectedPriority int32 - enableWorkloadAwarePreemption bool - expectError bool + name string + priorityClasses []*scheduling.PriorityClass + preparePodGroup *scheduling.PodGroup + operation admission.Operation + expectedPriorityClass string + expectedPriority int32 + enableGenericWorkload bool + expectError bool }{ { - name: "pod group with empty priorityClassName, accepted and set to global default", - priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, - preparePodGroup: podGroup("" /* empty priorityClassName */), - operation: admission.Create, - expectedPriorityClass: "default1", - expectedPriority: defaultClass1.Value, - enableWorkloadAwarePreemption: true, + name: "pod group with empty priorityClassName, accepted and set to global default", + priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, + preparePodGroup: podGroup("" /* empty priorityClassName */), + operation: admission.Create, + expectedPriorityClass: "default1", + expectedPriority: defaultClass1.Value, + enableGenericWorkload: true, }, { - name: "pod group with explicit priorityClassName, accepted", - priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, - preparePodGroup: podGroup("nondefault1"), - operation: admission.Create, - expectedPriorityClass: "nondefault1", - expectedPriority: nondefaultClass1.Value, - enableWorkloadAwarePreemption: true, + name: "pod group with explicit priorityClassName, accepted", + priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, + preparePodGroup: podGroup("nondefault1"), + operation: admission.Create, + expectedPriorityClass: "nondefault1", + expectedPriority: nondefaultClass1.Value, + enableGenericWorkload: true, }, { - name: "pod group with non-existent priorityClassName, rejected", - priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, - preparePodGroup: podGroup("non-existent"), - operation: admission.Create, - enableWorkloadAwarePreemption: true, - expectError: true, + name: "pod group with non-existent priorityClassName, rejected", + priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, + preparePodGroup: podGroup("non-existent"), + operation: admission.Create, + enableGenericWorkload: true, + expectError: true, }, { name: "pod group with any priorityClassName but feature gate disabled, skips validation", @@ -854,46 +854,44 @@ func TestAdmitPodGroup(t *testing.T) { operation: admission.Create, }, { - name: "pod group with no priorityClassName and no global default, accepted and priority should be zero", - priorityClasses: []*scheduling.PriorityClass{nondefaultClass1}, - preparePodGroup: podGroup("" /* empty priorityClassName */), - operation: admission.Create, - expectedPriorityClass: "", - expectedPriority: 0, - enableWorkloadAwarePreemption: true, + name: "pod group with no priorityClassName and no global default, accepted and priority should be zero", + priorityClasses: []*scheduling.PriorityClass{nondefaultClass1}, + preparePodGroup: podGroup("" /* empty priorityClassName */), + operation: admission.Create, + expectedPriorityClass: "", + expectedPriority: 0, + enableGenericWorkload: true, }, { - name: "pod group create with pre-set Priority matching computed value, accepted", - priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, - preparePodGroup: podGroupWithPriority("nondefault1", nondefaultClass1.Value), - operation: admission.Create, - expectedPriorityClass: "nondefault1", - expectedPriority: nondefaultClass1.Value, - enableWorkloadAwarePreemption: true, + name: "pod group create with pre-set Priority matching computed value, accepted", + priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, + preparePodGroup: podGroupWithPriority("nondefault1", nondefaultClass1.Value), + operation: admission.Create, + expectedPriorityClass: "nondefault1", + expectedPriority: nondefaultClass1.Value, + enableGenericWorkload: true, }, { - name: "pod group create with pre-set Priority not matching computed value, rejected", - priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, - preparePodGroup: podGroupWithPriority("nondefault1", int32(9999)), - operation: admission.Create, - enableWorkloadAwarePreemption: true, - expectError: true, + name: "pod group create with pre-set Priority not matching computed value, rejected", + priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, + preparePodGroup: podGroupWithPriority("nondefault1", int32(9999)), + operation: admission.Create, + enableGenericWorkload: true, + expectError: true, }, { - name: "update operation is a no-op, admission does not mutate pod group on update", - priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, - preparePodGroup: podGroup("non-existent"), - operation: admission.Update, - enableWorkloadAwarePreemption: true, + name: "update operation is a no-op, admission does not mutate pod group on update", + priorityClasses: []*scheduling.PriorityClass{defaultClass1, nondefaultClass1}, + preparePodGroup: podGroup("non-existent"), + operation: admission.Update, + enableGenericWorkload: true, }, } for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, feature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ - features.GenericWorkload: true, - features.GangScheduling: true, - features.WorkloadAwarePreemption: tt.enableWorkloadAwarePreemption, + features.GenericWorkload: tt.enableGenericWorkload, }) admissionPlugin := NewPlugin() @@ -907,7 +905,7 @@ func TestAdmitPodGroup(t *testing.T) { if (err != nil) != tt.expectError { t.Errorf("PodGroup Admit(), error = %v, want = %v", err, tt.expectError) } - if !tt.expectError && tt.operation == admission.Create && tt.enableWorkloadAwarePreemption && tt.preparePodGroup.Spec.PodGroupTemplateRef == nil { + if !tt.expectError && tt.operation == admission.Create && tt.enableGenericWorkload && tt.preparePodGroup.Spec.PodGroupTemplateRef == nil { if tt.preparePodGroup.Spec.PriorityClassName != tt.expectedPriorityClass { t.Errorf("PodGroup Admit(), priorityClassName = %v, want = %v", tt.preparePodGroup.Spec.PriorityClassName, tt.expectedPriorityClass) } diff --git a/staging/src/k8s.io/client-go/applyconfigurations/scheduling/v1alpha3/podgroupspec.go b/staging/src/k8s.io/client-go/applyconfigurations/scheduling/v1alpha3/podgroupspec.go index de2e80fe5db..148869feb96 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/scheduling/v1alpha3/podgroupspec.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/scheduling/v1alpha3/podgroupspec.go @@ -50,8 +50,6 @@ type PodGroupSpecApplyConfiguration struct { // Controllers are expected to fill this field by copying it from a PodGroupTemplate. // One of Single, All. Defaults to Single if unset. // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. DisruptionMode *DisruptionModeApplyConfiguration `json:"disruptionMode,omitempty"` // PriorityClassName defines the priority that should be considered when scheduling this pod group. // Controllers are expected to fill this field by copying it from a PodGroupTemplate. @@ -59,8 +57,6 @@ type PodGroupSpecApplyConfiguration struct { // (i.e. if no priority class is specified, admission control can set this to the global default // priority class if it exists. Otherwise, the pod group's priority will be zero). // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. PriorityClassName *string `json:"priorityClassName,omitempty"` // Priority is the value of priority of this pod group. Various system components // use this field to find the priority of the pod group. When Priority Admission @@ -68,8 +64,6 @@ type PodGroupSpecApplyConfiguration struct { // controller populates this field from PriorityClassName. // The higher the value, the higher the priority. // This field is immutable. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. Priority *int32 `json:"priority,omitempty"` } diff --git a/staging/src/k8s.io/client-go/applyconfigurations/scheduling/v1alpha3/podgrouptemplate.go b/staging/src/k8s.io/client-go/applyconfigurations/scheduling/v1alpha3/podgrouptemplate.go index b7861c7ee85..6ffdf5fe136 100644 --- a/staging/src/k8s.io/client-go/applyconfigurations/scheduling/v1alpha3/podgrouptemplate.go +++ b/staging/src/k8s.io/client-go/applyconfigurations/scheduling/v1alpha3/podgrouptemplate.go @@ -44,23 +44,17 @@ type PodGroupTemplateApplyConfiguration struct { ResourceClaims []PodGroupResourceClaimApplyConfiguration `json:"resourceClaims,omitempty"` // DisruptionMode defines the mode in which a given PodGroup can be disrupted. // One of Single, All. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. DisruptionMode *DisruptionModeApplyConfiguration `json:"disruptionMode,omitempty"` // PriorityClassName indicates the priority that should be considered when scheduling // a pod group created from this template. If no priority class is specified, admission // control can set this to the global default priority class if it exists. Otherwise, // pod groups created from this template will have the priority set to zero. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. PriorityClassName *string `json:"priorityClassName,omitempty"` // Priority is the value of priority of pod groups created from this template. Various // system components use this field to find the priority of the pod group. When // Priority Admission Controller is enabled, it prevents users from setting this field. // The admission controller populates this field from PriorityClassName. // The higher the value, the higher the priority. - // This field is available only when the WorkloadAwarePreemption feature gate - // is enabled. Priority *int32 `json:"priority,omitempty"` } diff --git a/test/compatibility_lifecycle/reference/feature_list.md b/test/compatibility_lifecycle/reference/feature_list.md index 95d5186c5cb..7bfb2cd520d 100644 --- a/test/compatibility_lifecycle/reference/feature_list.md +++ b/test/compatibility_lifecycle/reference/feature_list.md @@ -78,7 +78,6 @@ | ExecProbeTimeout | :ballot_box_with_check: 1.20+ | :closed_lock_with_key: 1.35+ | | | 1.20– | | | [code](https://cs.k8s.io/?q=%5CbExecProbeTimeout%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbExecProbeTimeout%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | ExtendWebSocketsToKubelet | :ballot_box_with_check: 1.36+ | | | 1.36– | | | NodeDeclaredFeatures | [code](https://cs.k8s.io/?q=%5CbExtendWebSocketsToKubelet%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbExtendWebSocketsToKubelet%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | ExternalServiceAccountTokenSigner | :ballot_box_with_check: 1.34+ | :closed_lock_with_key: 1.36+ | 1.32–1.33 | 1.34–1.35 | 1.36– | | | [code](https://cs.k8s.io/?q=%5CbExternalServiceAccountTokenSigner%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbExternalServiceAccountTokenSigner%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | -| GangScheduling | | | 1.35– | | | | GenericWorkload | [code](https://cs.k8s.io/?q=%5CbGangScheduling%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbGangScheduling%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | GenericWorkload | | | 1.35– | | | | | [code](https://cs.k8s.io/?q=%5CbGenericWorkload%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbGenericWorkload%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | GitRepoVolumeDriver | :ballot_box_with_check: 1.0+ | :closed_lock_with_key: 1.36+ | | | 1.0–1.32 | 1.33– | | [code](https://cs.k8s.io/?q=%5CbGitRepoVolumeDriver%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbGitRepoVolumeDriver%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | GracefulNodeShutdown | :ballot_box_with_check: 1.21+ | | 1.20 | 1.21– | | | | [code](https://cs.k8s.io/?q=%5CbGracefulNodeShutdown%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbGracefulNodeShutdown%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | @@ -225,7 +224,6 @@ | WindowsCPUAndMemoryAffinity | | | 1.32– | | | | | [code](https://cs.k8s.io/?q=%5CbWindowsCPUAndMemoryAffinity%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbWindowsCPUAndMemoryAffinity%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | WindowsGracefulNodeShutdown | :ballot_box_with_check: 1.34+ | | 1.32–1.33 | 1.34– | | | GracefulNodeShutdown | [code](https://cs.k8s.io/?q=%5CbWindowsGracefulNodeShutdown%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbWindowsGracefulNodeShutdown%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | WindowsHostNetwork | | | 1.26–1.32 | | | 1.33– | | [code](https://cs.k8s.io/?q=%5CbWindowsHostNetwork%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbWindowsHostNetwork%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | -| WorkloadAwarePreemption | | | 1.36– | | | | GangScheduling | [code](https://cs.k8s.io/?q=%5CbWorkloadAwarePreemption%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbWorkloadAwarePreemption%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | | WorkloadWithJob | | | 1.36– | | | | GenericWorkload | [code](https://cs.k8s.io/?q=%5CbWorkloadWithJob%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbWorkloadWithJob%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) | ## Legend diff --git a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml index e78aefd623f..83f26845dac 100644 --- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml +++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml @@ -657,12 +657,6 @@ lockToDefault: true preRelease: GA version: "1.36" -- name: GangScheduling - versionedSpecs: - - default: false - lockToDefault: false - preRelease: Alpha - version: "1.35" - name: GenericWorkload versionedSpecs: - default: false @@ -2111,12 +2105,6 @@ lockToDefault: true preRelease: GA version: "1.34" -- name: WorkloadAwarePreemption - versionedSpecs: - - default: false - lockToDefault: false - preRelease: Alpha - version: "1.36" - name: WorkloadWithJob versionedSpecs: - default: false diff --git a/test/declarative_validation/scheduling/podgroup/declarative_validation_test.go b/test/declarative_validation/scheduling/podgroup/declarative_validation_test.go index 241a1a4a386..7d02fe9a6f7 100644 --- a/test/declarative_validation/scheduling/podgroup/declarative_validation_test.go +++ b/test/declarative_validation/scheduling/podgroup/declarative_validation_test.go @@ -59,7 +59,6 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) { input scheduling.PodGroup enableTopologyAwareScheduling bool enableDRAWorkloadResourceClaims bool - enableWorkloadAwarePreemption bool expectedErrs field.ErrorList }{ "valid": { @@ -167,91 +166,42 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) { enableTopologyAwareScheduling: true, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "schedulingConstraints", "topology").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key")}, }, - "pod disruption mode, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeSingle()), - enableWorkloadAwarePreemption: true, + "pod group disruption mode": { + input: mkValidPodGroup(setDisruptionModeAll()), }, - "pod disruption mode, workload aware preemption disabled": { - input: mkValidPodGroup(setDisruptionModeSingle()), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "disruptionMode"), "")}, - }, - "pod group disruption mode, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeAll()), - enableWorkloadAwarePreemption: true, - }, - "pod group disruption mode, workload aware preemption disabled": { - input: mkValidPodGroup(setDisruptionModeAll()), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "disruptionMode"), "")}, - }, - "disruption mode with neither single nor all, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeNeither()), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "disruptionMode"), nil, "").WithOrigin("union")}, - }, - "disruption mode with neither single nor all, workload aware preemption disabled": { + "disruption mode with neither single nor all": { input: mkValidPodGroup(setDisruptionModeNeither()), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "disruptionMode"), "")}, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "disruptionMode"), nil, "").WithOrigin("union")}, }, - "disruption mode with both single and all, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeBoth()), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "disruptionMode"), nil, "").WithOrigin("union")}, - }, - "disruption mode with both single and all, workload aware preemption disabled": { + "disruption mode with both single and all": { input: mkValidPodGroup(setDisruptionModeBoth()), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "disruptionMode"), "")}, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "disruptionMode"), nil, "").WithOrigin("union")}, }, - "valid pod group without disruption mode, workload aware preemption enabled": { - input: mkValidPodGroup(), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Required(field.NewPath("spec", "disruptionMode"), "")}, + "pod group without disruption mode": { + input: mkValidPodGroup(clearDisruptionMode()), + expectedErrs: field.ErrorList{field.Required(field.NewPath("spec", "disruptionMode"), "")}, }, - "valid priority class name, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeSingle(), setPriorityClassName("high-priority")), - enableWorkloadAwarePreemption: true, + "valid priority class name": { + input: mkValidPodGroup(setPriorityClassName("high-priority")), }, - "valid priority class name, workload aware preemption disabled": { - input: mkValidPodGroup(setPriorityClassName("high-priority")), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "priorityClassName"), "")}, - }, - "invalid priority class name, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeSingle(), setPriorityClassName("high/priority")), - enableWorkloadAwarePreemption: true, + "invalid priority class name": { + input: mkValidPodGroup(setPriorityClassName("high/priority")), expectedErrs: field.ErrorList{ field.Invalid(field.NewPath("spec", "priorityClassName"), nil, "").WithOrigin("format=k8s-long-name"), }, }, - "invalid priority class name, workload aware preemption disabled": { - input: mkValidPodGroup(setPriorityClassName("high/priority")), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "priorityClassName"), "")}, + "valid priority": { + input: mkValidPodGroup(setPriority(1000)), }, - "valid priority, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeSingle(), setPriority(1000)), - enableWorkloadAwarePreemption: true, + "valid negative priority": { + input: mkValidPodGroup(setPriority(-2147483648)), }, - "valid priority, workload aware preemption disabled": { - input: mkValidPodGroup(setPriority(1000)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "priority"), "")}, - }, - "valid negative priority, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeSingle(), setPriority(-2147483648)), - enableWorkloadAwarePreemption: true, - }, - "valid negative priority, workload aware preemption disabled": { - input: mkValidPodGroup(setPriority(-2147483648)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "priority"), "")}, - }, - "too high priority, workload aware preemption enabled": { - input: mkValidPodGroup(setDisruptionModeSingle(), setPriority(scheduling.HighestUserDefinablePriority+1)), - enableWorkloadAwarePreemption: true, + "too high priority": { + input: mkValidPodGroup(setPriority(scheduling.HighestUserDefinablePriority + 1)), expectedErrs: field.ErrorList{ field.Invalid(field.NewPath("spec", "priority"), nil, "").WithOrigin("maximum"), }, }, - "too high priority, workload aware preemption disabled": { - input: mkValidPodGroup(setPriority(scheduling.HighestUserDefinablePriority + 1)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "priority"), "")}, - }, "ok resourceClaimName reference": { input: mkValidPodGroup(addResourceClaims(scheduling.PodGroupResourceClaim{Name: "claim", ResourceClaimName: new("resource-claim")})), }, @@ -348,8 +298,6 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) { features.GenericWorkload: true, features.TopologyAwareWorkloadScheduling: tc.enableTopologyAwareScheduling, features.DRAWorkloadResourceClaims: tc.enableDRAWorkloadResourceClaims, - features.GangScheduling: tc.enableWorkloadAwarePreemption, - features.WorkloadAwarePreemption: tc.enableWorkloadAwarePreemption, }) apitesting.VerifyValidationEquivalence(t, ctx, &tc.input, strategy, tc.expectedErrs) }) @@ -380,7 +328,6 @@ func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) { updateObj scheduling.PodGroup enableTopologyAwareScheduling bool enableDRAWorkloadResourceClaims bool - enableWorkloadAwarePreemption bool expectedErrs field.ErrorList }{ "valid update": { @@ -532,38 +479,20 @@ func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) { enableDRAWorkloadResourceClaims: true, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "resourceClaims"), nil, "").WithOrigin("immutable")}, }, - "invalid update of disruption mode, workload aware preemption enabled": { - oldObj: mkValidPodGroup(setResourceVersion("1"), setDisruptionModeSingle()), - updateObj: mkValidPodGroup(setResourceVersion("1"), setDisruptionModeAll()), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "disruptionMode"), &scheduling.DisruptionMode{All: &scheduling.AllDisruptionMode{}}, "field is immutable").WithOrigin("immutable")}, - }, - "invalid update of disruption mode, workload aware preemption disabled": { - oldObj: mkValidPodGroup(setResourceVersion("1"), setDisruptionModeSingle()), + "invalid update of disruption mode": { + oldObj: mkValidPodGroup(setResourceVersion("1")), updateObj: mkValidPodGroup(setResourceVersion("1"), setDisruptionModeAll()), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "disruptionMode"), "")}, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "disruptionMode"), &scheduling.DisruptionMode{All: &scheduling.AllDisruptionMode{}}, "field is immutable").WithOrigin("immutable")}, }, - "invalid update of priority class name, workload aware preemption enabled": { - oldObj: mkValidPodGroup(setResourceVersion("1"), setPriorityClassName("low-priority")), - updateObj: mkValidPodGroup(setResourceVersion("1"), setPriorityClassName("high-priority")), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "priorityClassName"), nil, "").WithOrigin("immutable")}, - }, - "invalid update of priority class name, workload aware preemption disabled": { + "invalid update of priority class name": { oldObj: mkValidPodGroup(setResourceVersion("1"), setPriorityClassName("low-priority")), updateObj: mkValidPodGroup(setResourceVersion("1"), setPriorityClassName("high-priority")), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "priorityClassName"), "")}, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "priorityClassName"), nil, "").WithOrigin("immutable")}, }, - "invalid update of priority, workload aware preemption enabled": { - oldObj: mkValidPodGroup(setResourceVersion("1"), setPriority(1000)), - updateObj: mkValidPodGroup(setResourceVersion("1"), setPriority(2000)), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "priority"), nil, "").WithOrigin("immutable")}, - }, - "invalid update of priority, workload aware preemption disabled": { + "invalid update of priority": { oldObj: mkValidPodGroup(setResourceVersion("1"), setPriority(1000)), updateObj: mkValidPodGroup(setResourceVersion("1"), setPriority(2000)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "priority"), "")}, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "priority"), nil, "").WithOrigin("immutable")}, }, } for k, tc := range testCases { @@ -572,8 +501,6 @@ func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) { features.GenericWorkload: true, features.TopologyAwareWorkloadScheduling: tc.enableTopologyAwareScheduling, features.DRAWorkloadResourceClaims: tc.enableDRAWorkloadResourceClaims, - features.GangScheduling: tc.enableWorkloadAwarePreemption, - features.WorkloadAwarePreemption: tc.enableWorkloadAwarePreemption, }) strategy := registry.NewStrategy() apitesting.VerifyUpdateValidationEquivalence(t, ctx, &tc.updateObj, &tc.oldObj, strategy, tc.expectedErrs) @@ -729,6 +656,9 @@ func mkValidPodGroup(tweaks ...func(pg *scheduling.PodGroup)) scheduling.PodGrou MinCount: 5, }, }, + DisruptionMode: &scheduling.DisruptionMode{ + Single: &scheduling.SingleDisruptionMode{}, + }, }, } for _, tweak := range tweaks { @@ -856,14 +786,6 @@ func addTopologyConstraint(value string) func(obj *scheduling.PodGroup) { } } -func setDisruptionModeSingle() func(obj *scheduling.PodGroup) { - return func(obj *scheduling.PodGroup) { - obj.Spec.DisruptionMode = &scheduling.DisruptionMode{ - Single: &scheduling.SingleDisruptionMode{}, - } - } -} - func setDisruptionModeAll() func(obj *scheduling.PodGroup) { return func(obj *scheduling.PodGroup) { obj.Spec.DisruptionMode = &scheduling.DisruptionMode{ @@ -898,3 +820,9 @@ func setPriority(priority int32) func(obj *scheduling.PodGroup) { obj.Spec.Priority = new(priority) } } + +func clearDisruptionMode() func(obj *scheduling.PodGroup) { + return func(obj *scheduling.PodGroup) { + obj.Spec.DisruptionMode = nil + } +} diff --git a/test/declarative_validation/scheduling/workload/declarative_validation_test.go b/test/declarative_validation/scheduling/workload/declarative_validation_test.go index 9ba674fe8a0..566ac3d3db9 100644 --- a/test/declarative_validation/scheduling/workload/declarative_validation_test.go +++ b/test/declarative_validation/scheduling/workload/declarative_validation_test.go @@ -58,7 +58,6 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) { input scheduling.Workload enableTopologyAwareScheduling bool enableDRAWorkloadResourceClaims bool - enableWorkloadAwarePreemption bool expectedErrs field.ErrorList }{ "valid": { @@ -189,87 +188,41 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) { enableTopologyAwareScheduling: true, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates").Index(0).Child("schedulingConstraints", "topology").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key")}, }, - "pod disruption mode, workload aware preemption enabled": { - input: mkValidWorkload(setDisruptionModeSingle(0)), - enableWorkloadAwarePreemption: true, + "disruption mode single": { + input: mkValidWorkload(setDisruptionModeSingle(0)), }, - "pod disruption mode, workload aware preemption disabled": { - input: mkValidWorkload(setDisruptionModeSingle(0)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("disruptionMode"), "")}, + "disruption mode all": { + input: mkValidWorkload(setDisruptionModeAll(0)), }, - "pod group disruption mode, workload aware preemption enabled": { - input: mkValidWorkload(setDisruptionModeAll(0)), - enableWorkloadAwarePreemption: true, - }, - "pod group disruption mode, workload aware preemption disabled": { - input: mkValidWorkload(setDisruptionModeAll(0)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("disruptionMode"), "")}, - }, - "disruption mode with neither single nor all, workload aware preemption enabled": { - input: mkValidWorkload(setDisruptionModeNeither(0)), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates").Index(0).Child("disruptionMode"), nil, "").WithOrigin("union")}, - }, - "disruption mode with neither single nor all, workload aware preemption disabled": { + "disruption mode with neither single nor all": { input: mkValidWorkload(setDisruptionModeNeither(0)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("disruptionMode"), "")}, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates").Index(0).Child("disruptionMode"), nil, "").WithOrigin("union")}, }, - "disruption mode with both single and all, workload aware preemption enabled": { - input: mkValidWorkload(setDisruptionModeBoth(0)), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates").Index(0).Child("disruptionMode"), nil, "").WithOrigin("union")}, - }, - "disruption mode with both single and all, workload aware preemption disabled": { + "disruption mode with both single and all": { input: mkValidWorkload(setDisruptionModeBoth(0)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("disruptionMode"), "")}, + expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates").Index(0).Child("disruptionMode"), nil, "").WithOrigin("union")}, }, - "valid priorityClassName, workload aware preemption enabled": { - input: mkValidWorkload(setPriorityClassName(0, "high-priority")), - enableWorkloadAwarePreemption: true, + "valid priorityClassName": { + input: mkValidWorkload(setPriorityClassName(0, "high-priority")), }, - "valid priorityClassName, workload aware preemption disabled": { - input: mkValidWorkload(setPriorityClassName(0, "high-priority")), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("priorityClassName"), "")}, - }, - "invalid priorityClassName, workload aware preemption enabled": { - input: mkValidWorkload(setPriorityClassName(0, "high/priority")), - enableWorkloadAwarePreemption: true, + "invalid priorityClassName": { + input: mkValidWorkload(setPriorityClassName(0, "high/priority")), expectedErrs: field.ErrorList{ field.Invalid(field.NewPath("spec", "podGroupTemplates").Index(0).Child("priorityClassName"), nil, "").WithOrigin("format=k8s-long-name"), }, }, - "invalid priorityClassName, workload aware preemption disabled": { - input: mkValidWorkload(setPriorityClassName(0, "high/priority")), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("priorityClassName"), "")}, + "valid priority": { + input: mkValidWorkload(setPriority(0, 1000)), }, - - "valid priority, workload aware preemption enabled": { - input: mkValidWorkload(setPriority(0, 1000)), - enableWorkloadAwarePreemption: true, + "valid negative priority": { + input: mkValidWorkload(setPriority(0, -2147483648)), }, - "valid priority, workload aware preemption disabled": { - input: mkValidWorkload(setPriority(0, 1000)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("priority"), "")}, - }, - "valid negative priority, workload aware preemption enabled": { - input: mkValidWorkload(setPriority(0, -2147483648)), - enableWorkloadAwarePreemption: true, - }, - "valid negative priority, workload aware preemption disabled": { - input: mkValidWorkload(setPriority(0, -2147483648)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("priority"), "")}, - }, - "too high priority, workload aware preemption enabled": { - input: mkValidWorkload(setPriority(0, scheduling.HighestUserDefinablePriority+1)), - enableWorkloadAwarePreemption: true, + "too high priority": { + input: mkValidWorkload(setPriority(0, scheduling.HighestUserDefinablePriority+1)), expectedErrs: field.ErrorList{ field.Invalid(field.NewPath("spec", "podGroupTemplates").Index(0).Child("priority"), nil, "").WithOrigin("maximum"), }, }, - "too high priority, workload aware preemption disabled": { - input: mkValidWorkload(setPriority(0, scheduling.HighestUserDefinablePriority+1)), - expectedErrs: field.ErrorList{field.Forbidden(field.NewPath("spec", "podGroupTemplates").Index(0).Child("priority"), "")}, - }, "ok resourceClaimName reference": { input: mkValidWorkload(addResourceClaims(scheduling.PodGroupResourceClaim{Name: "claim", ResourceClaimName: new("resource-claim")})), }, @@ -369,8 +322,6 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) { features.GenericWorkload: true, features.TopologyAwareWorkloadScheduling: tc.enableTopologyAwareScheduling, features.DRAWorkloadResourceClaims: tc.enableDRAWorkloadResourceClaims, - features.GangScheduling: tc.enableWorkloadAwarePreemption, - features.WorkloadAwarePreemption: tc.enableWorkloadAwarePreemption, }) apitesting.VerifyValidationEquivalence(t, ctx, &tc.input, registry.Strategy, tc.expectedErrs) }) @@ -392,7 +343,6 @@ func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) { updateObj scheduling.Workload enableTopologyAwareScheduling bool enableDRAWorkloadResourceClaims bool - enableWorkloadAwarePreemption bool expectedErrs field.ErrorList }{ "valid update": { @@ -566,35 +516,17 @@ func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) { enableDRAWorkloadResourceClaims: true, expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates"), nil, "").WithOrigin("immutable")}, }, - "invalid update of disruption mode, workload aware preemption enabled": { - oldObj: mkValidWorkload(setResourceVersion("1"), setDisruptionModeSingle(0)), - updateObj: mkValidWorkload(setResourceVersion("1"), setDisruptionModeAll(0)), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates"), nil, "").WithOrigin("immutable")}, - }, - "invalid update of disruption mode, workload aware preemption disabled": { + "invalid update of disruption mode": { oldObj: mkValidWorkload(setResourceVersion("1"), setDisruptionModeSingle(0)), updateObj: mkValidWorkload(setResourceVersion("1"), setDisruptionModeAll(0)), expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates"), nil, "").WithOrigin("immutable")}, }, - "invalid update of priority class name, workload aware preemption enabled": { - oldObj: mkValidWorkload(setResourceVersion("1"), setPriorityClassName(0, "low-priority")), - updateObj: mkValidWorkload(setResourceVersion("1"), setPriorityClassName(0, "high-priority")), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates"), nil, "").WithOrigin("immutable")}, - }, - "invalid update of priority class name, workload aware preemption disabled": { + "invalid update of priority class name": { oldObj: mkValidWorkload(setResourceVersion("1"), setPriorityClassName(0, "low-priority")), updateObj: mkValidWorkload(setResourceVersion("1"), setPriorityClassName(0, "high-priority")), expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates"), nil, "").WithOrigin("immutable")}, }, - "invalid update of priority, workload aware preemption enabled": { - oldObj: mkValidWorkload(setResourceVersion("1"), setPriority(0, 1000)), - updateObj: mkValidWorkload(setResourceVersion("1"), setPriority(0, 2000)), - enableWorkloadAwarePreemption: true, - expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates"), nil, "").WithOrigin("immutable")}, - }, - "invalid update of priority, workload aware preemption disabled": { + "invalid update of priority": { oldObj: mkValidWorkload(setResourceVersion("1"), setPriority(0, 1000)), updateObj: mkValidWorkload(setResourceVersion("1"), setPriority(0, 2000)), expectedErrs: field.ErrorList{field.Invalid(field.NewPath("spec", "podGroupTemplates"), nil, "").WithOrigin("immutable")}, @@ -606,8 +538,6 @@ func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) { features.GenericWorkload: true, features.TopologyAwareWorkloadScheduling: tc.enableTopologyAwareScheduling, features.DRAWorkloadResourceClaims: tc.enableDRAWorkloadResourceClaims, - features.GangScheduling: tc.enableWorkloadAwarePreemption, - features.WorkloadAwarePreemption: tc.enableWorkloadAwarePreemption, }) ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{ APIPrefix: "apis", diff --git a/test/e2e/scheduling/gang_scheduling.go b/test/e2e/scheduling/gang_scheduling.go index c252137f74d..4d199478ec3 100644 --- a/test/e2e/scheduling/gang_scheduling.go +++ b/test/e2e/scheduling/gang_scheduling.go @@ -32,7 +32,7 @@ import ( admissionapi "k8s.io/pod-security-admission/api" ) -var _ = SIGDescribe("GangScheduling", framework.WithFeatureGate(features.GangScheduling), func() { +var _ = SIGDescribe("GangScheduling", framework.WithFeatureGate(features.GenericWorkload), func() { f := framework.NewDefaultFramework("gang-scheduling") f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged diff --git a/test/integration/dra/dra.go b/test/integration/dra/dra.go index 7810a43e1f0..077f04a19ed 100644 --- a/test/integration/dra/dra.go +++ b/test/integration/dra/dra.go @@ -229,8 +229,7 @@ func run(tCtx ktesting.TContext, whatRE string) { features.DRAExtendedResource: true, features.DRANodeAllocatableResources: true, features.DRAWorkloadResourceClaims: true, - features.GangScheduling: true, - features.GenericWorkload: true, // dependency of DRAWorkloadResourceClaims, GangScheduling + features.GenericWorkload: true, // dependency of DRAWorkloadResourceClaims }, f: func(tCtx ktesting.TContext) { // These tests must run in parallel as much as possible to keep overall runtime low! diff --git a/test/integration/scheduler/podgroup/podgroup_test.go b/test/integration/scheduler/podgroup/podgroup_test.go index 80dcc495144..1b7f4c70127 100644 --- a/test/integration/scheduler/podgroup/podgroup_test.go +++ b/test/integration/scheduler/podgroup/podgroup_test.go @@ -110,7 +110,6 @@ func TestPodGroupScheduling(t *testing.T) { tests := []struct { name string - enableWorkloadAwarePreemption bool enableTopologyAwareWorkloadScheduling []bool steps []stepsframework.Step }{ @@ -304,43 +303,6 @@ func TestPodGroupScheduling(t *testing.T) { }, }, }, - { - name: "gang schedules with preemption", - steps: []stepsframework.Step{ - { - Name: "Create a low priority pod taking all resources", - CreatePods: []*v1.Pod{lowPriorityBlockerPod}, - }, - { - Name: "Schedule the low priority resource-blocking pod", - WaitForPodsScheduled: []string{"low-priority-blocker"}, - }, - { - Name: "Create the PodGroup object", - CreatePodGroup: gangPodGroup, - }, - { - Name: "Create high priority gang pods", - CreatePods: []*v1.Pod{p1, p2, p3, p4}, - }, - { - Name: "Verify all gang pods are scheduled successfully (after preemption)", - WaitForPodsScheduled: []string{"p1", "p2", "p3", "p4"}, - }, - { - Name: "Verify PodGroup condition is set to Scheduled after preemption completes", - WaitForPodGroupCondition: &stepsframework.PodGroupConditionCheck{ - PodGroupName: "pg1", - ConditionStatus: metav1.ConditionTrue, - Reason: "Scheduled", - }, - }, - { - Name: "Verify preemption victims were removed", - WaitForPodsRemoved: []string{"low-priority-blocker"}, - }, - }, - }, { name: "basic group schedules when pod group and resources are available, without gang enforcement", steps: []stepsframework.Step{ @@ -407,39 +369,9 @@ func TestPodGroupScheduling(t *testing.T) { }, }, }, - { - name: "basic group schedules with preemption", - steps: []stepsframework.Step{ - { - Name: "Create a low priority pod taking all resources", - CreatePods: []*v1.Pod{lowPriorityBlockerPod}, - }, - { - Name: "Schedule the low priority resource-blocking pod", - WaitForPodsScheduled: []string{"low-priority-blocker"}, - }, - { - Name: "Create the PodGroup object", - CreatePodGroup: basicPodGroup, - }, - { - Name: "Create high priority group's pods", - CreatePods: []*v1.Pod{p1, p2, p3, p4}, - }, - { - Name: "Verify all group's pods are scheduled successfully (after preemption)", - WaitForPodsScheduled: []string{"p1", "p2", "p3", "p4"}, - }, - { - Name: "Verify preemption victims were removed", - WaitForPodsRemoved: []string{"low-priority-blocker"}, - }, - }, - }, { name: "basic group schedules with workload-aware preemption", enableTopologyAwareWorkloadScheduling: []bool{false}, - enableWorkloadAwarePreemption: true, steps: []stepsframework.Step{ { Name: "Create a low priority pod taking all resources", @@ -468,8 +400,7 @@ func TestPodGroupScheduling(t *testing.T) { }, }, { - name: "gang schedules with workload-aware preemption", - enableWorkloadAwarePreemption: true, + name: "gang schedules with workload-aware preemption", steps: []stepsframework.Step{ { Name: "Create low priority pods that take up all node resources", @@ -480,7 +411,7 @@ func TestPodGroupScheduling(t *testing.T) { WaitForPodsScheduled: []string{"low-p1", "low-p2", "low-p3", "low-p4"}, }, { - Name: "Create the Workload object", + Name: "Create the PodGroup object", CreatePodGroup: gangPodGroup, }, { @@ -491,6 +422,14 @@ func TestPodGroupScheduling(t *testing.T) { Name: "Verify all gang pods are scheduled successfully (after workload-aware preemption)", WaitForPodsScheduled: []string{"p1", "p2", "p3", "p4"}, }, + { + Name: "Verify PodGroup condition is set to Scheduled after preemption completes", + WaitForPodGroupCondition: &stepsframework.PodGroupConditionCheck{ + PodGroupName: "pg1", + ConditionStatus: metav1.ConditionTrue, + Reason: "Scheduled", + }, + }, { Name: "Verify preemption victims were removed", WaitForPodsRemoved: []string{"low-p1", "low-p2", "low-p3", "low-p4"}, @@ -498,8 +437,7 @@ func TestPodGroupScheduling(t *testing.T) { }, }, { - name: "gang schedules with partial workload-aware preemption", - enableWorkloadAwarePreemption: true, + name: "gang schedules with partial workload-aware preemption", steps: []stepsframework.Step{ { Name: "Create very low and low priority pods that take up all node resources", @@ -555,7 +493,6 @@ func TestPodGroupScheduling(t *testing.T) { }, { name: "tas gang with constraint does not use workload preemption", - enableWorkloadAwarePreemption: true, enableTopologyAwareWorkloadScheduling: []bool{true}, steps: []stepsframework.Step{ { @@ -591,9 +528,7 @@ func TestPodGroupScheduling(t *testing.T) { t.Run(fmt.Sprintf("%s (TopologyAwareWorkloadScheduling enabled: %v)", tt.name, tasEnabled), func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, features.TopologyAwareWorkloadScheduling: tasEnabled, - features.WorkloadAwarePreemption: tt.enableWorkloadAwarePreemption, }) testCtx := testutils.InitTestSchedulerWithNS(t, "podgroup-scheduling", @@ -624,9 +559,7 @@ func TestPodGroupScheduling(t *testing.T) { func TestWorkloadAwarePreemptionInvocation(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ - features.GenericWorkload: true, - features.GangScheduling: true, - features.WorkloadAwarePreemption: true, + features.GenericWorkload: true, }) node := st.MakeNode().Name("node").Capacity(map[v1.ResourceName]string{v1.ResourceCPU: "4"}).Obj() @@ -735,9 +668,7 @@ func (m *mockPostFilterPlugin) PostFilter(ctx context.Context, state framework.C func TestPostFilterInvocationCount(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ - features.GenericWorkload: true, - features.GangScheduling: true, - features.WorkloadAwarePreemption: true, + features.GenericWorkload: true, }) node := st.MakeNode().Name("node").Capacity(map[v1.ResourceName]string{v1.ResourceCPU: "4"}).Obj() diff --git a/test/integration/scheduler/podgroup/queueing/queueing_test.go b/test/integration/scheduler/podgroup/queueing/queueing_test.go index f107fb98d5a..a1282935c03 100644 --- a/test/integration/scheduler/podgroup/queueing/queueing_test.go +++ b/test/integration/scheduler/podgroup/queueing/queueing_test.go @@ -691,7 +691,6 @@ func TestPodGroupQueueing(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) var testCtx *testutils.TestContext @@ -835,7 +834,6 @@ func TestPodGroupSequentialQueueing(t *testing.T) { t.Run(tt.name, func(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) testCtx := testutils.InitTestSchedulerWithOptions( diff --git a/test/integration/scheduler/podgroup/topology_aware_scheduling/tas_test.go b/test/integration/scheduler/podgroup/topology_aware_scheduling/tas_test.go index a322c5839da..9f0bcf79cf6 100644 --- a/test/integration/scheduler/podgroup/topology_aware_scheduling/tas_test.go +++ b/test/integration/scheduler/podgroup/topology_aware_scheduling/tas_test.go @@ -17,7 +17,6 @@ limitations under the License. package topologyawarescheduling import ( - "fmt" "testing" v1 "k8s.io/api/core/v1" @@ -658,7 +657,7 @@ func TestTopologyAwareSchedulingWithGangPolicy(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - runTestScenario(t, tt, true /* gangSchedulingEnabled */) + runTestScenario(t, tt) }) } } @@ -1318,19 +1317,16 @@ func TestTopologyAwareSchedulingWithBasicPolicy(t *testing.T) { }, } - for _, gangSchedulingEnabled := range []bool{true, false} { - for _, tt := range tests { - t.Run(fmt.Sprintf("%s (GangScheduling enabled: %v)", tt.name, gangSchedulingEnabled), func(t *testing.T) { - runTestScenario(t, tt, gangSchedulingEnabled) - }) - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + runTestScenario(t, tt) + }) } } -func runTestScenario(t *testing.T, tt scenario, gangSchedulingEnabled bool) { +func runTestScenario(t *testing.T, tt scenario) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: gangSchedulingEnabled, features.TopologyAwareWorkloadScheduling: true, }) diff --git a/test/integration/scheduler/preemption/podgrouppreemption_test.go b/test/integration/scheduler/preemption/podgrouppreemption_test.go index d653d1559a8..f753f59506e 100644 --- a/test/integration/scheduler/preemption/podgrouppreemption_test.go +++ b/test/integration/scheduler/preemption/podgrouppreemption_test.go @@ -50,9 +50,7 @@ import ( // TestPodGroupPreemption tests preemption scenarios involving pod groups. func TestPodGroupPreemption(t *testing.T) { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ - features.GenericWorkload: true, - features.GangScheduling: true, - features.WorkloadAwarePreemption: true, + features.GenericWorkload: true, }) tests := []struct { name string diff --git a/test/integration/scheduler/queueing/queue.go b/test/integration/scheduler/queueing/queue.go index 14b093f8d75..3f4b5ad433e 100644 --- a/test/integration/scheduler/queueing/queue.go +++ b/test/integration/scheduler/queueing/queue.go @@ -111,9 +111,9 @@ type CoreResourceEnqueueTestCase struct { EnableDRAExtendedResource bool // EnableNodeDeclaredFeatures indicates if the test case runs with the NodeDeclaredFeatures feature gate enabled. EnableNodeDeclaredFeatures bool - // EnableGangScheduling indicates wether the test case should run with feature gates - // GenericWorkload and GangScheduling enabled or not. - EnableGangScheduling bool + // EnableGenericWorkload indicates wether the test case should run with feature gate + // GenericWorkload enabled or not. + EnableGenericWorkload bool } // We define all the test cases here in the one place, @@ -2543,7 +2543,7 @@ var CoreResourceEnqueueTestCases = []*CoreResourceEnqueueTestCase{ }, ExpectedInitialRejectingPhase: rejectingPhasePreEnqueue, WantRequeuedPods: sets.New("pod1", "pod3"), - EnableGangScheduling: true, + EnableGenericWorkload: true, }, { Name: "Pod rejected by the GangScheduling plugin is requeued when a matching pod group is created", @@ -2564,7 +2564,7 @@ var CoreResourceEnqueueTestCases = []*CoreResourceEnqueueTestCase{ }, ExpectedInitialRejectingPhase: rejectingPhasePreEnqueue, WantRequeuedPods: sets.New("pod1"), - EnableGangScheduling: true, + EnableGenericWorkload: true, }, } @@ -2590,10 +2590,9 @@ func RunTestCoreResourceEnqueue(t *testing.T, tt *CoreResourceEnqueueTestCase) { ndfFramework := ndf.New([]ndf.Feature{mockFeature}) ndftesting.SetFrameworkDuringTest(t, *ndfFramework) } - if tt.EnableGangScheduling { + if tt.EnableGenericWorkload { featuregatetesting.SetFeatureGatesDuringTest(t, utilfeature.DefaultFeatureGate, featuregatetesting.FeatureOverrides{ features.GenericWorkload: true, - features.GangScheduling: true, }) } logger, _ := ktesting.NewTestContext(t) diff --git a/test/integration/scheduler_perf/podgroup/gangscheduling/performance-config.yaml b/test/integration/scheduler_perf/podgroup/gangscheduling/performance-config.yaml index 50bfd3bbe54..9373b56168f 100644 --- a/test/integration/scheduler_perf/podgroup/gangscheduling/performance-config.yaml +++ b/test/integration/scheduler_perf/podgroup/gangscheduling/performance-config.yaml @@ -7,7 +7,6 @@ - name: GangScheduling featureGates: GenericWorkload: true - GangScheduling: true workloadTemplate: - opcode: createNodes countParam: $initNodes diff --git a/test/integration/scheduler_perf/podgroup/tas/performance-config.yaml b/test/integration/scheduler_perf/podgroup/tas/performance-config.yaml index 6b7b6633693..a345e8b32d0 100644 --- a/test/integration/scheduler_perf/podgroup/tas/performance-config.yaml +++ b/test/integration/scheduler_perf/podgroup/tas/performance-config.yaml @@ -7,7 +7,6 @@ - name: TopologyAwareScheduling featureGates: GenericWorkload: true - GangScheduling: true TopologyAwareWorkloadScheduling: true workloadTemplate: - opcode: createNodes