Skip to content

Commit

Permalink
Add SELinux mount support to CSI driver
Browse files Browse the repository at this point in the history
With some minor refactoring to use common getCSIDriver function.
  • Loading branch information
jsafrane committed Aug 4, 2022
1 parent de7f5b6 commit 5c90474
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 53 deletions.
21 changes: 16 additions & 5 deletions pkg/volume/csi/csi_attacher.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ 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"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"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"
)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
33 changes: 24 additions & 9 deletions pkg/volume/csi/csi_mounter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ 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"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"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"
Expand All @@ -49,14 +48,16 @@ var (
driverName,
nodeName,
attachmentID,
volumeLifecycleMode string
volumeLifecycleMode,
seLinuxMountContext string
}{
"specVolID",
"volumeHandle",
"driverName",
"nodeName",
"attachmentID",
"volumeLifecycleMode",
"seLinuxMountContext",
}
)

Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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) {
Expand Down Expand Up @@ -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,
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/volume/csi/csi_mounter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
72 changes: 34 additions & 38 deletions pkg/volume/csi/csi_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 5c90474

Please sign in to comment.