@@ -4,13 +4,16 @@ import (
44 "context"
55 "crypto/sha256"
66 "fmt"
7+ "github.com/openshift/api/features"
78 "os"
9+ "strconv"
810
911 "github.com/openshift/library-go/pkg/operator/resource/resourcehash"
1012 "github.com/openshift/vmware-vsphere-csi-driver-operator/pkg/operator/utils"
1113
1214 operatorapi "github.com/openshift/api/operator/v1"
1315 "github.com/openshift/library-go/pkg/controller/factory"
16+ "github.com/openshift/library-go/pkg/operator/configobserver/featuregates"
1417 "github.com/openshift/library-go/pkg/operator/csi/csicontrollerset"
1518 "github.com/openshift/library-go/pkg/operator/csi/csidrivercontrollerservicecontroller"
1619 "github.com/openshift/library-go/pkg/operator/csi/csidrivernodeservicecontroller"
@@ -23,6 +26,8 @@ import (
2326 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2427 corev1informers "k8s.io/client-go/informers/core/v1"
2528 "k8s.io/klog/v2"
29+
30+ operatorlistersv1 "github.com/openshift/client-go/operator/listers/operator/v1"
2631)
2732
2833func (c * VSphereController ) createCSIDriver () {
@@ -135,6 +140,7 @@ func (c *VSphereController) createCSIDriver() {
135140 c .apiClients .SecretInformer ,
136141 ),
137142 csidrivercontrollerservicecontroller .WithReplicasHook (c .apiClients .ConfigInformers ),
143+ WithMaxVolumesPerNodeDeploymentHook (c .apiClients .ClusterCSIDriverInformer .Lister (), c .featureGates ),
138144 ).WithCSIDriverNodeService (
139145 "VMwareVSphereDriverNodeServiceController" ,
140146 assets .ReadFile ,
@@ -150,6 +156,7 @@ func (c *VSphereController) createCSIDriver() {
150156 c .apiClients .ConfigMapInformer ,
151157 ),
152158 WithSecretDaemonSetAnnotationHook (driverConfigSecretName , defaultNamespace , c .apiClients .SecretInformer ),
159+ WithMaxVolumesPerNodeDaemonSetHook (c .apiClients .ClusterCSIDriverInformer .Lister (), c .featureGates ),
153160 ).WithServiceMonitorController (
154161 "VMWareVSphereDriverServiceMonitorController" ,
155162 c .apiClients .DynamicClient ,
@@ -324,3 +331,71 @@ func getOperatorSyncState(operatorClient v1helpers.OperatorClientWithFinalizers)
324331 }
325332 return opSpec .ManagementState
326333}
334+
335+ // setMaxVolumesPerNodeEnvVar sets the MAX_VOLUMES_PER_NODE environment variable
336+ // in container specifications based on ClusterCSIDriver configuration.
337+ func setMaxVolumesPerNodeEnvVar (containers []v1.Container , clusterCSIDriverLister operatorlistersv1.ClusterCSIDriverLister , featureGate featuregates.FeatureGate ) ([]v1.Container , error ) {
338+ // Get ClusterCSIDriver object
339+ clusterCSIDriver , err := clusterCSIDriverLister .Get (utils .VSphereDriverName )
340+ if err != nil {
341+ return nil , fmt .Errorf ("failed to get ClusterCSIDriver: %v" , err )
342+ }
343+
344+ // Get the maximum volume limit
345+ maxVolumesPerNode := utils .GetMaxVolumesPerNode (clusterCSIDriver )
346+
347+ // Set the environment variable in all containers
348+ for i := range containers {
349+ container := & containers [i ]
350+
351+ // Find and update existing MAX_VOLUMES_PER_NODE env var if it exists
352+ envVarFound := false
353+ for j := range container .Env {
354+ if container .Env [j ].Name == "MAX_VOLUMES_PER_NODE" {
355+ container .Env [j ].Value = strconv .FormatInt (int64 (maxVolumesPerNode ), 10 )
356+ envVarFound = true
357+ break
358+ }
359+ }
360+
361+ // If not found, append it
362+ if ! envVarFound {
363+ container .Env = append (container .Env , v1.EnvVar {
364+ Name : "MAX_VOLUMES_PER_NODE" ,
365+ Value : strconv .FormatInt (int64 (maxVolumesPerNode ), 10 ),
366+ })
367+ }
368+ }
369+
370+ return containers , nil
371+ }
372+
373+ // WithMaxVolumesPerNodeDaemonSetHook sets the MAX_VOLUMES_PER_NODE environment variable in the DaemonSet container specifications.
374+ func WithMaxVolumesPerNodeDaemonSetHook (clusterCSIDriverLister operatorlistersv1.ClusterCSIDriverLister , featureGate featuregates.FeatureGate ) csidrivernodeservicecontroller.DaemonSetHookFunc {
375+ return func (opSpec * operatorapi.OperatorSpec , ds * appsv1.DaemonSet ) error {
376+ if ! featureGate .Enabled (features .FeatureGateVSphereConfigurableMaxAllowedBlockVolumesPerNode ) {
377+ return nil
378+ }
379+ containers , err := setMaxVolumesPerNodeEnvVar (ds .Spec .Template .Spec .Containers , clusterCSIDriverLister , featureGate )
380+ if err != nil {
381+ return err
382+ }
383+ ds .Spec .Template .Spec .Containers = containers
384+ return nil
385+ }
386+ }
387+
388+ // WithMaxVolumesPerNodeDeploymentHook sets the MAX_VOLUMES_PER_NODE environment variable in the Deployment container specifications.
389+ func WithMaxVolumesPerNodeDeploymentHook (clusterCSIDriverLister operatorlistersv1.ClusterCSIDriverLister , featureGate featuregates.FeatureGate ) deploymentcontroller.DeploymentHookFunc {
390+ return func (opSpec * operatorapi.OperatorSpec , deployment * appsv1.Deployment ) error {
391+ if ! featureGate .Enabled (features .FeatureGateVSphereConfigurableMaxAllowedBlockVolumesPerNode ) {
392+ return nil
393+ }
394+ containers , err := setMaxVolumesPerNodeEnvVar (deployment .Spec .Template .Spec .Containers , clusterCSIDriverLister , featureGate )
395+ if err != nil {
396+ return err
397+ }
398+ deployment .Spec .Template .Spec .Containers = containers
399+ return nil
400+ }
401+ }
0 commit comments