Skip to content

Commit f9c67dd

Browse files
Pass DRA driver feature gates via FEATURE_GATES env
Signed-off-by: Karthik Vetrivel <kvetrivel@nvidia.com>
1 parent 3be3986 commit f9c67dd

9 files changed

Lines changed: 137 additions & 0 deletions

File tree

api/nvidia/v1/clusterpolicy_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,16 @@ type DRADriverSpec struct {
10151015
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:io.kubernetes:Secret"
10161016
ImagePullSecrets []string `json:"imagePullSecrets,omitempty"`
10171017

1018+
// FeatureGates is a map of NVIDIA DRA Driver feature gate names to bool values,
1019+
// passed to the controller and both kubelet-plugin containers as the
1020+
// FEATURE_GATES environment variable. See the k8s-dra-driver-gpu project for
1021+
// the list of supported gate names.
1022+
// +kubebuilder:validation:Optional
1023+
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true
1024+
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="Feature Gates"
1025+
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:com.tectonic.ui:advanced"
1026+
FeatureGates map[string]bool `json:"featureGates,omitempty"`
1027+
10181028
// GPUs defines configuration for GPUs in the NVIDIA DRA Driver
10191029
GPUs DRADriverGPUs `json:"gpus,omitempty"`
10201030

api/nvidia/v1/zz_generated.deepcopy.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bundle/manifests/nvidia.com_clusterpolicies.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,15 @@ spec:
10661066
type: object
10671067
type: object
10681068
type: object
1069+
featureGates:
1070+
additionalProperties:
1071+
type: boolean
1072+
description: |-
1073+
FeatureGates is a map of NVIDIA DRA Driver feature gate names to bool values,
1074+
passed to the controller and both kubelet-plugin containers as the
1075+
FEATURE_GATES environment variable. See the k8s-dra-driver-gpu project for
1076+
the list of supported gate names.
1077+
type: object
10691078
gpus:
10701079
description: GPUs defines configuration for GPUs in the NVIDIA
10711080
DRA Driver

config/crd/bases/nvidia.com_clusterpolicies.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,15 @@ spec:
10661066
type: object
10671067
type: object
10681068
type: object
1069+
featureGates:
1070+
additionalProperties:
1071+
type: boolean
1072+
description: |-
1073+
FeatureGates is a map of NVIDIA DRA Driver feature gate names to bool values,
1074+
passed to the controller and both kubelet-plugin containers as the
1075+
FEATURE_GATES environment variable. See the k8s-dra-driver-gpu project for
1076+
the list of supported gate names.
1077+
type: object
10691078
gpus:
10701079
description: GPUs defines configuration for GPUs in the NVIDIA
10711080
DRA Driver

controllers/object_controls.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,8 @@ func TransformDRADriverKubeletPlugin(obj *appsv1.DaemonSet, config *gpuv1.Cluste
19171917
}
19181918
}
19191919

1920+
applyDRAFeatureGates(&obj.Spec.Template.Spec.Containers[i], config.DRADriver.FeatureGates)
1921+
19201922
containers = append(containers, obj.Spec.Template.Spec.Containers[i])
19211923
}
19221924
obj.Spec.Template.Spec.Containers = containers
@@ -1953,6 +1955,27 @@ func transformDRADriverRoot(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySp
19531955
}
19541956
}
19551957

1958+
// applyDRAFeatureGates renders gates as the FEATURE_GATES env var on the
1959+
// container. Format matches the upstream k8s-dra-driver-gpu Helm chart
1960+
// (comma-separated Key=Value with trailing comma); keys are sorted so the
1961+
// rendered string is a pure function of the input map and reconciles don't
1962+
// churn the pod spec. No-op when empty.
1963+
func applyDRAFeatureGates(container *corev1.Container, gates map[string]bool) {
1964+
if len(gates) == 0 {
1965+
return
1966+
}
1967+
names := make([]string, 0, len(gates))
1968+
for name := range gates {
1969+
names = append(names, name)
1970+
}
1971+
sort.Strings(names)
1972+
var value strings.Builder
1973+
for _, name := range names {
1974+
fmt.Fprintf(&value, "%s=%t,", name, gates[name])
1975+
}
1976+
setContainerEnv(container, "FEATURE_GATES", value.String())
1977+
}
1978+
19561979
// TransformDCGMExporter transforms dcgm exporter daemonset with required config as per ClusterPolicy
19571980
func TransformDCGMExporter(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicySpec, n ClusterPolicyController) error {
19581981
// update validation container
@@ -4368,6 +4391,8 @@ func TransformDRADriverController(obj *appsv1.Deployment, spec *gpuv1.ClusterPol
43684391
}
43694392
}
43704393

