mirror of https://github.com/k3s-io/k3s
Merge pull request #69211 from lichuqiang/mount_options
mountoptions support for local storagepull/58/head
commit
02df80d82b
|
@ -87,7 +87,7 @@ func (plugin *localVolumePlugin) RequiresRemount() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (plugin *localVolumePlugin) SupportsMountOption() bool {
|
func (plugin *localVolumePlugin) SupportsMountOption() bool {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (plugin *localVolumePlugin) SupportsBulkVolumeVerification() bool {
|
func (plugin *localVolumePlugin) SupportsBulkVolumeVerification() bool {
|
||||||
|
@ -130,6 +130,7 @@ func (plugin *localVolumePlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ vo
|
||||||
globalPath: globalLocalPath,
|
globalPath: globalLocalPath,
|
||||||
MetricsProvider: volume.NewMetricsStatFS(plugin.host.GetPodVolumeDir(pod.UID, stringsutil.EscapeQualifiedNameForDisk(localVolumePluginName), spec.Name())),
|
MetricsProvider: volume.NewMetricsStatFS(plugin.host.GetPodVolumeDir(pod.UID, stringsutil.EscapeQualifiedNameForDisk(localVolumePluginName), spec.Name())),
|
||||||
},
|
},
|
||||||
|
mountOptions: util.MountOptionFromSpec(spec),
|
||||||
readOnly: readOnly,
|
readOnly: readOnly,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
|
@ -394,6 +395,7 @@ func (l *localVolume) GetPath() string {
|
||||||
type localVolumeMounter struct {
|
type localVolumeMounter struct {
|
||||||
*localVolume
|
*localVolume
|
||||||
readOnly bool
|
readOnly bool
|
||||||
|
mountOptions []string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ volume.Mounter = &localVolumeMounter{}
|
var _ volume.Mounter = &localVolumeMounter{}
|
||||||
|
@ -476,10 +478,11 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error {
|
||||||
if m.readOnly {
|
if m.readOnly {
|
||||||
options = append(options, "ro")
|
options = append(options, "ro")
|
||||||
}
|
}
|
||||||
|
mountOptions := util.JoinMountOptions(options, m.mountOptions)
|
||||||
|
|
||||||
glog.V(4).Infof("attempting to mount %s", dir)
|
glog.V(4).Infof("attempting to mount %s", dir)
|
||||||
globalPath := util.MakeAbsolutePath(runtime.GOOS, m.globalPath)
|
globalPath := util.MakeAbsolutePath(runtime.GOOS, m.globalPath)
|
||||||
err = m.mounter.Mount(globalPath, dir, "", options)
|
err = m.mounter.Mount(globalPath, dir, "", mountOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Mount of volume %s failed: %v", dir, err)
|
glog.Errorf("Mount of volume %s failed: %v", dir, err)
|
||||||
notMnt, mntErr := m.mounter.IsNotMountPoint(dir)
|
notMnt, mntErr := m.mounter.IsNotMountPoint(dir)
|
||||||
|
|
|
@ -131,7 +131,7 @@ func getDeviceMountablePluginWithBlockPath(t *testing.T, isBlockDevice bool) (st
|
||||||
return tmpDir, plug
|
return tmpDir, plug
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTestVolume(readOnly bool, path string, isBlock bool) *volume.Spec {
|
func getTestVolume(readOnly bool, path string, isBlock bool, mountOptions []string) *volume.Spec {
|
||||||
pv := &v1.PersistentVolume{
|
pv := &v1.PersistentVolume{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: testPVName,
|
Name: testPVName,
|
||||||
|
@ -142,6 +142,7 @@ func getTestVolume(readOnly bool, path string, isBlock bool) *volume.Spec {
|
||||||
Path: path,
|
Path: path,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
MountOptions: mountOptions,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +157,7 @@ func TestCanSupport(t *testing.T) {
|
||||||
tmpDir, plug := getPlugin(t)
|
tmpDir, plug := getPlugin(t)
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
if !plug.CanSupport(getTestVolume(false, tmpDir, false)) {
|
if !plug.CanSupport(getTestVolume(false, tmpDir, false, nil)) {
|
||||||
t.Errorf("Expected true")
|
t.Errorf("Expected true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +183,7 @@ func TestGetVolumeName(t *testing.T) {
|
||||||
tmpDir, plug := getPersistentPlugin(t)
|
tmpDir, plug := getPersistentPlugin(t)
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
volName, err := plug.GetVolumeName(getTestVolume(false, tmpDir, false))
|
volName, err := plug.GetVolumeName(getTestVolume(false, tmpDir, false, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to get volume name: %v", err)
|
t.Errorf("Failed to get volume name: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,7 @@ func TestInvalidLocalPath(t *testing.T) {
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||||
mounter, err := plug.NewMounter(getTestVolume(false, "/no/backsteps/allowed/..", false), pod, volume.VolumeOptions{})
|
mounter, err := plug.NewMounter(getTestVolume(false, "/no/backsteps/allowed/..", false, nil), pod, volume.VolumeOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -218,7 +219,7 @@ func TestBlockDeviceGlobalPathAndMountDevice(t *testing.T) {
|
||||||
t.Errorf("Failed to make a new device mounter: %v", err)
|
t.Errorf("Failed to make a new device mounter: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pvSpec := getTestVolume(false, tmpBlockDir, false)
|
pvSpec := getTestVolume(false, tmpBlockDir, false, nil)
|
||||||
|
|
||||||
expectedGlobalPath := filepath.Join(tmpBlockDir, testBlockFormattingToFSGlobalPath)
|
expectedGlobalPath := filepath.Join(tmpBlockDir, testBlockFormattingToFSGlobalPath)
|
||||||
actualPath, err := dm.GetDeviceMountPath(pvSpec)
|
actualPath, err := dm.GetDeviceMountPath(pvSpec)
|
||||||
|
@ -264,7 +265,7 @@ func TestFSGlobalPathAndMountDevice(t *testing.T) {
|
||||||
t.Errorf("Failed to make a new device mounter: %v", err)
|
t.Errorf("Failed to make a new device mounter: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pvSpec := getTestVolume(false, tmpFSDir, false)
|
pvSpec := getTestVolume(false, tmpFSDir, false, nil)
|
||||||
|
|
||||||
expectedGlobalPath := tmpFSDir
|
expectedGlobalPath := tmpFSDir
|
||||||
actualPath, err := dm.GetDeviceMountPath(pvSpec)
|
actualPath, err := dm.GetDeviceMountPath(pvSpec)
|
||||||
|
@ -294,7 +295,7 @@ func TestMountUnmount(t *testing.T) {
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false), pod, volume.VolumeOptions{})
|
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -347,7 +348,7 @@ func TestMapUnmap(t *testing.T) {
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||||
volSpec := getTestVolume(false, tmpDir, true /*isBlock*/)
|
volSpec := getTestVolume(false, tmpDir, true /*isBlock*/, nil)
|
||||||
mapper, err := plug.NewBlockVolumeMapper(volSpec, pod, volume.VolumeOptions{})
|
mapper, err := plug.NewBlockVolumeMapper(volSpec, pod, volume.VolumeOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||||
|
@ -399,7 +400,7 @@ func TestMapUnmap(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFSGroupMount(plug volume.VolumePlugin, pod *v1.Pod, tmpDir string, fsGroup int64) error {
|
func testFSGroupMount(plug volume.VolumePlugin, pod *v1.Pod, tmpDir string, fsGroup int64) error {
|
||||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false), pod, volume.VolumeOptions{})
|
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -501,13 +502,40 @@ func TestConstructBlockVolumeSpec(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMountOptions(t *testing.T) {
|
||||||
|
tmpDir, plug := getPlugin(t)
|
||||||
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
|
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||||
|
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false, []string{"test-option"}), pod, volume.VolumeOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||||
|
}
|
||||||
|
if mounter == nil {
|
||||||
|
t.Fatalf("Got a nil Mounter")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap with FakeMounter.
|
||||||
|
fakeMounter := &mount.FakeMounter{}
|
||||||
|
mounter.(*localVolumeMounter).mounter = fakeMounter
|
||||||
|
|
||||||
|
if err := mounter.SetUp(nil); err != nil {
|
||||||
|
t.Errorf("Expected success, got: %v", err)
|
||||||
|
}
|
||||||
|
mountOptions := fakeMounter.MountPoints[0].Opts
|
||||||
|
expectedMountOptions := []string{"bind", "test-option"}
|
||||||
|
if !reflect.DeepEqual(mountOptions, expectedMountOptions) {
|
||||||
|
t.Errorf("Expected mount options to be %v got %v", expectedMountOptions, mountOptions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||||
tmpDir, plug := getPlugin(t)
|
tmpDir, plug := getPlugin(t)
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
// Read only == true
|
// Read only == true
|
||||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||||
mounter, err := plug.NewMounter(getTestVolume(true, tmpDir, false), pod, volume.VolumeOptions{})
|
mounter, err := plug.NewMounter(getTestVolume(true, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -519,7 +547,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read only == false
|
// Read only == false
|
||||||
mounter, err = plug.NewMounter(getTestVolume(false, tmpDir, false), pod, volume.VolumeOptions{})
|
mounter, err = plug.NewMounter(getTestVolume(false, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to make a new Mounter: %v", err)
|
t.Errorf("Failed to make a new Mounter: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -540,7 +568,7 @@ func TestUnsupportedPlugins(t *testing.T) {
|
||||||
|
|
||||||
plugMgr := volume.VolumePluginMgr{}
|
plugMgr := volume.VolumePluginMgr{}
|
||||||
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(tmpDir, nil, nil))
|
plugMgr.InitPlugins(ProbeVolumePlugins(), nil /* prober */, volumetest.NewFakeVolumeHost(tmpDir, nil, nil))
|
||||||
spec := getTestVolume(false, tmpDir, false)
|
spec := getTestVolume(false, tmpDir, false, nil)
|
||||||
|
|
||||||
recyclePlug, err := plugMgr.FindRecyclablePluginBySpec(spec)
|
recyclePlug, err := plugMgr.FindRecyclablePluginBySpec(spec)
|
||||||
if err == nil && recyclePlug != nil {
|
if err == nil && recyclePlug != nil {
|
||||||
|
@ -573,7 +601,7 @@ func TestFilterPodMounts(t *testing.T) {
|
||||||
defer os.RemoveAll(tmpDir)
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
pod := &v1.Pod{ObjectMeta: metav1.ObjectMeta{UID: types.UID("poduid")}}
|
||||||
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false), pod, volume.VolumeOptions{})
|
mounter, err := plug.NewMounter(getTestVolume(false, tmpDir, false, nil), pod, volume.VolumeOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue