Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/nvidia/v1/clusterpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,12 @@ type DriverRepoConfigSpec struct {
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="ConfigMap Name"
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:com.tectonic.ui:text"
ConfigMapName string `json:"configMapName,omitempty"`

// UseHostSubscription mounts the host RHEL subscription configuration with this custom repo configuration.
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="Use Host RHEL Subscription"
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
UseHostSubscription bool `json:"useHostSubscription,omitempty"`
}

// DriverCertConfigSpec defines custom certificates configuration for NVIDIA Driver container
Expand Down
6 changes: 6 additions & 0 deletions api/nvidia/v1alpha1/nvidiadriver_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,12 @@ type DriverRepoConfigSpec struct {
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="ConfigMap Name"
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:com.tectonic.ui:text"
Name string `json:"name,omitempty"`

// UseHostSubscription mounts the host RHEL subscription configuration with this custom repo configuration.
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.displayName="Use Host RHEL Subscription"
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors.x-descriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
UseHostSubscription bool `json:"useHostSubscription,omitempty"`
}

// DriverLicensingConfigSpec defines licensing server configuration for NVIDIA Driver container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,11 @@ spec:
path: imagePullPolicy
x-descriptors:
- 'urn:alm:descriptor:com.tectonic.ui:imagePullPolicy'
- displayName: Use Host RHEL Subscription
description: Mount the host RHEL subscription configuration with this custom repo configuration.
path: repoConfig.useHostSubscription
x-descriptors:
- 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch'
- displayName: UseOpenKernelModules
description: 'Enable use of open GPU kernel modules'
path: useOpenKernelModules
Expand Down Expand Up @@ -488,6 +493,11 @@ spec:
path: driver.imagePullPolicy
x-descriptors:
- 'urn:alm:descriptor:com.tectonic.ui:imagePullPolicy'
- displayName: Use Host RHEL Subscription
description: Mount the host RHEL subscription configuration with this custom repo configuration.
path: driver.repoConfig.useHostSubscription
x-descriptors:
- 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch'
- displayName: UseOpenKernelModules
description: 'Enable use of open GPU kernel modules'
path: driver.useOpenKernelModules
Expand Down
4 changes: 4 additions & 0 deletions bundle/manifests/nvidia.com_clusterpolicies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,10 @@ spec:
properties:
configMapName:
type: string
useHostSubscription:
description: UseHostSubscription mounts the host RHEL subscription
configuration with this custom repo configuration.
type: boolean
type: object
repository:
description: NVIDIA Driver image repository
Expand Down
4 changes: 4 additions & 0 deletions bundle/manifests/nvidia.com_nvidiadrivers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,10 @@ spec:
properties:
name:
type: string
useHostSubscription:
description: UseHostSubscription mounts the host RHEL subscription
configuration with this custom repo configuration.
type: boolean
type: object
repository:
description: NVIDIA Driver repository
Expand Down
4 changes: 4 additions & 0 deletions config/crd/bases/nvidia.com_clusterpolicies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,10 @@ spec:
properties:
configMapName:
type: string
useHostSubscription:
description: UseHostSubscription mounts the host RHEL subscription
configuration with this custom repo configuration.
type: boolean
type: object
repository:
description: NVIDIA Driver image repository
Expand Down
4 changes: 4 additions & 0 deletions config/crd/bases/nvidia.com_nvidiadrivers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,10 @@ spec:
properties:
name:
type: string
useHostSubscription:
description: UseHostSubscription mounts the host RHEL subscription
configuration with this custom repo configuration.
type: boolean
type: object
repository:
description: NVIDIA Driver repository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ spec:
path: driver.imagePullPolicy
x-descriptors:
- 'urn:alm:descriptor:com.tectonic.ui:imagePullPolicy'
- displayName: Use Host RHEL Subscription
description: Mount the host RHEL subscription configuration with this custom repo configuration.
path: driver.repoConfig.useHostSubscription
x-descriptors:
- 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch'
- description: Group Feature Discovery Plugin config
displayName: Group Feature Discovery Plugin config
path: gfd
Expand Down
81 changes: 76 additions & 5 deletions controllers/object_controls.go
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"path"
"path/filepath"
"regexp"
"slices"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -3720,12 +3721,15 @@ func transformDriverContainer(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicy
if err != nil {
return fmt.Errorf("ERROR: failed to create ConfigMap VolumeMounts for custom repo config: %v", err)
}
removeConfigMapVolumeAndMounts(podSpec, config.Driver.RepoConfig.ConfigMapName)
driverContainer.VolumeMounts = append(driverContainer.VolumeMounts, volumeMounts...)
podSpec.Volumes = append(podSpec.Volumes, createConfigMapVolume(config.Driver.RepoConfig.ConfigMapName, itemsToInclude))
}

