Add SELinux mount support to CSI driver

With some minor refactoring to use common getCSIDriver function.
This commit is contained in:
Jan Safranek 2022-03-21 16:39:46 +01:00
parent de7f5b66ed
commit 5c90474f38
4 changed files with 75 additions and 53 deletions

View File

@ -26,9 +26,6 @@ import (
"strings"
"time"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/klog/v2"
v1 "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -36,9 +33,12 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util"
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
"k8s.io/utils/clock"
)
@ -331,8 +331,9 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
klog.V(4).Info(log("created target path successfully [%s]", deviceMountPath))
dataDir := filepath.Dir(deviceMountPath)
data := map[string]string{
volDataKey.volHandle: csiSource.VolumeHandle,
volDataKey.driverName: csiSource.Driver,
volDataKey.volHandle: csiSource.VolumeHandle,
volDataKey.driverName: csiSource.Driver,
volDataKey.seLinuxMountContext: deviceMounterArgs.SELinuxLabel,
}
err = saveVolumeData(dataDir, volDataFileName, data)
@ -371,6 +372,16 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
mountOptions = spec.PersistentVolume.Spec.MountOptions
}
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
support, err := c.plugin.SupportsSELinuxContextMount(spec)
if err != nil {
return errors.New(log("failed to query for SELinuxMount support: %s", err))
}
if support {
mountOptions = util.AddSELinuxMountOption(mountOptions, deviceMounterArgs.SELinuxLabel)
}
}
var nodeStageFSGroupArg *int64
if utilfeature.DefaultFeatureGate.Enabled(features.DelegateFSGroupToCSIDriver) {
driverSupportsCSIVolumeMountGroup, err := csi.NodeSupportsVolumeMountGroup(ctx)

View File

@ -24,8 +24,6 @@ import (
"os"
"path/filepath"
"k8s.io/klog/v2"
authenticationv1 "k8s.io/api/authentication/v1"
api "k8s.io/api/core/v1"
storage "k8s.io/api/storage/v1"
@ -33,6 +31,7 @@ import (
"k8s.io/apimachinery/pkg/types"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util"
@ -49,7 +48,8 @@ var (
driverName,
nodeName,
attachmentID,
volumeLifecycleMode string
volumeLifecycleMode,
seLinuxMountContext string
}{
"specVolID",
"volumeHandle",
@ -57,6 +57,7 @@ var (
"nodeName",
"attachmentID",
"volumeLifecycleMode",
"seLinuxMountContext",
}
)
@ -70,7 +71,7 @@ type csiMountMgr struct {
volumeID string
specVolumeID string
readOnly bool
supportsSELinux bool
needSELinuxRelabel bool
spec *volume.Spec
pod *api.Pod
podUID types.UID
@ -245,6 +246,18 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error
}
}
var selinuxLabelMount bool
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
support, err := c.plugin.SupportsSELinuxContextMount(c.spec)
if err != nil {
return errors.New(log("failed to query for SELinuxMount support: %s", err))
}
if support {
mountOptions = util.AddSELinuxMountOption(mountOptions, mounterArgs.SELinuxLabel)
selinuxLabelMount = true
}
}
err = csi.NodePublishVolume(
ctx,
volumeHandle,
@ -270,10 +283,12 @@ func (c *csiMountMgr) SetUpAt(dir string, mounterArgs volume.MounterArgs) error
return err
}
c.supportsSELinux, err = c.kubeVolHost.GetHostUtil().GetSELinuxSupport(dir)
if err != nil {
// The volume is mounted. Return UncertainProgressError, so kubelet will unmount it when user deletes the pod.
return volumetypes.NewUncertainProgressError(fmt.Sprintf("error checking for SELinux support: %s", err))
if !selinuxLabelMount {
c.needSELinuxRelabel, err = c.kubeVolHost.GetHostUtil().GetSELinuxSupport(dir)
if err != nil {
// The volume is mounted. Return UncertainProgressError, so kubelet will unmount it when user deletes the pod.
return volumetypes.NewUncertainProgressError(fmt.Sprintf("error checking for SELinux support: %s", err))
}
}
if !driverSupportsCSIVolumeMountGroup && c.supportsFSGroup(fsType, mounterArgs.FsGroup, c.fsGroupPolicy) {
@ -350,7 +365,7 @@ func (c *csiMountMgr) GetAttributes() volume.Attributes {
return volume.Attributes{
ReadOnly: c.readOnly,
Managed: !c.readOnly,
SELinuxRelabel: c.supportsSELinux,
SELinuxRelabel: c.needSELinuxRelabel,
}
}

View File

@ -1235,7 +1235,7 @@ func Test_csiMountMgr_supportsFSGroup(t *testing.T) {
volumeID: tt.fields.volumeID,
specVolumeID: tt.fields.specVolumeID,
readOnly: tt.fields.readOnly,
supportsSELinux: tt.fields.supportsSELinux,
needSELinuxRelabel: tt.fields.supportsSELinux,
spec: tt.fields.spec,
pod: tt.fields.pod,
podUID: tt.fields.podUID,

View File

@ -351,7 +351,7 @@ func (p *csiPlugin) RequiresRemount(spec *volume.Spec) bool {
klog.V(5).Info(log("Failed to mark %q as republish required, err: %v", spec.Name(), err))
return false
}
csiDriver, err := p.csiDriverLister.Get(driverName)
csiDriver, err := p.getCSIDriver(driverName)
if err != nil {
klog.V(5).Info(log("Failed to mark %q as republish required, err: %v", spec.Name(), err))
return false
@ -582,6 +582,20 @@ func (p *csiPlugin) SupportsBulkVolumeVerification() bool {
}
func (p *csiPlugin) SupportsSELinuxContextMount(spec *volume.Spec) (bool, error) {
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
driver, err := GetCSIDriverName(spec)
if err != nil {
return false, err
}
csiDriver, err := p.getCSIDriver(driver)
if err != nil {
return false, err
}
if csiDriver.Spec.SELinuxMount != nil {
return *csiDriver.Spec.SELinuxMount, nil
}
return false, nil
}
return false, nil
}
@ -795,17 +809,7 @@ func (p *csiPlugin) ConstructBlockVolumeSpec(podUID types.UID, specVolName, mapP
// skipAttach looks up CSIDriver object associated with driver name
// to determine if driver requires attachment volume operation
func (p *csiPlugin) skipAttach(driver string) (bool, error) {
kletHost, ok := p.host.(volume.KubeletVolumeHost)
if ok {
if err := kletHost.WaitForCacheSync(); err != nil {
return false, err
}
}
if p.csiDriverLister == nil {
return false, errors.New("CSIDriver lister does not exist")
}
csiDriver, err := p.csiDriverLister.Get(driver)
csiDriver, err := p.getCSIDriver(driver)
if err != nil {
if apierrors.IsNotFound(err) {
// Don't skip attach if CSIDriver does not exist
@ -819,6 +823,21 @@ func (p *csiPlugin) skipAttach(driver string) (bool, error) {
return false, nil
}
func (p *csiPlugin) getCSIDriver(driver string) (*storage.CSIDriver, error) {
kletHost, ok := p.host.(volume.KubeletVolumeHost)
if ok {
if err := kletHost.WaitForCacheSync(); err != nil {
return nil, err
}
}
if p.csiDriverLister == nil {
return nil, errors.New("CSIDriver lister does not exist")
}
csiDriver, err := p.csiDriverLister.Get(driver)
return csiDriver, err
}
// supportsVolumeMode checks whether the CSI driver supports a volume in the given mode.
// An error indicates that it isn't supported and explains why.
func (p *csiPlugin) supportsVolumeLifecycleMode(driver string, volumeMode storage.VolumeLifecycleMode) error {
@ -836,14 +855,7 @@ func (p *csiPlugin) supportsVolumeLifecycleMode(driver string, volumeMode storag
// optional), but then only persistent volumes are supported.
var csiDriver *storage.CSIDriver
if p.csiDriverLister != nil {
kletHost, ok := p.host.(volume.KubeletVolumeHost)
if ok {
if err := kletHost.WaitForCacheSync(); err != nil {
return err
}
}
c, err := p.csiDriverLister.Get(driver)
c, err := p.getCSIDriver(driver)
if err != nil && !apierrors.IsNotFound(err) {
// Some internal error.
return err
@ -904,14 +916,7 @@ func (p *csiPlugin) getFSGroupPolicy(driver string) (storage.FSGroupPolicy, erro
// optional)
var csiDriver *storage.CSIDriver
if p.csiDriverLister != nil {
kletHost, ok := p.host.(volume.KubeletVolumeHost)
if ok {
if err := kletHost.WaitForCacheSync(); err != nil {
return storage.ReadWriteOnceWithFSTypeFSGroupPolicy, err
}
}
c, err := p.csiDriverLister.Get(driver)
c, err := p.getCSIDriver(driver)
if err != nil && !apierrors.IsNotFound(err) {
// Some internal error.
return storage.ReadWriteOnceWithFSTypeFSGroupPolicy, err
@ -969,16 +974,7 @@ func (p *csiPlugin) newAttacherDetacher() (*csiAttacher, error) {
// podInfoEnabled check CSIDriver enabled pod info flag
func (p *csiPlugin) podInfoEnabled(driverName string) (bool, error) {
kletHost, ok := p.host.(volume.KubeletVolumeHost)
if ok {
kletHost.WaitForCacheSync()
}
if p.csiDriverLister == nil {
return false, fmt.Errorf("CSIDriverLister not found")
}
csiDriver, err := p.csiDriverLister.Get(driverName)
csiDriver, err := p.getCSIDriver(driverName)
if err != nil {
if apierrors.IsNotFound(err) {
klog.V(4).Infof(log("CSIDriver %q not found, not adding pod information", driverName))