From 2f4be20f5de220ddceef3d77baad7967986c12b1 Mon Sep 17 00:00:00 2001 From: lichuqiang Date: Fri, 28 Sep 2018 16:29:01 +0800 Subject: [PATCH 1/2] mountoptions support for local storage --- pkg/volume/local/local.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/volume/local/local.go b/pkg/volume/local/local.go index 8d6c18b4bf..f121eb5e75 100644 --- a/pkg/volume/local/local.go +++ b/pkg/volume/local/local.go @@ -87,7 +87,7 @@ func (plugin *localVolumePlugin) RequiresRemount() bool { } func (plugin *localVolumePlugin) SupportsMountOption() bool { - return false + return true } func (plugin *localVolumePlugin) SupportsBulkVolumeVerification() bool { From f733837392813156b92aba23aea43e86dad60112 Mon Sep 17 00:00:00 2001 From: lichuqiang Date: Wed, 3 Oct 2018 13:10:35 +0800 Subject: [PATCH 2/2] support mount options in setup --- pkg/volume/local/local.go | 9 ++++-- pkg/volume/local/local_test.go | 54 ++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/pkg/volume/local/local.go b/pkg/volume/local/local.go index f121eb5e75..3b0b59f563 100644 --- a/pkg/volume/local/local.go +++ b/pkg/volume/local/local.go @@ -130,7 +130,8 @@ func (plugin *localVolumePlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ vo globalPath: globalLocalPath, MetricsProvider: volume.NewMetricsStatFS(plugin.host.GetPodVolumeDir(pod.UID, stringsutil.EscapeQualifiedNameForDisk(localVolumePluginName), spec.Name())), }, - readOnly: readOnly, + mountOptions: util.MountOptionFromSpec(spec), + readOnly: readOnly, }, nil } @@ -393,7 +394,8 @@ func (l *localVolume) GetPath() string { type localVolumeMounter struct { *localVolume - readOnly bool + readOnly bool + mountOptions []string } var _ volume.Mounter = &localVolumeMounter{} @@ -476,10 +478,11 @@ func (m *localVolumeMounter) SetUpAt(dir string, fsGroup *int64) error { if m.readOnly { options = append(options, "ro") } + mountOptions := util.JoinMountOptions(options, m.mountOptions) glog.V(4).Infof("attempting to mount %s", dir) globalPath := util.MakeAbsolutePath(runtime.GOOS, m.globalPath) - err = m.mounter.Mount(globalPath, dir, "", options) + err = m.mounter.Mount(globalPath, dir, "", mountOptions) if err != nil { glog.Errorf("Mount of volume %s failed: %v", dir, err) notMnt, mntErr := m.mounter.IsNotMountPoint(dir) diff --git a/pkg/volume/local/local_test.go b/pkg/volume/local/local_test.go index 37fd16a080..c28c92dde0 100644 --- a/pkg/volume/local/local_test.go +++ b/pkg/volume/local/local_test.go @@ -131,7 +131,7 @@ func getDeviceMountablePluginWithBlockPath(t *testing.T, isBlockDevice bool) (st 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{ ObjectMeta: metav1.ObjectMeta{ Name: testPVName, @@ -142,6 +142,7 @@ func getTestVolume(readOnly bool, path string, isBlock bool) *volume.Spec { Path: path, }, }, + MountOptions: mountOptions, }, } @@ -156,7 +157,7 @@ func TestCanSupport(t *testing.T) { tmpDir, plug := getPlugin(t) defer os.RemoveAll(tmpDir) - if !plug.CanSupport(getTestVolume(false, tmpDir, false)) { + if !plug.CanSupport(getTestVolume(false, tmpDir, false, nil)) { t.Errorf("Expected true") } } @@ -182,7 +183,7 @@ func TestGetVolumeName(t *testing.T) { tmpDir, plug := getPersistentPlugin(t) defer os.RemoveAll(tmpDir) - volName, err := plug.GetVolumeName(getTestVolume(false, tmpDir, false)) + volName, err := plug.GetVolumeName(getTestVolume(false, tmpDir, false, nil)) if err != nil { t.Errorf("Failed to get volume name: %v", err) } @@ -196,7 +197,7 @@ func TestInvalidLocalPath(t *testing.T) { defer os.RemoveAll(tmpDir) 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 { t.Fatal(err) } @@ -218,7 +219,7 @@ func TestBlockDeviceGlobalPathAndMountDevice(t *testing.T) { 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) 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) } - pvSpec := getTestVolume(false, tmpFSDir, false) + pvSpec := getTestVolume(false, tmpFSDir, false, nil) expectedGlobalPath := tmpFSDir actualPath, err := dm.GetDeviceMountPath(pvSpec) @@ -294,7 +295,7 @@ func TestMountUnmount(t *testing.T) { defer os.RemoveAll(tmpDir) 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 { t.Errorf("Failed to make a new Mounter: %v", err) } @@ -347,7 +348,7 @@ func TestMapUnmap(t *testing.T) { defer os.RemoveAll(tmpDir) 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{}) if err != nil { 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 { - 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 { 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) { tmpDir, plug := getPlugin(t) defer os.RemoveAll(tmpDir) // Read only == true 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 { t.Errorf("Failed to make a new Mounter: %v", err) } @@ -519,7 +547,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) { } // 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 { t.Errorf("Failed to make a new Mounter: %v", err) } @@ -540,7 +568,7 @@ func TestUnsupportedPlugins(t *testing.T) { plugMgr := volume.VolumePluginMgr{} 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) if err == nil && recyclePlug != nil { @@ -573,7 +601,7 @@ func TestFilterPodMounts(t *testing.T) { defer os.RemoveAll(tmpDir) 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 { t.Fatal(err) }