From ecef7c31b74d810ba144b663bdac6a7ec3eb6c96 Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 22 Apr 2026 21:08:04 +0000 Subject: [PATCH] Updated Red Hat mounts for air-gapped clusters --- controllers/object_controls.go | 16 +++++++++++----- internal/state/driver_volumes.go | 20 +++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/controllers/object_controls.go b/controllers/object_controls.go index f7ea8abf8..c0f78367a 100644 --- a/controllers/object_controls.go +++ b/controllers/object_controls.go @@ -253,10 +253,13 @@ var SubscriptionPathMap = map[string](MountPathToVolumeSource){ Type: ptr.To(corev1.HostPathDirectory), }, }, + // FileOrCreate: kubelet rejects HostPathFile when the path is missing; air-gapped + // RHEL nodes often have no redhat.repo. When driver.repoConfig is set, this mount is + // omitted so the driver uses only the mounted ConfigMap repos. "/run/secrets/redhat.repo": corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{ Path: "/etc/yum.repos.d/redhat.repo", - Type: ptr.To(corev1.HostPathFile), + Type: ptr.To(corev1.HostPathFileOrCreate), }, }, "/run/secrets/rhsm": corev1.VolumeSource{ @@ -276,7 +279,7 @@ var SubscriptionPathMap = map[string](MountPathToVolumeSource){ "/run/secrets/redhat.repo": corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{ Path: "/etc/yum.repos.d/redhat.repo", - Type: ptr.To(corev1.HostPathFile), + Type: ptr.To(corev1.HostPathFileOrCreate), }, }, "/run/secrets/rhsm": corev1.VolumeSource{ @@ -3676,9 +3679,12 @@ 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" { 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: %v", err) + pathToVolumeSource := MountPathToVolumeSource{} + if config.Driver.RepoConfig == nil || config.Driver.RepoConfig.ConfigMapName == "" || osID != "rhel" { + pathToVolumeSource, err = n.getSubscriptionPathsToVolumeSources() + if err != nil { + return fmt.Errorf("ERROR: failed to get path items for subscription entitlements: %v", err) + } } // sort host path volumes to ensure ordering is preserved when adding to pod spec diff --git a/internal/state/driver_volumes.go b/internal/state/driver_volumes.go index a1f59c94c..8e5bdfe42 100644 --- a/internal/state/driver_volumes.go +++ b/internal/state/driver_volumes.go @@ -72,10 +72,13 @@ var SubscriptionPathMap = map[string]MountPathToVolumeSource{ Type: ptr.To(corev1.HostPathDirectory), }, }, + // FileOrCreate: kubelet rejects HostPathFile when the path is missing; air-gapped + // RHEL nodes often have no redhat.repo. When repoConfig is set, this mount is omitted + // so the driver uses only the mounted ConfigMap repos. "/run/secrets/redhat.repo": corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{ Path: "/etc/yum.repos.d/redhat.repo", - Type: ptr.To(corev1.HostPathFile), + Type: ptr.To(corev1.HostPathFileOrCreate), }, }, "/run/secrets/rhsm": corev1.VolumeSource{ @@ -95,7 +98,7 @@ var SubscriptionPathMap = map[string]MountPathToVolumeSource{ "/run/secrets/redhat.repo": corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{ Path: "/etc/yum.repos.d/redhat.repo", - Type: ptr.To(corev1.HostPathFile), + Type: ptr.To(corev1.HostPathFileOrCreate), }, }, "/run/secrets/rhsm": corev1.VolumeSource{ @@ -183,9 +186,16 @@ func (s *stateDriver) getDriverAdditionalConfigs(ctx context.Context, cr *v1alph // set up subscription entitlements for RHEL(using K8s with a non-CRIO runtime) and SLES if (pool.osRelease == "rhel" && openshiftVersion == "" && runtime != consts.CRIO) || pool.osRelease == "sles" || pool.osRelease == "sl-micro" { logger.Info("Mounting subscriptions into the driver container", "OS", pool.osVersion) - pathToVolumeSource, err := getSubscriptionPathsToVolumeSources(pool.osRelease) - if err != nil { - return nil, fmt.Errorf("ERROR: failed to get path items for subscription entitlements: %v", err) + pathToVolumeSource := MountPathToVolumeSource{} + // Custom repo ConfigMap supplies yum repos in offline/air-gapped installs. Skip + // mounting host RHSM paths (/etc/pki/entitlement, redhat.repo, /etc/rhsm): they may + // be missing or not directories on minimal nodes, and are not needed when packages + // come only from the mounted repo ConfigMap. + if !cr.Spec.IsRepoConfigEnabled() || pool.osRelease != "rhel" { + pathToVolumeSource, err = getSubscriptionPathsToVolumeSources(pool.osRelease) + if err != nil { + return nil, fmt.Errorf("ERROR: failed to get path items for subscription entitlements: %v", err) + } } // sort host path volumes to ensure ordering is preserved when adding to pod spec