4394+
applyDRAFeatureGates(computeDomainsCtr, config.FeatureGates)
4395+
43714396
if config.ComputeDomains.Controller.Resources != nil {
43724397
computeDomainsCtr.Resources.Requests = config.ComputeDomains.Controller.Resources.Requests
43734398
computeDomainsCtr.Resources.Limits = config.ComputeDomains.Controller.Resources.Limits

controllers/transforms_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5161,3 +5161,64 @@ func TestTransformDRADriverController(t *testing.T) {
51615161
})
51625162
}
51635163
}
5164+
5165+
func TestApplyDRAFeatureGates(t *testing.T) {
5166+
testCases := []struct {
5167+
description string
5168+
gates map[string]bool
5169+
initialEnv []corev1.EnvVar
5170+
expectedEnv []corev1.EnvVar
5171+
}{
5172+
{
5173+
description: "empty map is a no-op",
5174+
gates: map[string]bool{},
5175+
initialEnv: []corev1.EnvVar{{Name: "KEEP_ME", Value: "yes"}},
5176+
expectedEnv: []corev1.EnvVar{{Name: "KEEP_ME", Value: "yes"}},
5177+
},
5178+
{
5179+
description: "nil map is a no-op",
5180+
gates: nil,
5181+
initialEnv: []corev1.EnvVar{{Name: "KEEP_ME", Value: "yes"}},
5182+
expectedEnv: []corev1.EnvVar{{Name: "KEEP_ME", Value: "yes"}},
5183+
},
5184+
{
5185+
description: "single gate renders Key=true with trailing comma",
5186+
gates: map[string]bool{"NVMLDeviceHealthCheck": true},
5187+
expectedEnv: []corev1.EnvVar{{Name: "FEATURE_GATES", Value: "NVMLDeviceHealthCheck=true,"}},
5188+
},
5189+
{
5190+
description: "multiple gates render in alphabetical order",
5191+
gates: map[string]bool{"DynamicMIG": false, "NVMLDeviceHealthCheck": true, "MPSSupport": true},
5192+
expectedEnv: []corev1.EnvVar{{Name: "FEATURE_GATES", Value: "DynamicMIG=false,MPSSupport=true,NVMLDeviceHealthCheck=true,"}},
5193+
},
5194+
{
5195+
description: "overwrites existing FEATURE_GATES entry without duplicating",
5196+
gates: map[string]bool{"DynamicMIG": true},
5197+
initialEnv: []corev1.EnvVar{
5198+
{Name: "FEATURE_GATES", Value: "stale=true,"},
5199+
{Name: "OTHER", Value: "preserved"},
5200+
},
5201+
expectedEnv: []corev1.EnvVar{
5202+
{Name: "FEATURE_GATES", Value: "DynamicMIG=true,"},
5203+
{Name: "OTHER", Value: "preserved"},
5204+
},
5205+
},
5206+
{
5207+
description: "appends FEATURE_GATES when not present, preserves siblings",
5208+
gates: map[string]bool{"DynamicMIG": true},
5209+
initialEnv: []corev1.EnvVar{{Name: "OTHER", Value: "preserved"}},
5210+
expectedEnv: []corev1.EnvVar{
5211+
{Name: "OTHER", Value: "preserved"},
5212+
{Name: "FEATURE_GATES", Value: "DynamicMIG=true,"},
5213+
},
5214+
},
5215+
}
5216+
5217+
for _, tc := range testCases {
5218+
t.Run(tc.description, func(t *testing.T) {
5219+
c := &corev1.Container{Env: tc.initialEnv}
5220+
applyDRAFeatureGates(c, tc.gates)
5221+
assert.Equal(t, tc.expectedEnv, c.Env)
5222+
})
5223+
}
5224+
}

deployments/gpu-operator/crds/nvidia.com_clusterpolicies.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,15 @@ spec:
10661066
type: object
10671067
type: object
10681068
type: object
1069+
featureGates:
1070+
additionalProperties:
1071+
type: boolean
1072+
description: |-
1073+
FeatureGates is a map of NVIDIA DRA Driver feature gate names to bool values,
1074+
passed to the controller and both kubelet-plugin containers as the
1075+
FEATURE_GATES environment variable. See the k8s-dra-driver-gpu project for
1076+
the list of supported gate names.
1077+
type: object
10691078
gpus:
10701079
description: GPUs defines configuration for GPUs in the NVIDIA
10711080
DRA Driver

deployments/gpu-operator/templates/clusterpolicy.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,9 @@ spec:
534534
{{- if .Values.draDriver.imagePullSecrets }}
535535
imagePullSecrets: {{ toYaml .Values.draDriver.imagePullSecrets | nindent 6 }}
536536
{{- end }}
537+
{{- if .Values.draDriver.featureGates }}
538+
featureGates: {{ toYaml .Values.draDriver.featureGates | nindent 6 }}
539+
{{- end }}
537540
gpus:
538541
enabled: {{ .Values.draDriver.gpus.enabled }}
539542
kubeletPlugin:

deployments/gpu-operator/values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@ draDriver:
287287
imagePullPolicy: IfNotPresent
288288
imagePullSecrets: []
289289

290+
# Feature gates passed to all DRA driver containers as the FEATURE_GATES env var.
291+
# Names defined in https://github.com/NVIDIA/k8s-dra-driver-gpu/blob/main/pkg/featuregates/featuregates.go
292+
featureGates: {}
293+
290294
gpus:
291295
enabled: false
292296
kubeletPlugin:

0 commit comments

Comments
 (0)