mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Reconstruct SELinux mount option
When reconstructing volumes from disk after kubelet restart, reconstruct also context=XYZ mount option and add it to the ActualStateOfWorld.
This commit is contained in:
parent
95bd687a28
commit
e575e60ea4
@ -160,7 +160,6 @@ func (rc *reconciler) updateStates(volumesNeedUpdate map[v1.UniqueVolumeName]*gl
|
||||
klog.ErrorS(err, "Could not find device mount path for volume", "volumeName", gvl.volumeName)
|
||||
continue
|
||||
}
|
||||
// TODO(jsafrane): add reconstructed SELinux context
|
||||
err = rc.actualStateOfWorld.MarkDeviceAsMounted(gvl.volumeName, gvl.devicePath, deviceMountPath, "")
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Could not mark device is mounted to actual state of world", "volume", gvl.volumeName)
|
||||
|
@ -56,6 +56,7 @@ type reconstructedVolume struct {
|
||||
mounter volumepkg.Mounter
|
||||
deviceMounter volumepkg.DeviceMounter
|
||||
blockVolumeMapper volumepkg.BlockVolumeMapper
|
||||
seLinuxMountContext string
|
||||
}
|
||||
|
||||
// globalVolumeInfo stores reconstructed volume information
|
||||
@ -211,6 +212,9 @@ func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume,
|
||||
return nil, err
|
||||
}
|
||||
volumeSpec := reconstructed.Spec
|
||||
if volumeSpec == nil {
|
||||
return nil, fmt.Errorf("failed to reconstruct volume for plugin %q (spec.Name: %q) pod %q (UID: %q): got nil", volume.pluginName, volume.volumeSpecName, volume.podName, pod.UID)
|
||||
}
|
||||
|
||||
// We have to find the plugins by volume spec (NOT by plugin name) here
|
||||
// in order to correctly reconstruct ephemeral volume types.
|
||||
@ -312,9 +316,10 @@ func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume,
|
||||
volumeGidValue: "",
|
||||
// devicePath is updated during updateStates() by checking node status's VolumesAttached data.
|
||||
// TODO: get device path directly from the volume mount path.
|
||||
devicePath: "",
|
||||
mounter: volumeMounter,
|
||||
blockVolumeMapper: volumeMapper,
|
||||
devicePath: "",
|
||||
mounter: volumeMounter,
|
||||
blockVolumeMapper: volumeMapper,
|
||||
seLinuxMountContext: reconstructed.SELinuxMountContext,
|
||||
}
|
||||
return reconstructedVolume, nil
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ func (rc *reconciler) updateStatesNew(reconstructedVolumes map[v1.UniqueVolumeNa
|
||||
klog.ErrorS(err, "Could not add volume information to actual state of world", "volumeName", gvl.volumeName)
|
||||
continue
|
||||
}
|
||||
var seLinuxMountContext string
|
||||
for _, volume := range gvl.podVolumes {
|
||||
markVolumeOpts := operationexecutor.MarkVolumeOpts{
|
||||
PodName: volume.podName,
|
||||
@ -123,6 +124,7 @@ func (rc *reconciler) updateStatesNew(reconstructedVolumes map[v1.UniqueVolumeNa
|
||||
VolumeGidVolume: volume.volumeGidValue,
|
||||
VolumeSpec: volume.volumeSpec,
|
||||
VolumeMountState: operationexecutor.VolumeMountUncertain,
|
||||
SELinuxMountContext: volume.seLinuxMountContext,
|
||||
}
|
||||
|
||||
_, err = rc.actualStateOfWorld.CheckAndMarkVolumeAsUncertainViaReconstruction(markVolumeOpts)
|
||||
@ -130,7 +132,8 @@ func (rc *reconciler) updateStatesNew(reconstructedVolumes map[v1.UniqueVolumeNa
|
||||
klog.ErrorS(err, "Could not add pod to volume information to actual state of world", "pod", klog.KObj(volume.pod))
|
||||
continue
|
||||
}
|
||||
klog.V(2).InfoS("Volume is marked as uncertain and added into the actual state", "pod", klog.KObj(volume.pod), "podName", volume.podName, "volumeName", volume.volumeName)
|
||||
seLinuxMountContext = volume.seLinuxMountContext
|
||||
klog.V(2).InfoS("Volume is marked as uncertain and added into the actual state", "pod", klog.KObj(volume.pod), "podName", volume.podName, "volumeName", volume.volumeName, "seLinuxMountContext", volume.seLinuxMountContext)
|
||||
}
|
||||
// If the volume has device to mount, we mark its device as uncertain.
|
||||
if gvl.deviceMounter != nil || gvl.blockVolumeMapper != nil {
|
||||
@ -139,7 +142,7 @@ func (rc *reconciler) updateStatesNew(reconstructedVolumes map[v1.UniqueVolumeNa
|
||||
klog.ErrorS(err, "Could not find device mount path for volume", "volumeName", gvl.volumeName)
|
||||
continue
|
||||
}
|
||||
err = rc.actualStateOfWorld.MarkDeviceAsUncertain(gvl.volumeName, gvl.devicePath, deviceMountPath, "")
|
||||
err = rc.actualStateOfWorld.MarkDeviceAsUncertain(gvl.volumeName, gvl.devicePath, deviceMountPath, seLinuxMountContext)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Could not mark device is uncertain to actual state of world", "volumeName", gvl.volumeName, "deviceMountPath", deviceMountPath)
|
||||
continue
|
||||
|
@ -60,7 +60,7 @@ var (
|
||||
testAccount = "test-service-account"
|
||||
)
|
||||
|
||||
func prepareVolumeInfoFile(mountPath string, plug *csiPlugin, specVolumeName, volumeID, driverName, lifecycleMode string) error {
|
||||
func prepareVolumeInfoFile(mountPath string, plug *csiPlugin, specVolumeName, volumeID, driverName, lifecycleMode, seLinuxMountContext string) error {
|
||||
nodeName := string(plug.host.GetNodeName())
|
||||
volData := map[string]string{
|
||||
volDataKey.specVolID: specVolumeName,
|
||||
@ -69,6 +69,7 @@ func prepareVolumeInfoFile(mountPath string, plug *csiPlugin, specVolumeName, vo
|
||||
volDataKey.nodeName: nodeName,
|
||||
volDataKey.attachmentID: getAttachmentName(volumeID, driverName, nodeName),
|
||||
volDataKey.volumeLifecycleMode: lifecycleMode,
|
||||
volDataKey.seLinuxMountContext: seLinuxMountContext,
|
||||
}
|
||||
if err := os.MkdirAll(mountPath, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create dir for volume info file: %s", err)
|
||||
|
@ -455,22 +455,23 @@ func (p *csiPlugin) ConstructVolumeSpec(volumeName, mountPath string) (volume.Re
|
||||
if err != nil {
|
||||
return volume.ReconstructedVolume{}, errors.New(log("plugin.ConstructVolumeSpec failed loading volume data using [%s]: %v", mountPath, err))
|
||||
}
|
||||
|
||||
klog.V(4).Info(log("plugin.ConstructVolumeSpec extracted [%#v]", volData))
|
||||
|
||||
var spec *volume.Spec
|
||||
var ret volume.ReconstructedVolume
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||
ret.SELinuxMountContext = volData[volDataKey.seLinuxMountContext]
|
||||
}
|
||||
|
||||
// If mode is VolumeLifecycleEphemeral, use constructVolSourceSpec
|
||||
// to construct volume source spec. If mode is VolumeLifecyclePersistent,
|
||||
// use constructPVSourceSpec to construct volume construct pv source spec.
|
||||
if storage.VolumeLifecycleMode(volData[volDataKey.volumeLifecycleMode]) == storage.VolumeLifecycleEphemeral {
|
||||
spec = p.constructVolSourceSpec(volData[volDataKey.specVolID], volData[volDataKey.driverName])
|
||||
return volume.ReconstructedVolume{Spec: spec}, nil
|
||||
ret.Spec = p.constructVolSourceSpec(volData[volDataKey.specVolID], volData[volDataKey.driverName])
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
spec = p.constructPVSourceSpec(volData[volDataKey.specVolID], volData[volDataKey.driverName], volData[volDataKey.volHandle])
|
||||
return volume.ReconstructedVolume{
|
||||
Spec: spec,
|
||||
}, nil
|
||||
ret.Spec = p.constructPVSourceSpec(volData[volDataKey.specVolID], volData[volDataKey.driverName], volData[volDataKey.volHandle])
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// constructVolSourceSpec constructs volume.Spec with CSIVolumeSource
|
||||
|
@ -29,9 +29,12 @@ import (
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/informers"
|
||||
fakeclient "k8s.io/client-go/kubernetes/fake"
|
||||
utiltesting "k8s.io/client-go/util/testing"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
)
|
||||
@ -316,16 +319,20 @@ func TestPluginConstructVolumeSpec(t *testing.T) {
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
originSpec *volume.Spec
|
||||
specVolID string
|
||||
volHandle string
|
||||
podUID types.UID
|
||||
name string
|
||||
seLinuxMountEnabled bool
|
||||
originSpec *volume.Spec
|
||||
originSELinuxMountContext string
|
||||
specVolID string
|
||||
volHandle string
|
||||
expectedSELinuxContext string
|
||||
podUID types.UID
|
||||
}{
|
||||
{
|
||||
name: "construct spec1 from original persistent spec",
|
||||
specVolID: "test.vol.id",
|
||||
volHandle: "testvol-handle1",
|
||||
name: "construct spec1 from original persistent spec",
|
||||
specVolID: "test.vol.id",
|
||||
volHandle: "testvol-handle1",
|
||||
|
||||
originSpec: volume.NewSpecFromPersistentVolume(makeTestPV("test.vol.id", 20, testDriver, "testvol-handle1"), true),
|
||||
podUID: types.UID(fmt.Sprintf("%08X", rand.Uint64())),
|
||||
},
|
||||
@ -336,12 +343,35 @@ func TestPluginConstructVolumeSpec(t *testing.T) {
|
||||
originSpec: volume.NewSpecFromPersistentVolume(makeTestPV("spec2", 20, testDriver, "handle2"), true),
|
||||
podUID: types.UID(fmt.Sprintf("%08X", rand.Uint64())),
|
||||
},
|
||||
{
|
||||
name: "construct SELinux context from original persistent spec when the feature is enabled",
|
||||
seLinuxMountEnabled: true,
|
||||
specVolID: "spec3",
|
||||
volHandle: "handle3",
|
||||
originSELinuxMountContext: "system_u:object_r:container_file_t:s0:c314,c894",
|
||||
originSpec: volume.NewSpecFromPersistentVolume(makeTestPV("spec3", 20, testDriver, "handle3"), true),
|
||||
expectedSELinuxContext: "system_u:object_r:container_file_t:s0:c314,c894",
|
||||
podUID: types.UID(fmt.Sprintf("%08X", rand.Uint64())),
|
||||
},
|
||||
{
|
||||
name: "construct empty SELinux from original persistent spec when the feature is disabled",
|
||||
seLinuxMountEnabled: false,
|
||||
specVolID: "spec4",
|
||||
volHandle: "handle4",
|
||||
originSELinuxMountContext: "system_u:object_r:container_file_t:s0:c314,c894",
|
||||
originSpec: volume.NewSpecFromPersistentVolume(makeTestPV("spec4", 20, testDriver, "handle4"), true),
|
||||
expectedSELinuxContext: "", // The context is cleared when the feature gate is off
|
||||
podUID: types.UID(fmt.Sprintf("%08X", rand.Uint64())),
|
||||
},
|
||||
}
|
||||
|
||||
registerFakePlugin(testDriver, "endpoint", []string{"1.0.0"}, t)
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ReadWriteOncePod, tc.seLinuxMountEnabled)()
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, tc.seLinuxMountEnabled)()
|
||||
|
||||
mounter, err := plug.NewMounter(
|
||||
tc.originSpec,
|
||||
&api.Pod{ObjectMeta: meta.ObjectMeta{UID: tc.podUID, Namespace: testns}},
|
||||
@ -356,7 +386,7 @@ func TestPluginConstructVolumeSpec(t *testing.T) {
|
||||
csiMounter := mounter.(*csiMountMgr)
|
||||
|
||||
mountPath := filepath.Dir(csiMounter.GetPath())
|
||||
err = prepareVolumeInfoFile(mountPath, plug, tc.originSpec.Name(), csiMounter.volumeID, testDriver, string(csiMounter.volumeLifecycleMode))
|
||||
err = prepareVolumeInfoFile(mountPath, plug, tc.originSpec.Name(), csiMounter.volumeID, testDriver, string(csiMounter.volumeLifecycleMode), tc.originSELinuxMountContext)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save fake volume info file: %s", err)
|
||||
}
|
||||
@ -395,6 +425,10 @@ func TestPluginConstructVolumeSpec(t *testing.T) {
|
||||
if rec.Spec.Name() != tc.specVolID {
|
||||
t.Errorf("Unexpected spec name constructed %s", rec.Spec.Name())
|
||||
}
|
||||
|
||||
if rec.SELinuxMountContext != tc.expectedSELinuxContext {
|
||||
t.Errorf("Expected SELinux context %q, got %q", tc.expectedSELinuxContext, rec.SELinuxMountContext)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -490,7 +524,7 @@ func TestPluginConstructVolumeSpecWithInline(t *testing.T) {
|
||||
csiMounter := mounter.(*csiMountMgr)
|
||||
|
||||
mountPath := filepath.Dir(csiMounter.GetPath())
|
||||
err = prepareVolumeInfoFile(mountPath, plug, tc.originSpec.Name(), csiMounter.volumeID, testDriver, string(csiMounter.volumeLifecycleMode))
|
||||
err = prepareVolumeInfoFile(mountPath, plug, tc.originSpec.Name(), csiMounter.volumeID, testDriver, string(csiMounter.volumeLifecycleMode), "")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to save fake volume info file: %s", err)
|
||||
}
|
||||
|
@ -283,10 +283,25 @@ func (plugin *fcPlugin) ConstructVolumeSpec(volumeName, mountPath string) (volum
|
||||
FC: &v1.FCVolumeSource{WWIDs: wwids, Lun: &lun, TargetWWNs: wwns},
|
||||
},
|
||||
}
|
||||
|
||||
var mountContext string
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||
kvh, ok := plugin.host.(volume.KubeletVolumeHost)
|
||||
if !ok {
|
||||
return volume.ReconstructedVolume{}, fmt.Errorf("plugin volume host does not implement KubeletVolumeHost interface")
|
||||
}
|
||||
hu := kvh.GetHostUtil()
|
||||
mountContext, err = hu.GetSELinuxMountContext(mountPath)
|
||||
if err != nil {
|
||||
return volume.ReconstructedVolume{}, err
|
||||
}
|
||||
}
|
||||
|
||||
klog.V(5).Infof("ConstructVolumeSpec: TargetWWNs: %v, Lun: %v, WWIDs: %v",
|
||||
fcVolume.VolumeSource.FC.TargetWWNs, *fcVolume.VolumeSource.FC.Lun, fcVolume.VolumeSource.FC.WWIDs)
|
||||
return volume.ReconstructedVolume{
|
||||
Spec: volume.NewSpecFromVolume(fcVolume),
|
||||
Spec: volume.NewSpecFromVolume(fcVolume),
|
||||
SELinuxMountContext: mountContext,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -279,8 +279,23 @@ func (plugin *iscsiPlugin) ConstructVolumeSpec(volumeName, mountPath string) (vo
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var mountContext string
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||
kvh, ok := plugin.host.(volume.KubeletVolumeHost)
|
||||
if !ok {
|
||||
return volume.ReconstructedVolume{}, fmt.Errorf("plugin volume host does not implement KubeletVolumeHost interface")
|
||||
}
|
||||
hu := kvh.GetHostUtil()
|
||||
mountContext, err = hu.GetSELinuxMountContext(mountPath)
|
||||
if err != nil {
|
||||
return volume.ReconstructedVolume{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return volume.ReconstructedVolume{
|
||||
Spec: volume.NewSpecFromVolume(iscsiVolume),
|
||||
Spec: volume.NewSpecFromVolume(iscsiVolume),
|
||||
SELinuxMountContext: mountContext,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -573,7 +573,11 @@ type VolumeConfig struct {
|
||||
// ReconstructedVolume contains information about a volume reconstructed by
|
||||
// ConstructVolumeSpec().
|
||||
type ReconstructedVolume struct {
|
||||
// Spec is the volume spec of a mounted volume
|
||||
Spec *Spec
|
||||
// SELinuxMountContext is value of -o context=XYZ mount option.
|
||||
// If empty, no such mount option is used.
|
||||
SELinuxMountContext string
|
||||
}
|
||||
|
||||
// NewSpecFromVolume creates an Spec from an v1.Volume
|
||||
|
@ -430,8 +430,18 @@ func (plugin *rbdPlugin) ConstructVolumeSpec(volumeName, mountPath string) (volu
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var mountContext string
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||
mountContext, err = hu.GetSELinuxMountContext(mountPath)
|
||||
if err != nil {
|
||||
return volume.ReconstructedVolume{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return volume.ReconstructedVolume{
|
||||
Spec: volume.NewSpecFromVolume(rbdVolume),
|
||||
Spec: volume.NewSpecFromVolume(rbdVolume),
|
||||
SELinuxMountContext: mountContext,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -116,3 +116,9 @@ func (hu *FakeHostUtil) GetSELinuxSupport(pathname string) (bool, error) {
|
||||
func (hu *FakeHostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
func (hu *FakeHostUtil) GetSELinuxMountContext(pathname string) (string, error) {
|
||||
return "", errors.New("not implemented")
|
||||
}
|
||||
|
@ -68,6 +68,9 @@ type HostUtils interface {
|
||||
GetSELinuxSupport(pathname string) (bool, error)
|
||||
// GetMode returns permissions of the path.
|
||||
GetMode(pathname string) (os.FileMode, error)
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
GetSELinuxMountContext(pathname string) (string, error)
|
||||
}
|
||||
|
||||
// Compile-time check to ensure all HostUtil implementations satisfy
|
||||
|
@ -299,3 +299,35 @@ func GetModeLinux(pathname string) (os.FileMode, error) {
|
||||
}
|
||||
return info.Mode(), nil
|
||||
}
|
||||
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
func (hu *HostUtil) GetSELinuxMountContext(pathname string) (string, error) {
|
||||
return getSELinuxMountContext(pathname, procMountInfoPath, selinux.GetEnabled)
|
||||
}
|
||||
|
||||
// getSELinux is common implementation of GetSELinuxSupport on Linux.
|
||||
// Using an extra function for unit tests.
|
||||
func getSELinuxMountContext(path string, mountInfoFilename string, selinuxEnabled seLinuxEnabledFunc) (string, error) {
|
||||
// Skip /proc/mounts parsing if SELinux is disabled.
|
||||
if !selinuxEnabled() {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
info, err := findMountInfo(path, mountInfoFilename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, opt := range info.SuperOptions {
|
||||
if !strings.HasPrefix(opt, "context=") {
|
||||
continue
|
||||
}
|
||||
// Remove context=
|
||||
context := strings.TrimPrefix(opt, "context=")
|
||||
// Remove double quotes
|
||||
context = strings.Trim(context, "\"")
|
||||
return context, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
@ -331,3 +331,60 @@ func writeFile(content string) (string, string, error) {
|
||||
}
|
||||
return tempDir, filename, nil
|
||||
}
|
||||
|
||||
func TestGetSELinuxMountContext(t *testing.T) {
|
||||
info :=
|
||||
`840 60 8:0 / /var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv rw,relatime shared:421 - ext4 /dev/sda rw,context="system_u:object_r:container_file_t:s0:c314,c894"
|
||||
224 62 253:0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
82 62 0:43 / /var/lib/foo rw,relatime shared:32 - tmpfs tmpfs rw
|
||||
83 63 0:44 / /var/lib/bar rw,relatime - tmpfs tmpfs rw
|
||||
`
|
||||
tempDir, filename, err := writeFile(info)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create temporary file: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
mountPoint string
|
||||
seLinuxEnabled bool
|
||||
expectedContext string
|
||||
}{
|
||||
{
|
||||
"no context",
|
||||
"/var/lib/foo",
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"with context with SELinux",
|
||||
"/var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv",
|
||||
true,
|
||||
"system_u:object_r:container_file_t:s0:c314,c894",
|
||||
},
|
||||
{
|
||||
"with context with no SELinux",
|
||||
"/var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv",
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"no context with seclabel",
|
||||
"/var/lib/docker/devicemapper/test/shared",
|
||||
true,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
out, err := getSELinuxMountContext(test.mountPoint, filename, func() bool { return test.seLinuxEnabled })
|
||||
if err != nil {
|
||||
t.Errorf("Test %s failed with error: %s", test.name, err)
|
||||
}
|
||||
if test.expectedContext != out {
|
||||
t.Errorf("Test %s failed: expected %v, got %v", test.name, test.expectedContext, out)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -101,3 +101,9 @@ func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) {
|
||||
return "", errUnsupported
|
||||
}
|
||||
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
func (hu *HostUtil) GetSELinuxMountContext(pathname string) (string, error) {
|
||||
return "", errUnsupported
|
||||
}
|
||||
|
@ -123,3 +123,9 @@ func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
}
|
||||
return info.Mode(), nil
|
||||
}
|
||||
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
func (hu *HostUtil) GetSELinuxMountContext(pathname string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user