From 0dbe78185d469d0d54b8613068429cf3d036b448 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 04:28:30 +0300
Subject: [PATCH 01/13] feat(multikueue): implement KEP-9270 stepSize for
Incremental Dispatcher
---
apis/config/v1beta1/configuration_types.go | 17 ++++
apis/config/v1beta1/defaults.go | 6 +-
.../config/v1beta1/zz_generated.conversion.go | 32 +++++++
apis/config/v1beta1/zz_generated.deepcopy.go | 25 ++++++
apis/config/v1beta2/configuration_types.go | 17 ++++
apis/config/v1beta2/defaults.go | 6 +-
apis/config/v1beta2/zz_generated.deepcopy.go | 25 ++++++
.../workloaddispatcher/controllers.go | 2 +-
.../incrementaldispatcher.go | 28 +++++-
.../incrementaldispatcher_test.go | 87 +++++++++++++++++--
pkg/features/kube_features.go | 9 ++
.../en/docs/reference/kueue-config.v1beta1.md | 37 ++++++++
.../en/docs/reference/kueue-config.v1beta2.md | 37 ++++++++
.../featuregates/versioned_feature_list.yaml | 48 ++++++++++
.../reference/versioned_feature_list.yaml | 16 ++--
15 files changed, 364 insertions(+), 28 deletions(-)
diff --git a/apis/config/v1beta1/configuration_types.go b/apis/config/v1beta1/configuration_types.go
index 2d413954aff..cbaacdaa6b1 100644
--- a/apis/config/v1beta1/configuration_types.go
+++ b/apis/config/v1beta1/configuration_types.go
@@ -338,6 +338,23 @@ type MultiKueue struct {
// GroupVersionKind (GVK) for MultiKueue operations.
// +optional
ExternalFrameworks []MultiKueueExternalFramework `json:"externalFrameworks,omitempty"`
+
+ // IncrementalDispatcherConfig contains the configuration for the incremental dispatcher.
+ // This field is only valid when DispatcherName is set to the incremental dispatcher.
+ // Note: This field is going to be ignored when the MultiKueueIncrementalDispatcherConfig feature gate is disabled.
+ // +optional
+ IncrementalDispatcherConfig *IncrementalDispatcherConfig `json:"incrementalDispatcherConfig,omitempty"`
+}
+
+// IncrementalDispatcherConfig holds configuration for the MultiKueue Incremental Dispatcher.
+type IncrementalDispatcherConfig struct {
+ // StepSize defines the number of worker clusters the Incremental Dispatcher
+ // will query simultaneously.
+ // Minimum value is 1. If not set, defaults to 3.
+ // +optional
+ // +kubebuilder:default=3
+ // +kubebuilder:validation:Minimum=1
+ StepSize *int32 `json:"stepSize,omitempty"`
}
// MultiKueueExternalFramework defines a framework that is not built-in.
diff --git a/apis/config/v1beta1/defaults.go b/apis/config/v1beta1/defaults.go
index f3c396404d3..3bf10df4d94 100644
--- a/apis/config/v1beta1/defaults.go
+++ b/apis/config/v1beta1/defaults.go
@@ -122,9 +122,11 @@ func SetDefaults_Configuration(cfg *Configuration) {
cfg.MultiKueue = cmp.Or(cfg.MultiKueue, &MultiKueue{})
cfg.MultiKueue.GCInterval = cmp.Or(cfg.MultiKueue.GCInterval, &metav1.Duration{Duration: DefaultMultiKueueGCInterval})
- cfg.MultiKueue.Origin = new(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
+ cfg.MultiKueue.Origin = ptr.To(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
cfg.MultiKueue.WorkerLostTimeout = cmp.Or(cfg.MultiKueue.WorkerLostTimeout, &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout})
- cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, new(MultiKueueDispatcherModeAllAtOnce))
+ cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, ptr.To(MultiKueueDispatcherModeAllAtOnce))
+ cfg.MultiKueue.IncrementalDispatcherConfig = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig, &IncrementalDispatcherConfig{})
+ cfg.MultiKueue.IncrementalDispatcherConfig.StepSize = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig.StepSize, ptr.To(int32(3)))
if fs := cfg.FairSharing; fs != nil && fs.Enable && len(fs.PreemptionStrategies) == 0 {
fs.PreemptionStrategies = []PreemptionStrategy{LessThanOrEqualToFinalShare, LessThanInitialShare}
diff --git a/apis/config/v1beta1/zz_generated.conversion.go b/apis/config/v1beta1/zz_generated.conversion.go
index b5b0ec7340f..2f7a1499096 100644
--- a/apis/config/v1beta1/zz_generated.conversion.go
+++ b/apis/config/v1beta1/zz_generated.conversion.go
@@ -130,6 +130,16 @@ func RegisterConversions(s *runtime.Scheme) error {
}); err != nil {
return err
}
+ if err := s.AddGeneratedConversionFunc((*IncrementalDispatcherConfig)(nil), (*v1beta2.IncrementalDispatcherConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta1_IncrementalDispatcherConfig_To_v1beta2_IncrementalDispatcherConfig(a.(*IncrementalDispatcherConfig), b.(*v1beta2.IncrementalDispatcherConfig), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*v1beta2.IncrementalDispatcherConfig)(nil), (*IncrementalDispatcherConfig)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta2_IncrementalDispatcherConfig_To_v1beta1_IncrementalDispatcherConfig(a.(*v1beta2.IncrementalDispatcherConfig), b.(*IncrementalDispatcherConfig), scope)
+ }); err != nil {
+ return err
+ }
if err := s.AddGeneratedConversionFunc((*v1beta2.Integrations)(nil), (*Integrations)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta2_Integrations_To_v1beta1_Integrations(a.(*v1beta2.Integrations), b.(*Integrations), scope)
}); err != nil {
@@ -638,6 +648,26 @@ func autoConvert_v1beta2_FairSharing_To_v1beta1_FairSharing(in *v1beta2.FairShar
return nil
}
+func autoConvert_v1beta1_IncrementalDispatcherConfig_To_v1beta2_IncrementalDispatcherConfig(in *IncrementalDispatcherConfig, out *v1beta2.IncrementalDispatcherConfig, s conversion.Scope) error {
+ out.StepSize = (*int32)(unsafe.Pointer(in.StepSize))
+ return nil
+}
+
+// Convert_v1beta1_IncrementalDispatcherConfig_To_v1beta2_IncrementalDispatcherConfig is an autogenerated conversion function.
+func Convert_v1beta1_IncrementalDispatcherConfig_To_v1beta2_IncrementalDispatcherConfig(in *IncrementalDispatcherConfig, out *v1beta2.IncrementalDispatcherConfig, s conversion.Scope) error {
+ return autoConvert_v1beta1_IncrementalDispatcherConfig_To_v1beta2_IncrementalDispatcherConfig(in, out, s)
+}
+
+func autoConvert_v1beta2_IncrementalDispatcherConfig_To_v1beta1_IncrementalDispatcherConfig(in *v1beta2.IncrementalDispatcherConfig, out *IncrementalDispatcherConfig, s conversion.Scope) error {
+ out.StepSize = (*int32)(unsafe.Pointer(in.StepSize))
+ return nil
+}
+
+// Convert_v1beta2_IncrementalDispatcherConfig_To_v1beta1_IncrementalDispatcherConfig is an autogenerated conversion function.
+func Convert_v1beta2_IncrementalDispatcherConfig_To_v1beta1_IncrementalDispatcherConfig(in *v1beta2.IncrementalDispatcherConfig, out *IncrementalDispatcherConfig, s conversion.Scope) error {
+ return autoConvert_v1beta2_IncrementalDispatcherConfig_To_v1beta1_IncrementalDispatcherConfig(in, out, s)
+}
+
func autoConvert_v1beta1_Integrations_To_v1beta2_Integrations(in *Integrations, out *v1beta2.Integrations, s conversion.Scope) error {
out.Frameworks = *(*[]string)(unsafe.Pointer(&in.Frameworks))
out.ExternalFrameworks = *(*[]string)(unsafe.Pointer(&in.ExternalFrameworks))
@@ -710,6 +740,7 @@ func autoConvert_v1beta1_MultiKueue_To_v1beta2_MultiKueue(in *MultiKueue, out *v
out.WorkerLostTimeout = (*metav1.Duration)(unsafe.Pointer(in.WorkerLostTimeout))
out.DispatcherName = (*string)(unsafe.Pointer(in.DispatcherName))
out.ExternalFrameworks = *(*[]v1beta2.MultiKueueExternalFramework)(unsafe.Pointer(&in.ExternalFrameworks))
+ out.IncrementalDispatcherConfig = (*v1beta2.IncrementalDispatcherConfig)(unsafe.Pointer(in.IncrementalDispatcherConfig))
return nil
}
@@ -725,6 +756,7 @@ func autoConvert_v1beta2_MultiKueue_To_v1beta1_MultiKueue(in *v1beta2.MultiKueue
out.DispatcherName = (*string)(unsafe.Pointer(in.DispatcherName))
out.ExternalFrameworks = *(*[]MultiKueueExternalFramework)(unsafe.Pointer(&in.ExternalFrameworks))
// WARNING: in.ClusterProfile requires manual conversion: does not exist in peer-type
+ out.IncrementalDispatcherConfig = (*IncrementalDispatcherConfig)(unsafe.Pointer(in.IncrementalDispatcherConfig))
return nil
}
diff --git a/apis/config/v1beta1/zz_generated.deepcopy.go b/apis/config/v1beta1/zz_generated.deepcopy.go
index 9e5a81bff2a..060a2d7cd46 100644
--- a/apis/config/v1beta1/zz_generated.deepcopy.go
+++ b/apis/config/v1beta1/zz_generated.deepcopy.go
@@ -359,6 +359,26 @@ func (in *FairSharing) DeepCopy() *FairSharing {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IncrementalDispatcherConfig) DeepCopyInto(out *IncrementalDispatcherConfig) {
+ *out = *in
+ if in.StepSize != nil {
+ in, out := &in.StepSize, &out.StepSize
+ *out = new(int32)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IncrementalDispatcherConfig.
+func (in *IncrementalDispatcherConfig) DeepCopy() *IncrementalDispatcherConfig {
+ if in == nil {
+ return nil
+ }
+ out := new(IncrementalDispatcherConfig)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Integrations) DeepCopyInto(out *Integrations) {
*out = *in
@@ -472,6 +492,11 @@ func (in *MultiKueue) DeepCopyInto(out *MultiKueue) {
*out = make([]MultiKueueExternalFramework, len(*in))
copy(*out, *in)
}
+ if in.IncrementalDispatcherConfig != nil {
+ in, out := &in.IncrementalDispatcherConfig, &out.IncrementalDispatcherConfig
+ *out = new(IncrementalDispatcherConfig)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiKueue.
diff --git a/apis/config/v1beta2/configuration_types.go b/apis/config/v1beta2/configuration_types.go
index ba47b8d2d3c..602b5ba3523 100644
--- a/apis/config/v1beta2/configuration_types.go
+++ b/apis/config/v1beta2/configuration_types.go
@@ -334,6 +334,23 @@ type MultiKueue struct {
// ClusterProfile defines configuration for using the ClusterProfile API.
// +optional
ClusterProfile *ClusterProfile `json:"clusterProfile,omitempty"`
+
+ // IncrementalDispatcherConfig contains the configuration for the incremental dispatcher.
+ // This field is only valid when DispatcherName is set to the incremental dispatcher.
+ // Note: This field is going to be ignored when the MultiKueueIncrementalDispatcherConfig feature gate is disabled.
+ // +optional
+ IncrementalDispatcherConfig *IncrementalDispatcherConfig `json:"incrementalDispatcherConfig,omitempty"`
+}
+
+// IncrementalDispatcherConfig holds configuration for the MultiKueue Incremental Dispatcher.
+type IncrementalDispatcherConfig struct {
+ // StepSize defines the number of worker clusters the Incremental Dispatcher
+ // will query simultaneously.
+ // Minimum value is 1. If not set, defaults to 3.
+ // +optional
+ // +kubebuilder:default=3
+ // +kubebuilder:validation:Minimum=1
+ StepSize *int32 `json:"stepSize,omitempty"`
}
// MultiKueueExternalFramework defines a framework that is not built-in.
diff --git a/apis/config/v1beta2/defaults.go b/apis/config/v1beta2/defaults.go
index 5423297dae7..df77cdc9926 100644
--- a/apis/config/v1beta2/defaults.go
+++ b/apis/config/v1beta2/defaults.go
@@ -120,9 +120,11 @@ func SetDefaults_Configuration(cfg *Configuration) {
cfg.MultiKueue = cmp.Or(cfg.MultiKueue, &MultiKueue{})
cfg.MultiKueue.GCInterval = cmp.Or(cfg.MultiKueue.GCInterval, &metav1.Duration{Duration: DefaultMultiKueueGCInterval})
- cfg.MultiKueue.Origin = new(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
+ cfg.MultiKueue.Origin = ptr.To(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
cfg.MultiKueue.WorkerLostTimeout = cmp.Or(cfg.MultiKueue.WorkerLostTimeout, &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout})
- cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, new(MultiKueueDispatcherModeAllAtOnce))
+ cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, ptr.To(MultiKueueDispatcherModeAllAtOnce))
+ cfg.MultiKueue.IncrementalDispatcherConfig = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig, &IncrementalDispatcherConfig{})
+ cfg.MultiKueue.IncrementalDispatcherConfig.StepSize = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig.StepSize, ptr.To(int32(3)))
if afs := cfg.AdmissionFairSharing; afs != nil {
afs.UsageSamplingInterval.Duration = cmp.Or(afs.UsageSamplingInterval.Duration, 5*time.Minute)
diff --git a/apis/config/v1beta2/zz_generated.deepcopy.go b/apis/config/v1beta2/zz_generated.deepcopy.go
index f84613522d6..93ee6125f99 100644
--- a/apis/config/v1beta2/zz_generated.deepcopy.go
+++ b/apis/config/v1beta2/zz_generated.deepcopy.go
@@ -382,6 +382,26 @@ func (in *FairSharing) DeepCopy() *FairSharing {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *IncrementalDispatcherConfig) DeepCopyInto(out *IncrementalDispatcherConfig) {
+ *out = *in
+ if in.StepSize != nil {
+ in, out := &in.StepSize, &out.StepSize
+ *out = new(int32)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IncrementalDispatcherConfig.
+func (in *IncrementalDispatcherConfig) DeepCopy() *IncrementalDispatcherConfig {
+ if in == nil {
+ return nil
+ }
+ out := new(IncrementalDispatcherConfig)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Integrations) DeepCopyInto(out *Integrations) {
*out = *in
@@ -495,6 +515,11 @@ func (in *MultiKueue) DeepCopyInto(out *MultiKueue) {
*out = new(ClusterProfile)
(*in).DeepCopyInto(*out)
}
+ if in.IncrementalDispatcherConfig != nil {
+ in, out := &in.IncrementalDispatcherConfig, &out.IncrementalDispatcherConfig
+ *out = new(IncrementalDispatcherConfig)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiKueue.
diff --git a/pkg/controller/workloaddispatcher/controllers.go b/pkg/controller/workloaddispatcher/controllers.go
index ac7c1e394e2..39f6550f616 100644
--- a/pkg/controller/workloaddispatcher/controllers.go
+++ b/pkg/controller/workloaddispatcher/controllers.go
@@ -34,7 +34,7 @@ func SetupControllers(mgr ctrl.Manager, cfg *configapi.Configuration, roleTracke
return "", err
}
- idRec := NewIncrementalDispatcherReconciler(mgr.GetClient(), helper, roleTracker)
+ idRec := NewIncrementalDispatcherReconciler(mgr.GetClient(), helper, roleTracker, cfg)
err = idRec.SetupWithManager(mgr, cfg)
if err != nil {
return "multikueue-incremental-dispatcher", err
diff --git a/pkg/controller/workloaddispatcher/incrementaldispatcher.go b/pkg/controller/workloaddispatcher/incrementaldispatcher.go
index 4719a02749b..0f4bf9b90e6 100644
--- a/pkg/controller/workloaddispatcher/incrementaldispatcher.go
+++ b/pkg/controller/workloaddispatcher/incrementaldispatcher.go
@@ -26,10 +26,12 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
+ utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/utils/clock"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
+ "sigs.k8s.io/kueue/pkg/features"
kueueconfig "sigs.k8s.io/kueue/apis/config/v1beta2"
kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
@@ -52,6 +54,7 @@ type IncrementalDispatcherReconciler struct {
clock clock.Clock
roundStartTimes *utilmaps.SyncMap[types.NamespacedName, time.Time]
roleTracker *roletracker.RoleTracker
+ cfg *kueueconfig.Configuration
}
var realClock = clock.RealClock{}
@@ -67,15 +70,17 @@ func (r *IncrementalDispatcherReconciler) SetupWithManager(mgr ctrl.Manager, cfg
Complete(core.WithLeadingManager(mgr, r, &kueue.Workload{}, cfg))
}
-func NewIncrementalDispatcherReconciler(c client.Client, helper *admissioncheck.MultiKueueStoreHelper, roleTracker *roletracker.RoleTracker) *IncrementalDispatcherReconciler {
+func NewIncrementalDispatcherReconciler(c client.Client, helper *admissioncheck.MultiKueueStoreHelper, roleTracker *roletracker.RoleTracker, cfg *kueueconfig.Configuration) *IncrementalDispatcherReconciler {
return &IncrementalDispatcherReconciler{
client: c,
helper: helper,
clock: realClock,
roundStartTimes: utilmaps.NewSyncMap[types.NamespacedName, time.Time](0),
roleTracker: roleTracker,
+ cfg: cfg,
}
}
+
func (r *IncrementalDispatcherReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := ctrl.LoggerFrom(ctx)
wl := &kueue.Workload{}
@@ -138,7 +143,7 @@ func (r *IncrementalDispatcherReconciler) nominateWorkers(ctx context.Context, w
return reconcile.Result{RequeueAfter: remainingWaitTime}, nil
}
- nextNominatedWorkers, err := getNextNominatedWorkers(log, wl, remoteClusters)
+ nextNominatedWorkers, err := getNextNominatedWorkers(log, wl, remoteClusters, r.stepSize())
log.V(5).Info("revoke outdated nomination and nominate new worker clusters", "revokedWorkerClusters", wl.Status.NominatedClusterNames, "nominatedWorkerClusters", nextNominatedWorkers)
if err != nil {
log.Error(err, "Failed to nominate next worker clusters")
@@ -161,7 +166,7 @@ func (r *IncrementalDispatcherReconciler) nominateWorkers(ctx context.Context, w
// getNextNominatedWorkers returns the next set of nominated workers for incremental dispatching.
// It nominates up to 3 remotes that have not yet been nominated, in sorted order.
-func getNextNominatedWorkers(log logr.Logger, wl *kueue.Workload, remoteClusters sets.Set[string]) ([]string, error) {
+func getNextNominatedWorkers(log logr.Logger, wl *kueue.Workload, remoteClusters sets.Set[string], batchSize int) ([]string, error) {
alreadyNominated := sets.New(wl.Status.NominatedClusterNames...)
workers := make([]string, 0, len(remoteClusters))
@@ -177,13 +182,28 @@ func getNextNominatedWorkers(log logr.Logger, wl *kueue.Workload, remoteClusters
if len(workers) == 0 {
return nil, ErrNoMoreWorkers
}
- batchSize := 3
if len(workers) < batchSize {
return workers, nil
}
return workers[:batchSize], nil
}
+// stepSize returns the configured batch size for the incremental dispatcher.
+// Falls back to the default of 3 if the feature gate is disabled or config is absent.
+func (r *IncrementalDispatcherReconciler) stepSize() int {
+ const defaultStepSize = 3
+ if !utilfeature.DefaultFeatureGate.Enabled(features.MultiKueueIncrementalDispatcherConfig) {
+ return defaultStepSize
+ }
+ if r.cfg != nil &&
+ r.cfg.MultiKueue != nil &&
+ r.cfg.MultiKueue.IncrementalDispatcherConfig != nil &&
+ r.cfg.MultiKueue.IncrementalDispatcherConfig.StepSize != nil {
+ return int(*r.cfg.MultiKueue.IncrementalDispatcherConfig.StepSize)
+ }
+ return defaultStepSize
+}
+
func (r *IncrementalDispatcherReconciler) setRoundStartTime(key types.NamespacedName, t time.Time) {
r.roundStartTimes.Add(key, t)
}
diff --git a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
index 0c92997731a..ce566a9a155 100644
--- a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
+++ b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
@@ -30,12 +30,15 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
testingclock "k8s.io/utils/clock/testing"
+ "k8s.io/utils/ptr"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
+ kueueconfig "sigs.k8s.io/kueue/apis/config/v1beta2"
kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
+ "sigs.k8s.io/kueue/pkg/features"
"sigs.k8s.io/kueue/pkg/util/admissioncheck"
utilmaps "sigs.k8s.io/kueue/pkg/util/maps"
utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
@@ -64,17 +67,17 @@ func TestIncrementalDispatcherReconciler_Reconcile(t *testing.T) {
workload: baseWorkload.Clone().DeletionTimestamp(now).Finalizers("kubernetes").Obj(),
},
"admission check nil": {
- workload: baseWorkload.DeepCopy(),
+ workload: baseWorkload.Clone().Obj(),
},
"admission check is rejected": {
- workload: baseWorkload.DeepCopy(),
+ workload: baseWorkload.Clone().Obj(),
mkAcState: &kueue.AdmissionCheckState{
Name: "ac1",
State: kueue.CheckStateRejected,
},
},
"admission check is ready": {
- workload: baseWorkload.DeepCopy(),
+ workload: baseWorkload.Clone().Obj(),
mkAcState: &kueue.AdmissionCheckState{
Name: "ac1",
State: kueue.CheckStateReady,
@@ -102,7 +105,7 @@ func TestIncrementalDispatcherReconciler_Reconcile(t *testing.T) {
},
},
"workload has quota reserved": {
- workload: baseWorkload.DeepCopy(),
+ workload: baseWorkload.Clone().Obj(),
mkAcState: &kueue.AdmissionCheckState{
Name: "ac1",
State: kueue.CheckStatePending,
@@ -180,14 +183,17 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
testCases := map[string]struct {
remoteClusters sets.Set[string]
workload *kueue.Workload
+ cfg *kueueconfig.Configuration
+ featureGateDisabled bool
wantNominatedClustersCount int
wantErr error
advanceRoundTime bool
wantNominatedClusters []string
}{
+ // ── original cases (unchanged) ────────────────────────────────────────
"one remote": {
remoteClusters: sets.New("A"),
- workload: baseWl.DeepCopy(),
+ workload: baseWl.Clone().Obj(),
wantNominatedClustersCount: 1,
wantErr: nil,
advanceRoundTime: false,
@@ -195,7 +201,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
},
"two remotes": {
remoteClusters: sets.New("A", "B"),
- workload: baseWl.DeepCopy(),
+ workload: baseWl.Clone().Obj(),
wantNominatedClustersCount: 2,
wantErr: nil,
advanceRoundTime: false,
@@ -203,7 +209,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
},
"three remotes": {
remoteClusters: sets.New("A", "B", "C"),
- workload: baseWl.DeepCopy(),
+ workload: baseWl.Clone().Obj(),
wantNominatedClustersCount: 3,
wantErr: nil,
advanceRoundTime: false,
@@ -211,7 +217,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
},
"fifteen remotes": {
remoteClusters: sets.New("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"),
- workload: baseWl.DeepCopy(),
+ workload: baseWl.Clone().Obj(),
wantNominatedClustersCount: 3,
wantErr: nil,
advanceRoundTime: false,
@@ -259,16 +265,78 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
},
"no remotes": {
remoteClusters: make(sets.Set[string]),
- workload: baseWl.DeepCopy(),
+ workload: baseWl.Clone().Obj(),
wantNominatedClustersCount: 0,
wantErr: ErrNoMoreWorkers,
advanceRoundTime: false,
wantNominatedClusters: []string{},
},
+
+ // ── new cases for stepSize / feature gate ─────────────────────────────
+
+ // stepSize=2: first call with 5 clusters should return exactly 2.
+ "stepSize=2, five remotes — first batch is exactly 2": {
+ remoteClusters: sets.New("A", "B", "C", "D", "E"),
+ workload: baseWl.Clone().Obj(),
+ cfg: &kueueconfig.Configuration{
+ MultiKueue: &kueueconfig.MultiKueue{
+ IncrementalDispatcherConfig: &kueueconfig.IncrementalDispatcherConfig{
+ StepSize: ptr.To(int32(2)),
+ },
+ },
+ },
+ wantNominatedClustersCount: 2,
+ wantErr: nil,
+ advanceRoundTime: false,
+ wantNominatedClusters: []string{"A", "B"},
+ },
+
+ // stepSize=2: after round expires the next 2 are appended.
+ "stepSize=2, round expired — second batch is next 2": {
+ remoteClusters: sets.New("A", "B", "C", "D", "E"),
+ workload: baseWl.Clone().NominatedClusterNames("A", "B").Obj(),
+ cfg: &kueueconfig.Configuration{
+ MultiKueue: &kueueconfig.MultiKueue{
+ IncrementalDispatcherConfig: &kueueconfig.IncrementalDispatcherConfig{
+ StepSize: ptr.To(int32(2)),
+ },
+ },
+ },
+ wantNominatedClustersCount: 4,
+ wantErr: nil,
+ advanceRoundTime: true,
+ wantNominatedClusters: []string{"A", "B", "C", "D"},
+ },
+
+ // Feature gate disabled: even with StepSize=10 set in config the
+ // dispatcher must fall back to the default of 3.
+ "feature gate disabled — ignores stepSize=10, uses default 3": {
+ remoteClusters: sets.New("A", "B", "C", "D", "E", "F", "G"),
+ workload: baseWl.Clone().Obj(),
+ cfg: &kueueconfig.Configuration{
+ MultiKueue: &kueueconfig.MultiKueue{
+ IncrementalDispatcherConfig: &kueueconfig.IncrementalDispatcherConfig{
+ StepSize: ptr.To(int32(10)),
+ },
+ },
+ },
+ featureGateDisabled: true,
+ wantNominatedClustersCount: 3,
+ wantErr: nil,
+ advanceRoundTime: false,
+ wantNominatedClusters: []string{"A", "B", "C"},
+ },
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
+ // Control feature gate per test case.
+ if tc.featureGateDisabled {
+ features.SetFeatureGateDuringTest(t, features.MultiKueueIncrementalDispatcherConfig, false)
+ } else {
+ features.SetFeatureGateDuringTest(t, features.MultiKueueIncrementalDispatcherConfig, true)
+ }
+
scheme := runtime.NewScheme()
if err := kueue.AddToScheme(scheme); err != nil {
t.Fatalf("Fail to add to scheme %s", err)
@@ -287,6 +355,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
client: client,
clock: fakeClock,
roundStartTimes: utilmaps.NewSyncMap[types.NamespacedName, time.Time](0),
+ cfg: tc.cfg,
}
key := types.NamespacedName{Namespace: tc.workload.Namespace, Name: tc.workload.Name}
diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go
index 14e76c2d089..4cf37510f81 100644
--- a/pkg/features/kube_features.go
+++ b/pkg/features/kube_features.go
@@ -380,6 +380,12 @@ const (
// deletes a Deployment-owned pod).
FinishOrphanedWorkloads featuregate.Feature = "FinishOrphanedWorkloads"
+ // owner: @Mostafahassen1
+ //
+ // kep: https://github.com/kubernetes-sigs/kueue/pull/10877#issuecomment-4412688735
+ // Enables configurable stepSize for the MultiKueue Incremental Dispatcher.
+ MultiKueueIncrementalDispatcherConfig featuregate.Feature = "MultiKueueIncrementalDispatcherConfig"
+
// owner: @pbundyra
// kep: https://github.com/kubernetes-sigs/kueue/tree/main/keps/8691-concurrent-admission
//
@@ -609,6 +615,9 @@ var defaultVersionedFeatureGates = map[featuregate.Feature]featuregate.Versioned
FinishOrphanedWorkloads: {
{Version: version.MustParse("0.18"), Default: false, PreRelease: featuregate.Alpha},
},
+ MultiKueueIncrementalDispatcherConfig: {
+ {Version: version.MustParse("0.19"), Default: false, PreRelease: featuregate.Alpha},
+ },
ConcurrentAdmission: {
{Version: version.MustParse("0.18"), Default: false, PreRelease: featuregate.Alpha},
},
diff --git a/site/content/en/docs/reference/kueue-config.v1beta1.md b/site/content/en/docs/reference/kueue-config.v1beta1.md
index 3c8d8abfce6..1441e2901af 100644
--- a/site/content/en/docs/reference/kueue-config.v1beta1.md
+++ b/site/content/en/docs/reference/kueue-config.v1beta1.md
@@ -669,6 +669,34 @@ The default strategy is ["LessThanOrEqualToFinalShare", "LessThan
+## `IncrementalDispatcherConfig` {#config-kueue-x-k8s-io-v1beta1-IncrementalDispatcherConfig}
+
+
+**Appears in:**
+
+- [MultiKueue](#config-kueue-x-k8s-io-v1beta1-MultiKueue)
+
+
+IncrementalDispatcherConfig holds configuration for the MultiKueue Incremental Dispatcher.
+
+
+
+| Field | Description |
+
+
+
+stepSize
+int32
+ |
+
+ StepSize defines the number of worker clusters the Incremental Dispatcher
+will query simultaneously.
+Minimum value is 1. If not set, defaults to 3.
+ |
+
+
+
+
## `Integrations` {#config-kueue-x-k8s-io-v1beta1-Integrations}
@@ -893,6 +921,15 @@ by the generic MultiKueue adapter. Each entry defines how to handle a specific
GroupVersionKind (GVK) for MultiKueue operations.
+incrementalDispatcherConfig
+IncrementalDispatcherConfig
+ |
+
+ IncrementalDispatcherConfig contains the configuration for the incremental dispatcher.
+This field is only valid when DispatcherName is set to the incremental dispatcher.
+Note: This field is going to be ignored when the MultiKueueIncrementalDispatcherConfig feature gate is disabled.
+ |
+
diff --git a/site/content/en/docs/reference/kueue-config.v1beta2.md b/site/content/en/docs/reference/kueue-config.v1beta2.md
index bfa0c0e4ebf..8fa3b24e38f 100644
--- a/site/content/en/docs/reference/kueue-config.v1beta2.md
+++ b/site/content/en/docs/reference/kueue-config.v1beta2.md
@@ -688,6 +688,34 @@ newest start time first.
+## `IncrementalDispatcherConfig` {#config-kueue-x-k8s-io-v1beta2-IncrementalDispatcherConfig}
+
+
+**Appears in:**
+
+- [MultiKueue](#config-kueue-x-k8s-io-v1beta2-MultiKueue)
+
+
+IncrementalDispatcherConfig holds configuration for the MultiKueue Incremental Dispatcher.
+
+
+
+| Field | Description |
+
+
+
+stepSize
+int32
+ |
+
+ StepSize defines the number of worker clusters the Incremental Dispatcher
+will query simultaneously.
+Minimum value is 1. If not set, defaults to 3.
+ |
+
+
+
+
## `Integrations` {#config-kueue-x-k8s-io-v1beta2-Integrations}
@@ -909,6 +937,15 @@ GroupVersionKind (GVK) for MultiKueue operations.
ClusterProfile defines configuration for using the ClusterProfile API.
+incrementalDispatcherConfig
+IncrementalDispatcherConfig
+ |
+
+ IncrementalDispatcherConfig contains the configuration for the incremental dispatcher.
+This field is only valid when DispatcherName is set to the incremental dispatcher.
+Note: This field is going to be ignored when the MultiKueueIncrementalDispatcherConfig feature gate is disabled.
+ |
+
diff --git a/site/data/featuregates/versioned_feature_list.yaml b/site/data/featuregates/versioned_feature_list.yaml
index c821ea7318c..11f6170553d 100644
--- a/site/data/featuregates/versioned_feature_list.yaml
+++ b/site/data/featuregates/versioned_feature_list.yaml
@@ -45,6 +45,10 @@
lockToDefault: true
preRelease: Deprecated
version: "0.18"
+ - default: false
+ lockToDefault: true
+ preRelease: Deprecated
+ version: "0.18"
- name: DynamicResourceAllocation
versionedSpecs:
- default: false
@@ -229,6 +233,12 @@
lockToDefault: false
preRelease: Alpha
version: "0.15"
+- name: MultiKueueIncrementalDispatcherConfig
+ versionedSpecs:
+ - default: false
+ lockToDefault: false
+ preRelease: Alpha
+ version: "0.18"
- name: MultiKueueManagerQuotaAutomation
versionedSpecs:
- default: false
@@ -443,6 +453,44 @@
lockToDefault: false
preRelease: Beta
version: "0.14"
+- name: TASRespectNodeAffinityPreferred
+ versionedSpecs:
+ - default: false
+ lockToDefault: false
+ preRelease: Alpha
+ version: "0.18"
+ - default: false
+ lockToDefault: true
+ preRelease: Deprecated
+ version: "0.18"
+- name: KueueDRAIntegration
+ versionedSpecs:
+ - default: true
+ lockToDefault: false
+ preRelease: Beta
+ version: "0.18"
+- name: KueueDRAIntegrationExtendedResource
+ versionedSpecs:
+ - default: false
+ lockToDefault: false
+ preRelease: Alpha
+ version: "0.18"
+- name: MultiKueueManagerQuotaAutomation
+ versionedSpecs:
+ - default: false
+ lockToDefault: false
+ preRelease: Alpha
+ version: "0.18"
+- name: MultiKueueIncrementalDispatcherConfig
+ versionedSpecs:
+ - default: false
+ lockToDefault: false
+ preRelease: Alpha
+ version: "0.19"
+ - default: true
+ lockToDefault: false
+ preRelease: Beta
+ version: "0.18"
- name: TASRespectNodeAffinityPreferred
versionedSpecs:
- default: false
diff --git a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
index c821ea7318c..25c0211b986 100644
--- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
+++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
@@ -235,6 +235,12 @@
lockToDefault: false
preRelease: Alpha
version: "0.18"
+- name: MultiKueueIncrementalDispatcherConfig
+ versionedSpecs:
+ - default: false
+ lockToDefault: false
+ preRelease: Alpha
+ version: "0.19"
- name: MultiKueueOrchestratedPreemption
versionedSpecs:
- default: false
@@ -359,10 +365,6 @@
lockToDefault: false
preRelease: Beta
version: "0.17"
- - default: true
- lockToDefault: false
- preRelease: Beta
- version: "0.18"
- name: ShortWorkloadNames
versionedSpecs:
- default: false
@@ -443,12 +445,6 @@
lockToDefault: false
preRelease: Beta
version: "0.14"
-- name: TASRespectNodeAffinityPreferred
- versionedSpecs:
- - default: false
- lockToDefault: false
- preRelease: Alpha
- version: "0.18"
- name: TLSOptions
versionedSpecs:
- default: true
From 1329f3bfe40250e9c3d0b72685c7e1829c56e29b Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 16:41:33 +0300
Subject: [PATCH 02/13] fix : unit test
---
apis/config/v1beta1/defaults_test.go | 12 ++++++++++++
apis/config/v1beta2/defaults_test.go | 12 ++++++++++++
pkg/config/config_test.go | 21 +++++++++++++++++++++
3 files changed, 45 insertions(+)
diff --git a/apis/config/v1beta1/defaults_test.go b/apis/config/v1beta1/defaults_test.go
index 7a91f5d5224..4fe1a2a760c 100644
--- a/apis/config/v1beta1/defaults_test.go
+++ b/apis/config/v1beta1/defaults_test.go
@@ -96,6 +96,9 @@ func TestSetDefaults_Configuration(t *testing.T) {
Origin: new(DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout},
DispatcherName: new(MultiKueueDispatcherModeAllAtOnce),
+ IncrementalDispatcherConfig: &IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
}
podsReadyTimeout := metav1.Duration{Duration: defaultPodsReadyTimeout}
@@ -512,6 +515,9 @@ func TestSetDefaults_Configuration(t *testing.T) {
Origin: new("multikueue-manager1"),
WorkerLostTimeout: &metav1.Duration{Duration: time.Minute},
DispatcherName: new(MultiKueueDispatcherModeIncremental),
+ IncrementalDispatcherConfig: &IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: defaultManagedJobsNamespaceSelector,
WaitForPodsReady: &WaitForPodsReady{},
@@ -542,6 +548,9 @@ func TestSetDefaults_Configuration(t *testing.T) {
Origin: new(DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: time.Minute},
DispatcherName: defaultMultiKueue.DispatcherName,
+ IncrementalDispatcherConfig: &IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: defaultManagedJobsNamespaceSelector,
WaitForPodsReady: &WaitForPodsReady{},
@@ -570,6 +579,9 @@ func TestSetDefaults_Configuration(t *testing.T) {
Origin: new("multikueue-manager1"),
WorkerLostTimeout: &metav1.Duration{Duration: 15 * time.Minute},
DispatcherName: defaultMultiKueue.DispatcherName,
+ IncrementalDispatcherConfig: &IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: defaultManagedJobsNamespaceSelector,
WaitForPodsReady: &WaitForPodsReady{},
diff --git a/apis/config/v1beta2/defaults_test.go b/apis/config/v1beta2/defaults_test.go
index 79147d1f738..f5e76036404 100644
--- a/apis/config/v1beta2/defaults_test.go
+++ b/apis/config/v1beta2/defaults_test.go
@@ -96,6 +96,9 @@ func TestSetDefaults_Configuration(t *testing.T) {
Origin: new(DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout},
DispatcherName: new(MultiKueueDispatcherModeAllAtOnce),
+ IncrementalDispatcherConfig: &IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
}
defaultVisibilityServer := &VisibilityServerConfiguration{
@@ -554,6 +557,9 @@ func TestSetDefaults_Configuration(t *testing.T) {
Origin: new("multikueue-manager1"),
WorkerLostTimeout: &metav1.Duration{Duration: time.Minute},
DispatcherName: new(MultiKueueDispatcherModeIncremental),
+ IncrementalDispatcherConfig: &IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: defaultManagedJobsNamespaceSelector,
VisibilityServer: defaultVisibilityServer,
@@ -584,6 +590,9 @@ func TestSetDefaults_Configuration(t *testing.T) {
Origin: new(DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: time.Minute},
DispatcherName: defaultMultiKueue.DispatcherName,
+ IncrementalDispatcherConfig: &IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: defaultManagedJobsNamespaceSelector,
VisibilityServer: defaultVisibilityServer,
@@ -612,6 +621,9 @@ func TestSetDefaults_Configuration(t *testing.T) {
Origin: new("multikueue-manager1"),
WorkerLostTimeout: &metav1.Duration{Duration: 15 * time.Minute},
DispatcherName: defaultMultiKueue.DispatcherName,
+ IncrementalDispatcherConfig: &IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: defaultManagedJobsNamespaceSelector,
VisibilityServer: defaultVisibilityServer,
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index 976228e95e9..04a9656e585 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -416,6 +416,9 @@ objectRetentionPolicies:
Origin: ptr.To(configapi.DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: configapi.DefaultMultiKueueWorkerLostTimeout},
DispatcherName: ptr.To(configapi.MultiKueueDispatcherModeAllAtOnce),
+ IncrementalDispatcherConfig: &configapi.IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
}
defaultVisibility := &configapi.VisibilityServerConfiguration{
@@ -749,6 +752,9 @@ objectRetentionPolicies:
Origin: new("multikueue-manager1"),
WorkerLostTimeout: &metav1.Duration{Duration: 10 * time.Minute},
DispatcherName: ptr.To(configapi.MultiKueueDispatcherModeIncremental),
+ IncrementalDispatcherConfig: &configapi.IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
ClusterProfile: &configapi.ClusterProfile{
CredentialsProviders: []configapi.ClusterProfileCredentialsProvider{
{
@@ -948,6 +954,9 @@ webhook:
Origin: ptr.To(configapi.DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: configapi.DefaultMultiKueueWorkerLostTimeout},
DispatcherName: ptr.To(configapi.MultiKueueDispatcherModeAllAtOnce),
+ IncrementalDispatcherConfig: &configapi.IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
@@ -998,6 +1007,9 @@ webhook:
Origin: ptr.To(configapi.DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: configapi.DefaultMultiKueueWorkerLostTimeout},
DispatcherName: ptr.To(configapi.MultiKueueDispatcherModeAllAtOnce),
+ IncrementalDispatcherConfig: &configapi.IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
@@ -1048,6 +1060,9 @@ webhook:
Origin: ptr.To(configapi.DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: configapi.DefaultMultiKueueWorkerLostTimeout},
DispatcherName: ptr.To(configapi.MultiKueueDispatcherModeAllAtOnce),
+ IncrementalDispatcherConfig: &configapi.IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
@@ -1094,6 +1109,9 @@ webhook:
Origin: ptr.To(configapi.DefaultMultiKueueOrigin),
WorkerLostTimeout: &metav1.Duration{Duration: configapi.DefaultMultiKueueWorkerLostTimeout},
DispatcherName: ptr.To(configapi.MultiKueueDispatcherModeAllAtOnce),
+ IncrementalDispatcherConfig: &configapi.IncrementalDispatcherConfig{
+ StepSize: ptr.To[int32](3),
+ },
},
ManagedJobsNamespaceSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
@@ -1245,6 +1263,9 @@ func TestEncode(t *testing.T) {
"origin": "multikueue",
"workerLostTimeout": "15m0s",
"dispatcherName": configapi.MultiKueueDispatcherModeAllAtOnce,
+ "incrementalDispatcherConfig": map[string]any{
+ "stepSize": int64(3),
+ },
},
"visibilityServer": map[string]any{
"bindPort": int64(8082),
From 385d7dd9b70cf3eb8c557c8461436f8d15df9752 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 18:22:24 +0300
Subject: [PATCH 03/13] fix : format
---
.../incrementaldispatcher.go | 4 ----
.../incrementaldispatcher_test.go | 23 +++++++------------
2 files changed, 8 insertions(+), 19 deletions(-)
diff --git a/pkg/controller/workloaddispatcher/incrementaldispatcher.go b/pkg/controller/workloaddispatcher/incrementaldispatcher.go
index 0f4bf9b90e6..70206d3f13f 100644
--- a/pkg/controller/workloaddispatcher/incrementaldispatcher.go
+++ b/pkg/controller/workloaddispatcher/incrementaldispatcher.go
@@ -164,8 +164,6 @@ func (r *IncrementalDispatcherReconciler) nominateWorkers(ctx context.Context, w
return reconcile.Result{}, nil
}
-// getNextNominatedWorkers returns the next set of nominated workers for incremental dispatching.
-// It nominates up to 3 remotes that have not yet been nominated, in sorted order.
func getNextNominatedWorkers(log logr.Logger, wl *kueue.Workload, remoteClusters sets.Set[string], batchSize int) ([]string, error) {
alreadyNominated := sets.New(wl.Status.NominatedClusterNames...)
@@ -188,8 +186,6 @@ func getNextNominatedWorkers(log logr.Logger, wl *kueue.Workload, remoteClusters
return workers[:batchSize], nil
}
-// stepSize returns the configured batch size for the incremental dispatcher.
-// Falls back to the default of 3 if the feature gate is disabled or config is absent.
func (r *IncrementalDispatcherReconciler) stepSize() int {
const defaultStepSize = 3
if !utilfeature.DefaultFeatureGate.Enabled(features.MultiKueueIncrementalDispatcherConfig) {
diff --git a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
index ce566a9a155..29684f45554 100644
--- a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
+++ b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
@@ -190,10 +190,10 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
advanceRoundTime bool
wantNominatedClusters []string
}{
- // ── original cases (unchanged) ────────────────────────────────────────
+
"one remote": {
remoteClusters: sets.New("A"),
- workload: baseWl.Clone().Obj(),
+ workload: baseWl.DeepCopy(),
wantNominatedClustersCount: 1,
wantErr: nil,
advanceRoundTime: false,
@@ -201,7 +201,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
},
"two remotes": {
remoteClusters: sets.New("A", "B"),
- workload: baseWl.Clone().Obj(),
+ workload: baseWl.DeepCopy(),
wantNominatedClustersCount: 2,
wantErr: nil,
advanceRoundTime: false,
@@ -209,7 +209,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
},
"three remotes": {
remoteClusters: sets.New("A", "B", "C"),
- workload: baseWl.Clone().Obj(),
+ workload: baseWl.DeepCopy(),
wantNominatedClustersCount: 3,
wantErr: nil,
advanceRoundTime: false,
@@ -217,7 +217,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
},
"fifteen remotes": {
remoteClusters: sets.New("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O"),
- workload: baseWl.Clone().Obj(),
+ workload: baseWl.DeepCopy(),
wantNominatedClustersCount: 3,
wantErr: nil,
advanceRoundTime: false,
@@ -265,19 +265,16 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
},
"no remotes": {
remoteClusters: make(sets.Set[string]),
- workload: baseWl.Clone().Obj(),
+ workload: baseWl.DeepCopy(),
wantNominatedClustersCount: 0,
wantErr: ErrNoMoreWorkers,
advanceRoundTime: false,
wantNominatedClusters: []string{},
},
- // ── new cases for stepSize / feature gate ─────────────────────────────
-
- // stepSize=2: first call with 5 clusters should return exactly 2.
"stepSize=2, five remotes — first batch is exactly 2": {
remoteClusters: sets.New("A", "B", "C", "D", "E"),
- workload: baseWl.Clone().Obj(),
+ workload: baseWl.DeepCopy(),
cfg: &kueueconfig.Configuration{
MultiKueue: &kueueconfig.MultiKueue{
IncrementalDispatcherConfig: &kueueconfig.IncrementalDispatcherConfig{
@@ -291,7 +288,6 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
wantNominatedClusters: []string{"A", "B"},
},
- // stepSize=2: after round expires the next 2 are appended.
"stepSize=2, round expired — second batch is next 2": {
remoteClusters: sets.New("A", "B", "C", "D", "E"),
workload: baseWl.Clone().NominatedClusterNames("A", "B").Obj(),
@@ -308,11 +304,9 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
wantNominatedClusters: []string{"A", "B", "C", "D"},
},
- // Feature gate disabled: even with StepSize=10 set in config the
- // dispatcher must fall back to the default of 3.
"feature gate disabled — ignores stepSize=10, uses default 3": {
remoteClusters: sets.New("A", "B", "C", "D", "E", "F", "G"),
- workload: baseWl.Clone().Obj(),
+ workload: baseWl.DeepCopy(),
cfg: &kueueconfig.Configuration{
MultiKueue: &kueueconfig.MultiKueue{
IncrementalDispatcherConfig: &kueueconfig.IncrementalDispatcherConfig{
@@ -330,7 +324,6 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
- // Control feature gate per test case.
if tc.featureGateDisabled {
features.SetFeatureGateDuringTest(t, features.MultiKueueIncrementalDispatcherConfig, false)
} else {
From 1716b18cd997e53c4fbaf4fe493e9ec53674b55e Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 18:24:56 +0300
Subject: [PATCH 04/13] fix : format
---
.../workloaddispatcher/incrementaldispatcher_test.go | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
index 29684f45554..882276d963b 100644
--- a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
+++ b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
@@ -67,17 +67,17 @@ func TestIncrementalDispatcherReconciler_Reconcile(t *testing.T) {
workload: baseWorkload.Clone().DeletionTimestamp(now).Finalizers("kubernetes").Obj(),
},
"admission check nil": {
- workload: baseWorkload.Clone().Obj(),
+ workload: baseWorkload.DeepCopy(),
},
"admission check is rejected": {
- workload: baseWorkload.Clone().Obj(),
+ workload: baseWorkload.DeepCopy(),
mkAcState: &kueue.AdmissionCheckState{
Name: "ac1",
State: kueue.CheckStateRejected,
},
},
"admission check is ready": {
- workload: baseWorkload.Clone().Obj(),
+ workload: baseWorkload.DeepCopy(),
mkAcState: &kueue.AdmissionCheckState{
Name: "ac1",
State: kueue.CheckStateReady,
@@ -105,7 +105,7 @@ func TestIncrementalDispatcherReconciler_Reconcile(t *testing.T) {
},
},
"workload has quota reserved": {
- workload: baseWorkload.Clone().Obj(),
+ workload: baseWorkload.DeepCopy(),
mkAcState: &kueue.AdmissionCheckState{
Name: "ac1",
State: kueue.CheckStatePending,
From 35aa908d07e3c3b66ccc0eda49cef52853011496 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 18:54:21 +0300
Subject: [PATCH 05/13] fix : format
---
apis/config/v1beta1/defaults.go | 2 +-
apis/config/v1beta2/defaults.go | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/apis/config/v1beta1/defaults.go b/apis/config/v1beta1/defaults.go
index 3bf10df4d94..232132c0e84 100644
--- a/apis/config/v1beta1/defaults.go
+++ b/apis/config/v1beta1/defaults.go
@@ -122,7 +122,7 @@ func SetDefaults_Configuration(cfg *Configuration) {
cfg.MultiKueue = cmp.Or(cfg.MultiKueue, &MultiKueue{})
cfg.MultiKueue.GCInterval = cmp.Or(cfg.MultiKueue.GCInterval, &metav1.Duration{Duration: DefaultMultiKueueGCInterval})
- cfg.MultiKueue.Origin = ptr.To(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
+ cfg.MultiKueue.Origin = new(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
cfg.MultiKueue.WorkerLostTimeout = cmp.Or(cfg.MultiKueue.WorkerLostTimeout, &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout})
cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, ptr.To(MultiKueueDispatcherModeAllAtOnce))
cfg.MultiKueue.IncrementalDispatcherConfig = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig, &IncrementalDispatcherConfig{})
diff --git a/apis/config/v1beta2/defaults.go b/apis/config/v1beta2/defaults.go
index df77cdc9926..97b5e1ce78d 100644
--- a/apis/config/v1beta2/defaults.go
+++ b/apis/config/v1beta2/defaults.go
@@ -120,7 +120,7 @@ func SetDefaults_Configuration(cfg *Configuration) {
cfg.MultiKueue = cmp.Or(cfg.MultiKueue, &MultiKueue{})
cfg.MultiKueue.GCInterval = cmp.Or(cfg.MultiKueue.GCInterval, &metav1.Duration{Duration: DefaultMultiKueueGCInterval})
- cfg.MultiKueue.Origin = ptr.To(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
+ cfg.MultiKueue.Origin = new(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
cfg.MultiKueue.WorkerLostTimeout = cmp.Or(cfg.MultiKueue.WorkerLostTimeout, &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout})
cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, ptr.To(MultiKueueDispatcherModeAllAtOnce))
cfg.MultiKueue.IncrementalDispatcherConfig = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig, &IncrementalDispatcherConfig{})
From 88b7ebbc3cd4cef406f82379ce2fc030d5c6f596 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 19:28:27 +0300
Subject: [PATCH 06/13] fix : the new and ptr.to
---
apis/config/v1beta1/defaults.go | 4 ++--
apis/config/v1beta2/defaults.go | 2 +-
.../workloaddispatcher/incrementaldispatcher_test.go | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/apis/config/v1beta1/defaults.go b/apis/config/v1beta1/defaults.go
index 232132c0e84..89dfbdb96f3 100644
--- a/apis/config/v1beta1/defaults.go
+++ b/apis/config/v1beta1/defaults.go
@@ -124,9 +124,9 @@ func SetDefaults_Configuration(cfg *Configuration) {
cfg.MultiKueue.GCInterval = cmp.Or(cfg.MultiKueue.GCInterval, &metav1.Duration{Duration: DefaultMultiKueueGCInterval})
cfg.MultiKueue.Origin = new(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
cfg.MultiKueue.WorkerLostTimeout = cmp.Or(cfg.MultiKueue.WorkerLostTimeout, &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout})
- cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, ptr.To(MultiKueueDispatcherModeAllAtOnce))
+ cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, new(MultiKueueDispatcherModeAllAtOnce))
cfg.MultiKueue.IncrementalDispatcherConfig = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig, &IncrementalDispatcherConfig{})
- cfg.MultiKueue.IncrementalDispatcherConfig.StepSize = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig.StepSize, ptr.To(int32(3)))
+ cfg.MultiKueue.IncrementalDispatcherConfig.StepSize = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig.StepSize, ptr.To[int32](3))
if fs := cfg.FairSharing; fs != nil && fs.Enable && len(fs.PreemptionStrategies) == 0 {
fs.PreemptionStrategies = []PreemptionStrategy{LessThanOrEqualToFinalShare, LessThanInitialShare}
diff --git a/apis/config/v1beta2/defaults.go b/apis/config/v1beta2/defaults.go
index 97b5e1ce78d..35424944b8b 100644
--- a/apis/config/v1beta2/defaults.go
+++ b/apis/config/v1beta2/defaults.go
@@ -122,7 +122,7 @@ func SetDefaults_Configuration(cfg *Configuration) {
cfg.MultiKueue.GCInterval = cmp.Or(cfg.MultiKueue.GCInterval, &metav1.Duration{Duration: DefaultMultiKueueGCInterval})
cfg.MultiKueue.Origin = new(cmp.Or(ptr.Deref(cfg.MultiKueue.Origin, ""), DefaultMultiKueueOrigin))
cfg.MultiKueue.WorkerLostTimeout = cmp.Or(cfg.MultiKueue.WorkerLostTimeout, &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout})
- cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, ptr.To(MultiKueueDispatcherModeAllAtOnce))
+ cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, new(MultiKueueDispatcherModeAllAtOnce))
cfg.MultiKueue.IncrementalDispatcherConfig = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig, &IncrementalDispatcherConfig{})
cfg.MultiKueue.IncrementalDispatcherConfig.StepSize = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig.StepSize, ptr.To(int32(3)))
diff --git a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
index 882276d963b..b6e1c32dfd5 100644
--- a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
+++ b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
@@ -278,7 +278,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
cfg: &kueueconfig.Configuration{
MultiKueue: &kueueconfig.MultiKueue{
IncrementalDispatcherConfig: &kueueconfig.IncrementalDispatcherConfig{
- StepSize: ptr.To(int32(2)),
+ StepSize: ptr.To[int32](2),
},
},
},
@@ -310,7 +310,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
cfg: &kueueconfig.Configuration{
MultiKueue: &kueueconfig.MultiKueue{
IncrementalDispatcherConfig: &kueueconfig.IncrementalDispatcherConfig{
- StepSize: ptr.To(int32(10)),
+ StepSize: ptr.To[int32](10),
},
},
},
From 4a36436e5aeb7bcc61144966b8ada10a75755b58 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 19:58:07 +0300
Subject: [PATCH 07/13] fix : the new and ptr.to
---
apis/config/v1beta2/defaults.go | 2 +-
pkg/controller/workloaddispatcher/incrementaldispatcher_test.go | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/apis/config/v1beta2/defaults.go b/apis/config/v1beta2/defaults.go
index 35424944b8b..f32a3d72f72 100644
--- a/apis/config/v1beta2/defaults.go
+++ b/apis/config/v1beta2/defaults.go
@@ -124,7 +124,7 @@ func SetDefaults_Configuration(cfg *Configuration) {
cfg.MultiKueue.WorkerLostTimeout = cmp.Or(cfg.MultiKueue.WorkerLostTimeout, &metav1.Duration{Duration: DefaultMultiKueueWorkerLostTimeout})
cfg.MultiKueue.DispatcherName = cmp.Or(cfg.MultiKueue.DispatcherName, new(MultiKueueDispatcherModeAllAtOnce))
cfg.MultiKueue.IncrementalDispatcherConfig = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig, &IncrementalDispatcherConfig{})
- cfg.MultiKueue.IncrementalDispatcherConfig.StepSize = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig.StepSize, ptr.To(int32(3)))
+ cfg.MultiKueue.IncrementalDispatcherConfig.StepSize = cmp.Or(cfg.MultiKueue.IncrementalDispatcherConfig.StepSize, ptr.To[int32](3))
if afs := cfg.AdmissionFairSharing; afs != nil {
afs.UsageSamplingInterval.Duration = cmp.Or(afs.UsageSamplingInterval.Duration, 5*time.Minute)
diff --git a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
index b6e1c32dfd5..13c57dba39f 100644
--- a/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
+++ b/pkg/controller/workloaddispatcher/incrementaldispatcher_test.go
@@ -294,7 +294,7 @@ func TestIncrementalDispatcherNominateWorkers(t *testing.T) {
cfg: &kueueconfig.Configuration{
MultiKueue: &kueueconfig.MultiKueue{
IncrementalDispatcherConfig: &kueueconfig.IncrementalDispatcherConfig{
- StepSize: ptr.To(int32(2)),
+ StepSize: ptr.To[int32](2),
},
},
},
From 654be42e86f440eee2a2f10185a2c070028b8f06 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 20:53:43 +0300
Subject: [PATCH 08/13] fix : the format
---
.../workloaddispatcher/incrementaldispatcher.go | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/pkg/controller/workloaddispatcher/incrementaldispatcher.go b/pkg/controller/workloaddispatcher/incrementaldispatcher.go
index 70206d3f13f..60ed7c63f3f 100644
--- a/pkg/controller/workloaddispatcher/incrementaldispatcher.go
+++ b/pkg/controller/workloaddispatcher/incrementaldispatcher.go
@@ -31,11 +31,11 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
- "sigs.k8s.io/kueue/pkg/features"
kueueconfig "sigs.k8s.io/kueue/apis/config/v1beta2"
kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
"sigs.k8s.io/kueue/pkg/controller/core"
+ "sigs.k8s.io/kueue/pkg/features"
"sigs.k8s.io/kueue/pkg/util/admissioncheck"
utilmaps "sigs.k8s.io/kueue/pkg/util/maps"
"sigs.k8s.io/kueue/pkg/util/roletracker"
@@ -70,7 +70,12 @@ func (r *IncrementalDispatcherReconciler) SetupWithManager(mgr ctrl.Manager, cfg
Complete(core.WithLeadingManager(mgr, r, &kueue.Workload{}, cfg))
}
-func NewIncrementalDispatcherReconciler(c client.Client, helper *admissioncheck.MultiKueueStoreHelper, roleTracker *roletracker.RoleTracker, cfg *kueueconfig.Configuration) *IncrementalDispatcherReconciler {
+func NewIncrementalDispatcherReconciler(
+ c client.Client,
+ helper *admissioncheck.MultiKueueStoreHelper,
+ roleTracker *roletracker.RoleTracker,
+ cfg *kueueconfig.Configuration,
+) *IncrementalDispatcherReconciler {
return &IncrementalDispatcherReconciler{
client: c,
helper: helper,
From 582578bfbe52e15952b222cc7624375598aed5f3 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Fri, 15 May 2026 18:22:24 +0300
Subject: [PATCH 09/13] fix : the versioned_feature_list
---
site/data/featuregates/versioned_feature_list.yaml | 4 ----
1 file changed, 4 deletions(-)
diff --git a/site/data/featuregates/versioned_feature_list.yaml b/site/data/featuregates/versioned_feature_list.yaml
index 11f6170553d..4c211300d53 100644
--- a/site/data/featuregates/versioned_feature_list.yaml
+++ b/site/data/featuregates/versioned_feature_list.yaml
@@ -483,10 +483,6 @@
version: "0.18"
- name: MultiKueueIncrementalDispatcherConfig
versionedSpecs:
- - default: false
- lockToDefault: false
- preRelease: Alpha
- version: "0.19"
- default: true
lockToDefault: false
preRelease: Beta
From 98cd03c022d9767eeb8ff8b084c93f61e38e254b Mon Sep 17 00:00:00 2001
From: mostafa
Date: Thu, 21 May 2026 00:33:27 +0300
Subject: [PATCH 10/13] fix : the versioned_feature_list
---
.../featuregates/versioned_feature_list.yaml | 34 -------------------
.../reference/versioned_feature_list.yaml | 6 ++++
2 files changed, 6 insertions(+), 34 deletions(-)
diff --git a/site/data/featuregates/versioned_feature_list.yaml b/site/data/featuregates/versioned_feature_list.yaml
index 4c211300d53..9454192af1d 100644
--- a/site/data/featuregates/versioned_feature_list.yaml
+++ b/site/data/featuregates/versioned_feature_list.yaml
@@ -453,40 +453,6 @@
lockToDefault: false
preRelease: Beta
version: "0.14"
-- name: TASRespectNodeAffinityPreferred
- versionedSpecs:
- - default: false
- lockToDefault: false
- preRelease: Alpha
- version: "0.18"
- - default: false
- lockToDefault: true
- preRelease: Deprecated
- version: "0.18"
-- name: KueueDRAIntegration
- versionedSpecs:
- - default: true
- lockToDefault: false
- preRelease: Beta
- version: "0.18"
-- name: KueueDRAIntegrationExtendedResource
- versionedSpecs:
- - default: false
- lockToDefault: false
- preRelease: Alpha
- version: "0.18"
-- name: MultiKueueManagerQuotaAutomation
- versionedSpecs:
- - default: false
- lockToDefault: false
- preRelease: Alpha
- version: "0.18"
-- name: MultiKueueIncrementalDispatcherConfig
- versionedSpecs:
- - default: true
- lockToDefault: false
- preRelease: Beta
- version: "0.18"
- name: TASRespectNodeAffinityPreferred
versionedSpecs:
- default: false
diff --git a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
index 25c0211b986..17f6e363169 100644
--- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
+++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
@@ -445,6 +445,12 @@
lockToDefault: false
preRelease: Beta
version: "0.14"
+- name: TASRespectNodeAffinityPreferred
+ versionedSpecs:
+ - default: false
+ lockToDefault: false
+ preRelease: Alpha
+ version: "0.18"
- name: TLSOptions
versionedSpecs:
- default: true
From 06762dc5dca36b6a25c6346db38ed54dacce2f65 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Thu, 21 May 2026 00:38:54 +0300
Subject: [PATCH 11/13] fix : the versioned_feature_list
---
site/data/featuregates/versioned_feature_list.yaml | 4 ----
.../reference/versioned_feature_list.yaml | 4 ++++
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/site/data/featuregates/versioned_feature_list.yaml b/site/data/featuregates/versioned_feature_list.yaml
index 9454192af1d..bfacca1f788 100644
--- a/site/data/featuregates/versioned_feature_list.yaml
+++ b/site/data/featuregates/versioned_feature_list.yaml
@@ -45,10 +45,6 @@
lockToDefault: true
preRelease: Deprecated
version: "0.18"
- - default: false
- lockToDefault: true
- preRelease: Deprecated
- version: "0.18"
- name: DynamicResourceAllocation
versionedSpecs:
- default: false
diff --git a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
index 17f6e363169..d190caa709d 100644
--- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
+++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
@@ -365,6 +365,10 @@
lockToDefault: false
preRelease: Beta
version: "0.17"
+ - default: true
+ lockToDefault: false
+ preRelease: Beta
+ version: "0.18"
- name: ShortWorkloadNames
versionedSpecs:
- default: false
From f46e9633cf9374eaaca279dbc291ff1d7ce50b65 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Thu, 21 May 2026 00:39:52 +0300
Subject: [PATCH 12/13] fix : the versioned_feature_list
---
.../reference/versioned_feature_list.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
index d190caa709d..1098ce1f8cd 100644
--- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
+++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
@@ -240,7 +240,7 @@
- default: false
lockToDefault: false
preRelease: Alpha
- version: "0.19"
+ version: "0.18"
- name: MultiKueueOrchestratedPreemption
versionedSpecs:
- default: false
From 55c24c44cfe0c29efe066f0b959216d59f179374 Mon Sep 17 00:00:00 2001
From: mostafa
Date: Thu, 21 May 2026 00:43:13 +0300
Subject: [PATCH 13/13] fix : the versioned_feature_list
---
site/data/featuregates/versioned_feature_list.yaml | 2 +-
.../reference/versioned_feature_list.yaml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/site/data/featuregates/versioned_feature_list.yaml b/site/data/featuregates/versioned_feature_list.yaml
index bfacca1f788..ac22f4b3a87 100644
--- a/site/data/featuregates/versioned_feature_list.yaml
+++ b/site/data/featuregates/versioned_feature_list.yaml
@@ -234,7 +234,7 @@
- default: false
lockToDefault: false
preRelease: Alpha
- version: "0.18"
+ version: "0.19"
- name: MultiKueueManagerQuotaAutomation
versionedSpecs:
- default: false
diff --git a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
index 1098ce1f8cd..d190caa709d 100644
--- a/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
+++ b/test/compatibility_lifecycle/reference/versioned_feature_list.yaml
@@ -240,7 +240,7 @@
- default: false
lockToDefault: false
preRelease: Alpha
- version: "0.18"
+ version: "0.19"
- name: MultiKueueOrchestratedPreemption
versionedSpecs:
- default: false