Skip to content
Merged
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
52 changes: 32 additions & 20 deletions controllers/object_controls.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,67 +263,75 @@ var SubscriptionPathMap = map[string](MountPathToVolumeSource){
"/run/secrets/etc-pki-entitlement": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/pki/entitlement",
Type: ptr.To(corev1.HostPathDirectory),
Type: new(corev1.HostPathDirectoryOrCreate),
},
},
"/run/secrets/redhat.repo": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/yum.repos.d/redhat.repo",
Type: ptr.To(corev1.HostPathFile),
Type: new(corev1.HostPathFileOrCreate),
},
},
"/run/secrets/rhsm": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/rhsm",
Type: ptr.To(corev1.HostPathDirectory),
Type: new(corev1.HostPathDirectoryOrCreate),
},
},
// FileOrCreate does not create parents. A separate directory volume
// lets kubelet create the repo directory and retry file setup if needed.
"/run/secrets/yum.repos.d": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/yum.repos.d",
Type: new(corev1.HostPathDirectoryOrCreate),
},
},
},
"rhcos": {
"/run/secrets/etc-pki-entitlement": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/pki/entitlement",
Type: ptr.To(corev1.HostPathDirectory),
Type: new(corev1.HostPathDirectory),
},
},
"/run/secrets/redhat.repo": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/yum.repos.d/redhat.repo",
Type: ptr.To(corev1.HostPathFile),
Type: new(corev1.HostPathFile),
},
},
"/run/secrets/rhsm": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/rhsm",
Type: ptr.To(corev1.HostPathDirectory),
Type: new(corev1.HostPathDirectory),
},
},
},
"sles": {
"/etc/zypp/credentials.d": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/zypp/credentials.d",
Type: ptr.To(corev1.HostPathDirectory),
Type: new(corev1.HostPathDirectoryOrCreate),
},
},
"/etc/SUSEConnect": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/SUSEConnect",
Type: ptr.To(corev1.HostPathFileOrCreate),
Type: new(corev1.HostPathFileOrCreate),
},
},
},
"sl-micro": {
"/etc/zypp/credentials.d": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/zypp/credentials.d",
Type: ptr.To(corev1.HostPathDirectory),
Type: new(corev1.HostPathDirectoryOrCreate),
},
},
"/etc/SUSEConnect": corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{
Path: "/etc/SUSEConnect",
Type: ptr.To(corev1.HostPathFileOrCreate),
Type: new(corev1.HostPathFileOrCreate),
},
},
},
Expand Down Expand Up @@ -3777,15 +3785,10 @@ 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)
} else {
n.logger.Info("Mounting subscriptions into the driver container", "OS", osID)
pathToVolumeSource, err = n.getSubscriptionPathsToVolumeSources()
if err != nil {
return fmt.Errorf("ERROR: failed to get path items for subscription entitlements: %w", err)
}
n.logger.Info("Mounting subscriptions into the driver container", "OS", osID)
pathToVolumeSource, err := n.getSubscriptionPathsToVolumeSources()
if err != nil {
return fmt.Errorf("ERROR: failed to get path items for subscription entitlements: %w", err)
}

// sort host path volumes to ensure ordering is preserved when adding to pod spec
Expand All @@ -3803,7 +3806,16 @@ func transformDriverContainer(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicy
MountPath: mountPath,
ReadOnly: true,
}
driverContainer.VolumeMounts = append(driverContainer.VolumeMounts, volMountSubscription)
if mountPath == "/run/secrets/yum.repos.d" {
// The parent directory is needed only for kubelet's file creation.
manager := findContainerByName(podSpec.InitContainers, "k8s-driver-manager")
if manager == nil {
return fmt.Errorf("k8s-driver-manager initContainer is missing from the driver daemonset manifest")
}
manager.VolumeMounts = append(manager.VolumeMounts, volMountSubscription)
} else {
driverContainer.VolumeMounts = append(driverContainer.VolumeMounts, volMountSubscription)
}

subscriptionVol := corev1.Volume{Name: volMountSubscriptionName, VolumeSource: pathToVolumeSource[mountPath]}
podSpec.Volumes = append(podSpec.Volumes, subscriptionVol)
Expand Down
100 changes: 78 additions & 22 deletions controllers/transforms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4711,41 +4711,72 @@ func TestTransformDriverSubscriptionMounts(t *testing.T) {
Namespace: "test-ns",
},
Data: map[string]string{
"redhat.repo": "[test-repo]",
"custom.repo": "[test-repo]",
},
}
mockClient := fake.NewFakeClient(repoConfigMap)