// set any custom ssl key/certificate configuration provided
if config.Driver.CertConfig != nil && config.Driver.CertConfig.Name != "" {
sharedRepoConfig := config.Driver.RepoConfig != nil &&
config.Driver.RepoConfig.ConfigMapName == config.Driver.CertConfig.Name
destinationDir, err := n.getCertConfigPath()
if err != nil {
return fmt.Errorf("ERROR: failed to get destination directory for custom cert config: %v", err)
Expand All @@ -3734,8 +3738,13 @@ func transformDriverContainer(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicy
if err != nil {
return fmt.Errorf("ERROR: failed to create ConfigMap VolumeMounts for custom certs: %w", err)
}
if !sharedRepoConfig {
removeConfigMapVolumeAndMounts(podSpec, config.Driver.CertConfig.Name)
}
driverContainer.VolumeMounts = append(driverContainer.VolumeMounts, volumeMounts...)
podSpec.Volumes = append(podSpec.Volumes, createConfigMapVolume(config.Driver.CertConfig.Name, itemsToInclude))
if !sharedRepoConfig {
podSpec.Volumes = append(podSpec.Volumes, createConfigMapVolume(config.Driver.CertConfig.Name, itemsToInclude))
}
}

secretName := config.Driver.SecretEnv
Expand All @@ -3749,8 +3758,9 @@ func transformDriverContainer(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicy
// set up subscription entitlements for RHEL(using K8s with a non-CRIO runtime) and SLES
if (osID == "rhel" && n.openshift == "" && n.runtime != gpuv1.CRIO) || osID == "sles" || osID == "sl-micro" {
pathToVolumeSource := MountPathToVolumeSource{}
if config.Driver.RepoConfig != nil && config.Driver.RepoConfig.ConfigMapName != "" && osID == "rhel" {
n.logger.Info("Skipping host subscription mounts because repoConfig is enabled", "OS", osID)
if config.Driver.RepoConfig != nil && config.Driver.RepoConfig.ConfigMapName != "" &&
!config.Driver.RepoConfig.UseHostSubscription && osID == "rhel" {
Comment thread
coderabbitai[bot] marked this conversation as resolved.
n.logger.Info("Skipping host subscription mounts because repoConfig is enabled and useHostSubscription is false", "OS", osID)
} else {
n.logger.Info("Mounting subscriptions into the driver container", "OS", osID)
pathToVolumeSource, err = n.getSubscriptionPathsToVolumeSources()
Expand All @@ -3766,8 +3776,15 @@ func transformDriverContainer(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicy
}
sort.Strings(mountPaths)

for num, mountPath := range mountPaths {
volMountSubscriptionName := fmt.Sprintf("subscription-config-%d", num)
removeSubscriptionMountsAndVolumes(driverContainer, podSpec)

usedVolumeNames := make(map[string]struct{}, len(podSpec.Volumes)+len(mountPaths))
for _, volume := range podSpec.Volumes {
usedVolumeNames[volume.Name] = struct{}{}
}
volumeIndex := 0
for _, mountPath := range mountPaths {
volMountSubscriptionName := nextSubscriptionVolumeName(usedVolumeNames, &volumeIndex)

volMountSubscription := corev1.VolumeMount{
Name: volMountSubscriptionName,
Expand Down Expand Up @@ -3795,6 +3812,60 @@ func transformDriverContainer(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicy
return nil
}

// removeConfigMapVolumeAndMounts removes an operator-managed ConfigMap volume and its mounts before rebuilding it.
func removeConfigMapVolumeAndMounts(podSpec *corev1.PodSpec, configMapName string) {
configMapVolumeNames := map[string]struct{}{}
podSpec.Volumes = slices.DeleteFunc(podSpec.Volumes, func(volume corev1.Volume) bool {
if volume.Name != configMapName || volume.ConfigMap == nil || volume.ConfigMap.Name != configMapName {
return false
}
configMapVolumeNames[volume.Name] = struct{}{}
return true
})
for containerIndex := range podSpec.Containers {
podSpec.Containers[containerIndex].VolumeMounts = slices.DeleteFunc(podSpec.Containers[containerIndex].VolumeMounts, func(volumeMount corev1.VolumeMount) bool {
_, found := configMapVolumeNames[volumeMount.Name]
return found
})
}
}

// nextSubscriptionVolumeName returns an unused subscription volume name and records it as used.
func nextSubscriptionVolumeName(usedVolumeNames map[string]struct{}, volumeIndex *int) string {
for {
volumeName := fmt.Sprintf("%s%d", consts.SubscriptionVolumeNamePrefix, *volumeIndex)
*volumeIndex += 1
if _, found := usedVolumeNames[volumeName]; found {
continue
}
usedVolumeNames[volumeName] = struct{}{}
return volumeName
}
}

// removeSubscriptionMountsAndVolumes removes host subscription volumes and their mounts before rebuilding them.
// It removes only volumes with the subscription prefix that are backed by hostPath, then removes only
// mounts that reference those volumes. ConfigMap-backed volumes with the same prefix are preserved.
func removeSubscriptionMountsAndVolumes(driverContainer *corev1.Container, podSpec *corev1.PodSpec) {
subscriptionVolumeNames := map[string]struct{}{}
podSpec.Volumes = slices.DeleteFunc(podSpec.Volumes, func(volume corev1.Volume) bool {
if !isHostSubscriptionVolume(volume) {
return false
}
subscriptionVolumeNames[volume.Name] = struct{}{}
return true
})
driverContainer.VolumeMounts = slices.DeleteFunc(driverContainer.VolumeMounts, func(volumeMount corev1.VolumeMount) bool {
_, found := subscriptionVolumeNames[volumeMount.Name]
return found
})
}

// isHostSubscriptionVolume reports whether a volume is managed for host subscriptions.
func isHostSubscriptionVolume(volume corev1.Volume) bool {
return strings.HasPrefix(volume.Name, consts.SubscriptionVolumeNamePrefix) && volume.HostPath != nil
}

func createSecretEnvReference(ctx context.Context, ctrlClient client.Client, secretName string,
namespace string, container *corev1.Container) error {
envFrom := container.EnvFrom
Expand Down
Loading
Loading