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.

+ + + + + + + + + + + +
FieldDescription
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.

+ + + + + + + + + + + +
FieldDescription
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