From 314729a2b117dcc820f626e56538f35c1226ea25 Mon Sep 17 00:00:00 2001 From: Frederic Crozat Date: Wed, 14 Jan 2026 10:05:39 +0100 Subject: [PATCH] ensure /lib/modules is available for driver container on SUSE products This will ensure driver container built by SUSE has access to host kernel modules Signed-off-by: Frederic Crozat --- controllers/object_controls.go | 22 +++++++++++++ controllers/object_controls_test.go | 50 +++++++++++++++++++++++++++++ internal/state/driver_volumes.go | 22 +++++++++++++ 3 files changed, 94 insertions(+) diff --git a/controllers/object_controls.go b/controllers/object_controls.go index f811e8568..a7de542b4 100644 --- a/controllers/object_controls.go +++ b/controllers/object_controls.go @@ -3571,6 +3571,28 @@ func transformDriverContainer(obj *appsv1.DaemonSet, config *gpuv1.ClusterPolicy } } + // Mount /lib/modules for SLES/SL-Micro + if release["ID"] == "sles" || release["ID"] == "sl-micro" { + n.logger.Info("Mounting /lib/modules into the driver container", "OS", release["ID"]) + libModulesVolMount := corev1.VolumeMount{ + Name: "lib-modules", + MountPath: "/run/host/lib/modules", + ReadOnly: true, + } + driverContainer.VolumeMounts = append(driverContainer.VolumeMounts, libModulesVolMount) + + libModulesVol := corev1.Volume{ + Name: "lib-modules", + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: "/lib/modules", + Type: ptr.To(corev1.HostPathDirectory), + }, + }, + } + podSpec.Volumes = append(podSpec.Volumes, libModulesVol) + } + // apply proxy and env settings if this is an OpenShift cluster if _, ok := release["OPENSHIFT_VERSION"]; ok { setContainerEnv(driverContainer, "OPENSHIFT_VERSION", release["OPENSHIFT_VERSION"]) diff --git a/controllers/object_controls_test.go b/controllers/object_controls_test.go index 2d84b2fc5..99bb8eb45 100644 --- a/controllers/object_controls_test.go +++ b/controllers/object_controls_test.go @@ -1479,3 +1479,53 @@ func TestCertConfigPathMap(t *testing.T) { require.Equal(t, expectedPath, path, "Incorrect path for OS %s", os) } } + +// TestDriverSLES tests that the GPU Operator correctly handles SLES-specific configurations +func TestDriverSLES(t *testing.T) { + // Backup original parseOSRelease + originalParseOSRelease := parseOSRelease + defer func() { parseOSRelease = originalParseOSRelease }() + + // Mock SLES environment + parseOSRelease = mockOSRelease("sles", "15.7") + + cp := getDriverTestInput("default") + output := getDriverTestOutput("default") + + ds, err := testDaemonsetCommon(t, cp, "Driver", output["numDaemonsets"].(int)) + if err != nil { + t.Fatalf("error in testDaemonsetCommon(): %v", err) + } + require.NotNil(t, ds) + + // Check for /lib/modules volume and mount + foundVolume := false + for _, vol := range ds.Spec.Template.Spec.Volumes { + if vol.Name == "lib-modules" { + foundVolume = true + require.NotNil(t, vol.HostPath) + require.Equal(t, "/lib/modules", vol.HostPath.Path) + } + } + require.True(t, foundVolume, "lib-modules volume not found for SLES") + + foundMount := false + driverContainer := findContainerByName(ds.Spec.Template.Spec.Containers, "nvidia-driver-ctr") + require.NotNil(t, driverContainer) + + for _, mount := range driverContainer.VolumeMounts { + if mount.Name == "lib-modules" { + foundMount = true + require.Equal(t, "/run/host/lib/modules", mount.MountPath) + require.True(t, mount.ReadOnly) + } + } + require.True(t, foundMount, "lib-modules volume mount not found for SLES") + + // Cleanup + err = removeState(&clusterPolicyController, clusterPolicyController.idx-1) + if err != nil { + t.Fatalf("error removing state %v:", err) + } + clusterPolicyController.idx-- +} diff --git a/internal/state/driver_volumes.go b/internal/state/driver_volumes.go index 40086750f..c007e9570 100644 --- a/internal/state/driver_volumes.go +++ b/internal/state/driver_volumes.go @@ -205,6 +205,28 @@ func (s *stateDriver) getDriverAdditionalConfigs(ctx context.Context, cr *v1alph additionalCfgs.Volumes = append(additionalCfgs.Volumes, subscriptionVol) } } + + // Mount /lib/modules for SLES/SL-Micro + if pool.osRelease == "sles" || pool.osRelease == "sl-micro" { + logger.Info("Mounting /lib/modules into the driver container", "OS", pool.osRelease) + libModulesVolMount := corev1.VolumeMount{ + Name: "lib-modules", + MountPath: "/run/host/lib/modules", + ReadOnly: true, + } + additionalCfgs.VolumeMounts = append(additionalCfgs.VolumeMounts, libModulesVolMount) + + libModulesVol := corev1.Volume{ + Name: "lib-modules", + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: "/lib/modules", + Type: ptr.To(corev1.HostPathDirectory), + }, + }, + } + additionalCfgs.Volumes = append(additionalCfgs.Volumes, libModulesVol) + } } // mount any custom kernel module configuration parameters at /drivers