Skip to content

Commit 0725d9e

Browse files
committed
add daemonset and deployment hooks for per node volume limit
Since NodeChecker now checks max attachment limit value it is now safe to add hooks for reflecting maxAllowedBlockVolumesPerNode field of clusterCSIDriver into deployment and daemonset as env variable.
1 parent 3566264 commit 0725d9e

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

pkg/operator/vspherecontroller/driver_starter.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2833
func (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

Comments
 (0)