testCases := []struct {
description string
rhelHostPaths := map[string]corev1.HostPathType{
"/etc/pki/entitlement": corev1.HostPathDirectoryOrCreate,
"/etc/yum.repos.d/redhat.repo": corev1.HostPathFileOrCreate,
"/etc/rhsm": corev1.HostPathDirectoryOrCreate,
"/etc/yum.repos.d": corev1.HostPathDirectoryOrCreate,
}
rhelDriverMounts := []corev1.VolumeMount{
{Name: "subscription-config-0", MountPath: "/run/secrets/etc-pki-entitlement", ReadOnly: true},
{Name: "subscription-config-1", MountPath: "/run/secrets/redhat.repo", ReadOnly: true},
{Name: "subscription-config-2", MountPath: "/run/secrets/rhsm", ReadOnly: true},
}
suseDriverMounts := []corev1.VolumeMount{
{Name: "subscription-config-0", MountPath: "/etc/SUSEConnect", ReadOnly: true},
{Name: "subscription-config-1", MountPath: "/etc/zypp/credentials.d", ReadOnly: true},
}
testCases := map[string]struct {
osRelease string
osTag string
runtime string
repoConfigEnabled bool
expectSubscriptionMounts bool
expectedSubscriptionHostMap map[string]corev1.HostPathType
expectedSubscriptionMounts []corev1.VolumeMount
}{
{
description: "rhel with repo config skips host subscription mounts",
osRelease: "rhel",
osTag: "rhel8.10",
repoConfigEnabled: true,
expectSubscriptionMounts: false,
"rhel with custom repositories retains subscription mounts": {
osRelease: "rhel", osTag: "rhel8.10", runtime: "containerd",
repoConfigEnabled: true, expectedSubscriptionHostMap: rhelHostPaths, expectedSubscriptionMounts: rhelDriverMounts,
},
{
description: "rhel without repo config mounts host subscription paths",
osRelease: "rhel",
osTag: "rhel8.10",
expectSubscriptionMounts: true,
"rhel without custom repositories mounts subscription paths": {
osRelease: "rhel", osTag: "rhel8.10", runtime: "containerd",
expectedSubscriptionHostMap: rhelHostPaths, expectedSubscriptionMounts: rhelDriverMounts,
},
"rhel with docker mounts subscription paths": {
osRelease: "rhel", osTag: "rhel8.10", runtime: "docker",
repoConfigEnabled: true, expectedSubscriptionHostMap: rhelHostPaths, expectedSubscriptionMounts: rhelDriverMounts,
},
"rhel with crio skips subscription mounts": {
osRelease: "rhel", osTag: "rhel8.10", runtime: "crio", repoConfigEnabled: true,
},
"ubuntu skips subscription mounts": {
osRelease: "ubuntu", osTag: "ubuntu22.04", runtime: "containerd", repoConfigEnabled: true,
},
"sles creates missing subscription paths": {
osRelease: "sles", osTag: "sles15.6", runtime: "containerd", repoConfigEnabled: true,
expectedSubscriptionMounts: suseDriverMounts,
expectedSubscriptionHostMap: map[string]corev1.HostPathType{
"/etc/zypp/credentials.d": corev1.HostPathDirectoryOrCreate,
"/etc/SUSEConnect": corev1.HostPathFileOrCreate,
},
},
"sl-micro creates missing subscription paths": {
osRelease: "sl-micro", osTag: "sl-micro6.1", runtime: "containerd", repoConfigEnabled: true,
expectedSubscriptionMounts: suseDriverMounts,
expectedSubscriptionHostMap: map[string]corev1.HostPathType{
"/etc/pki/entitlement": corev1.HostPathDirectory,
"/etc/yum.repos.d/redhat.repo": corev1.HostPathFile,
"/etc/rhsm": corev1.HostPathDirectory,
"/etc/zypp/credentials.d": corev1.HostPathDirectoryOrCreate,
"/etc/SUSEConnect": corev1.HostPathFileOrCreate,
},
},
}

for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
ds := NewDaemonset().WithContainer(corev1.Container{Name: "nvidia-driver-ctr"}).
WithInitContainer(corev1.Container{Name: "k8s-driver-manager"})
cpSpec := &gpuv1.ClusterPolicySpec{
Expand All @@ -4768,7 +4799,7 @@ func TestTransformDriverSubscriptionMounts(t *testing.T) {

err := TransformDriver(ds.DaemonSet, cpSpec, ClusterPolicyController{
client: mockClient,
runtime: gpuv1.Containerd,
runtime: gpuv1.Runtime(tc.runtime),
operatorNamespace: "test-ns",
logger: ctrl.Log.WithName("test"),
gpuNodeOSRelease: tc.osRelease,
Expand All @@ -4779,7 +4810,32 @@ func TestTransformDriverSubscriptionMounts(t *testing.T) {
driverContainer := findContainerByName(ds.Spec.Template.Spec.Containers, "nvidia-driver-ctr")
require.NotNil(t, driverContainer)
assertSubscriptionHostPathVolumesForTransform(t, ds.Spec.Template.Spec.Volumes, tc.expectedSubscriptionHostMap)
assert.Equal(t, tc.expectSubscriptionMounts, hasSubscriptionVolumeMountForTransform(driverContainer.VolumeMounts))
expectedAdditionalMounts := append([]corev1.VolumeMount{}, tc.expectedSubscriptionMounts...)
if tc.repoConfigEnabled {
repoPaths := map[string]string{
"rhel": "/etc/yum.repos.d/custom.repo",
"ubuntu": "/etc/apt/sources.list.d/custom.repo",
"sles": "/etc/zypp/repos.d/custom.repo",
"sl-micro": "/etc/zypp/repos.d/custom.repo",
}
expectedAdditionalMounts = append(expectedAdditionalMounts, corev1.VolumeMount{
Name: "test-repo-config", MountPath: repoPaths[tc.osRelease],
SubPath: "custom.repo", ReadOnly: true,
})
}
assert.ElementsMatch(t, expectedAdditionalMounts, driverContainer.VolumeMounts)
expectedManagerMounts := []corev1.VolumeMount{}
if tc.osRelease == "rhel" && len(tc.expectedSubscriptionMounts) > 0 {
expectedManagerMounts = append(expectedManagerMounts, corev1.VolumeMount{
Name: "subscription-config-3", MountPath: "/run/secrets/yum.repos.d", ReadOnly: true,
})
}

manager := findContainerByName(ds.Spec.Template.Spec.InitContainers, "k8s-driver-manager")
require.NotNil(t, manager)
assert.ElementsMatch(t, expectedManagerMounts, manager.VolumeMounts)

assert.Equal(t, len(tc.expectedSubscriptionHostMap) > 0, hasSubscriptionVolumeMountForTransform(driverContainer.VolumeMounts))
})
}
}
Expand Down
5 changes: 3 additions & 2 deletions internal/state/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ type precompiledSpec struct {
}

type additionalConfigs struct {
VolumeMounts []corev1.VolumeMount
Volumes []corev1.Volume
DriverManagerVolumeMounts []corev1.VolumeMount
VolumeMounts []corev1.VolumeMount
Volumes []corev1.Volume
}

type driverRenderData struct {
Expand Down
Loading
Loading