From e1a97a780d8eefdabdfbcc95ea91054acf95729b Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 2 Mar 2026 11:43:56 -0500 Subject: [PATCH] Update scheduler to check PreventPodSchedulingIfMissing --- .../framework/plugins/nodevolumelimits/csi.go | 8 +- .../plugins/nodevolumelimits/csi_test.go | 90 ++++++++++++------- 2 files changed, 67 insertions(+), 31 deletions(-) diff --git a/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go b/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go index 9bb7843eb8c..a61398b23c1 100644 --- a/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go +++ b/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go @@ -355,7 +355,7 @@ func (pl *CSILimits) Filter(ctx context.Context, _ fwk.CycleState, pod *v1.Pod, func (pl *CSILimits) checkCSIDriverOnNode(pluginName string, csiNode *storagev1.CSINode) (bool, error) { // the registered driver must be a CSI driver to enforce this limit, if we can't find the driver, // we assume the driver may not be a CSI driver and allow the pod to be scheduled. - _, err := pl.csiDriverLister.Get(pluginName) + csiDriver, err := pl.csiDriverLister.Get(pluginName) if err != nil { if apierrors.IsNotFound(err) { return true, nil @@ -363,6 +363,12 @@ func (pl *CSILimits) checkCSIDriverOnNode(pluginName string, csiNode *storagev1. return false, fmt.Errorf("error getting CSIDriver for provider %s: %w", pluginName, err) } + driverOptin := csiDriver.Spec.PreventPodSchedulingIfMissing + + if driverOptin == nil || !*driverOptin { + return true, nil + } + if csiNode == nil { return false, nil } diff --git a/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go b/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go index dd0a9eb6c21..5ba3cd6c63a 100644 --- a/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go +++ b/pkg/scheduler/framework/plugins/nodevolumelimits/csi_test.go @@ -1275,49 +1275,76 @@ func getFakeCSIDriverLister(driverNames ...string) fakeCSIDriverLister { return list } +func getFakeCSIDriverListerWithPreventPodSchedulingIfMissing(driverNames ...string) fakeCSIDriverLister { + var list fakeCSIDriverLister + for _, name := range driverNames { + list = append(list, storagev1.CSIDriver{ + ObjectMeta: metav1.ObjectMeta{Name: name}, + Spec: storagev1.CSIDriverSpec{ + PreventPodSchedulingIfMissing: ptr.To(true), + }, + }) + } + return list +} + func TestVolumeLimitScalingGate(t *testing.T) { // Pod uses a PVC that resolves to the EBS CSI driver via PV newPod := st.MakePod().PVC("csi-ebs.csi.aws.com-0").Obj() cases := []struct { - name string - enableVolumeLimitScaling bool - limitSource string - limit int32 - csiDriverPresent bool - wantStatus *fwk.Status + name string + enableVolumeLimitScaling bool + limitSource string + limit int32 + csiDriverPresent bool + preventPodSchedulingIfMissing bool + wantStatus *fwk.Status }{ { - name: "gate enabled - fail when driver not installed and CSIDriver exists", - enableVolumeLimitScaling: true, - limitSource: "no-csi-driver", - limit: 0, - csiDriverPresent: true, - wantStatus: fwk.NewStatus(fwk.Unschedulable, fmt.Sprintf("%s CSI driver is not installed on the node", ebsCSIDriverName)), + name: "gate enabled - allow scheduling when CSIDriver exists but PreventPodSchedulingIfMissing is not set", + enableVolumeLimitScaling: true, + limitSource: "no-csi-driver", + limit: 0, + csiDriverPresent: true, + preventPodSchedulingIfMissing: false, + wantStatus: nil, }, { - name: "gate disabled - skip driver presence check (regardless of CSIDriver presence)", - enableVolumeLimitScaling: false, - limitSource: "no-csi-driver", - limit: 0, - csiDriverPresent: true, - wantStatus: nil, + name: "gate enabled - fail when driver not installed and PreventPodSchedulingIfMissing is true", + enableVolumeLimitScaling: true, + limitSource: "no-csi-driver", + limit: 0, + csiDriverPresent: true, + preventPodSchedulingIfMissing: true, + wantStatus: fwk.NewStatus(fwk.Unschedulable, fmt.Sprintf("%s CSI driver is not installed on the node", ebsCSIDriverName)), }, { - name: "gate enabled - driver installed within limit", - enableVolumeLimitScaling: true, - limitSource: "csinode", - limit: 2, - csiDriverPresent: true, - wantStatus: nil, + name: "gate disabled - skip driver presence check (regardless of CSIDriver presence)", + enableVolumeLimitScaling: false, + limitSource: "no-csi-driver", + limit: 0, + csiDriverPresent: true, + preventPodSchedulingIfMissing: true, + wantStatus: nil, }, { - name: "gate enabled - allow scheduling when CSIDriver object missing", - enableVolumeLimitScaling: true, - limitSource: "no-csi-driver", - limit: 0, - csiDriverPresent: false, - wantStatus: nil, + name: "gate enabled - driver installed within limit", + enableVolumeLimitScaling: true, + limitSource: "csinode", + limit: 2, + csiDriverPresent: true, + preventPodSchedulingIfMissing: true, + wantStatus: nil, + }, + { + name: "gate enabled - allow scheduling when CSIDriver object missing", + enableVolumeLimitScaling: true, + limitSource: "no-csi-driver", + limit: 0, + csiDriverPresent: false, + preventPodSchedulingIfMissing: false, + wantStatus: nil, }, } @@ -1334,6 +1361,9 @@ func TestVolumeLimitScalingGate(t *testing.T) { vaLister: getFakeVolumeAttachmentLister(0, ebsCSIDriverName), csiDriverLister: func() fakeCSIDriverLister { if tt.csiDriverPresent { + if tt.preventPodSchedulingIfMissing { + return getFakeCSIDriverListerWithPreventPodSchedulingIfMissing(ebsCSIDriverName) + } return getFakeCSIDriverLister(ebsCSIDriverName) } return getFakeCSIDriverLister()