SafeFormatAndMount should use volume.Exec provided by VolumeHost

We need to execute mkfs / fsck where the utilities are.
This commit is contained in:
Jan Safranek 2017-08-14 12:16:27 +02:00
parent bc0e170d9c
commit 0e547bae22
35 changed files with 78 additions and 100 deletions

View File

@ -46,10 +46,7 @@ go_test(
"//conditions:default": [], "//conditions:default": [],
}), }),
library = ":go_default_library", library = ":go_default_library",
deps = [ deps = ["//vendor/k8s.io/utils/exec/testing:go_default_library"],
"//vendor/k8s.io/utils/exec:go_default_library",
"//vendor/k8s.io/utils/exec/testing:go_default_library",
],
) )
filegroup( filegroup(

View File

@ -25,7 +25,6 @@ import (
"strings" "strings"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/utils/exec"
) )
const ( const (
@ -99,7 +98,7 @@ type MountPoint struct {
// mounts it otherwise the device is formatted first then mounted. // mounts it otherwise the device is formatted first then mounted.
type SafeFormatAndMount struct { type SafeFormatAndMount struct {
Interface Interface
Runner exec.Interface Exec
} }
// FormatAndMount formats the given disk, if needed, and mounts it. // FormatAndMount formats the given disk, if needed, and mounts it.

View File

@ -412,8 +412,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
// Run fsck on the disk to fix repairable issues // Run fsck on the disk to fix repairable issues
glog.V(4).Infof("Checking for issues with fsck on disk: %s", source) glog.V(4).Infof("Checking for issues with fsck on disk: %s", source)
args := []string{"-a", source} args := []string{"-a", source}
cmd := mounter.Runner.Command("fsck", args...) out, err := mounter.Exec.Run("fsck", args...)
out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
ee, isExitError := err.(utilexec.ExitError) ee, isExitError := err.(utilexec.ExitError)
switch { switch {
@ -450,8 +449,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
args = []string{"-F", source} args = []string{"-F", source}
} }
glog.Infof("Disk %q appears to be unformatted, attempting to format as type: %q with options: %v", source, fstype, args) glog.Infof("Disk %q appears to be unformatted, attempting to format as type: %q with options: %v", source, fstype, args)
cmd := mounter.Runner.Command("mkfs."+fstype, args...) _, err := mounter.Exec.Run("mkfs."+fstype, args...)
_, err := cmd.CombinedOutput()
if err == nil { if err == nil {
// the disk has been formatted successfully try to mount it again. // the disk has been formatted successfully try to mount it again.
glog.Infof("Disk successfully formatted (mkfs): %s - %s %s", fstype, source, target) glog.Infof("Disk successfully formatted (mkfs): %s - %s %s", fstype, source, target)
@ -476,9 +474,8 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
// diskLooksUnformatted uses 'lsblk' to see if the given disk is unformated // diskLooksUnformatted uses 'lsblk' to see if the given disk is unformated
func (mounter *SafeFormatAndMount) getDiskFormat(disk string) (string, error) { func (mounter *SafeFormatAndMount) getDiskFormat(disk string) (string, error) {
args := []string{"-n", "-o", "FSTYPE", disk} args := []string{"-n", "-o", "FSTYPE", disk}
cmd := mounter.Runner.Command("lsblk", args...)
glog.V(4).Infof("Attempting to determine if disk %q is formatted using lsblk with args: (%v)", disk, args) glog.V(4).Infof("Attempting to determine if disk %q is formatted using lsblk with args: (%v)", disk, args)
dataOut, err := cmd.CombinedOutput() dataOut, err := mounter.Exec.Run("lsblk", args...)
output := string(dataOut) output := string(dataOut)
glog.V(4).Infof("Output: %q", output) glog.V(4).Infof("Output: %q", output)

View File

@ -21,7 +21,6 @@ import (
"runtime" "runtime"
"testing" "testing"
"k8s.io/utils/exec"
fakeexec "k8s.io/utils/exec/testing" fakeexec "k8s.io/utils/exec/testing"
) )
@ -181,40 +180,30 @@ func TestSafeFormatAndMount(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
commandScripts := []fakeexec.FakeCommandAction{} execCallCount := 0
for _, expected := range test.execScripts { execCallback := func(cmd string, args ...string) ([]byte, error) {
ecmd := expected.command if len(test.execScripts) <= execCallCount {
eargs := expected.args t.Errorf("Unexpected command: %s %v", cmd, args)
output := expected.output return nil, nil
err := expected.err
commandScript := func(cmd string, args ...string) exec.Cmd {
if cmd != ecmd {
t.Errorf("Unexpected command %s. Expecting %s", cmd, ecmd)
}
for j := range args {
if args[j] != eargs[j] {
t.Errorf("Unexpected args %v. Expecting %v", args, eargs)
}
}
fake := fakeexec.FakeCmd{
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
func() ([]byte, error) { return []byte(output), err },
},
}
return fakeexec.InitFakeCmd(&fake, cmd, args...)
} }
commandScripts = append(commandScripts, commandScript) script := test.execScripts[execCallCount]
} execCallCount++
if script.command != cmd {
fake := fakeexec.FakeExec{ t.Errorf("Unexpected command %s. Expecting %s", cmd, script.command)
CommandScript: commandScripts, }
for j := range args {
if args[j] != script.args[j] {
t.Errorf("Unexpected args %v. Expecting %v", args, script.args)
}
}
return []byte(script.output), script.err
} }
fakeMounter := ErrorMounter{&FakeMounter{}, 0, test.mountErrs} fakeMounter := ErrorMounter{&FakeMounter{}, 0, test.mountErrs}
fakeExec := NewFakeExec(execCallback)
mounter := SafeFormatAndMount{ mounter := SafeFormatAndMount{
Interface: &fakeMounter, Interface: &fakeMounter,
Runner: &fake, Exec: fakeExec,
} }
device := "/dev/foo" device := "/dev/foo"

View File

@ -27,7 +27,6 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
], ],
) )

View File

@ -29,7 +29,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/utils/exec" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
) )
type awsElasticBlockStoreAttacher struct { type awsElasticBlockStoreAttacher struct {
@ -222,7 +222,7 @@ func (attacher *awsElasticBlockStoreAttacher) MountDevice(spec *volume.Spec, dev
options = append(options, "ro") options = append(options, "ro")
} }
if notMnt { if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} diskMounter := volumehelper.NewSafeFormatAndMountFromHost(awsElasticBlockStorePluginName, attacher.host)
mountOptions := volume.MountOptionFromSpec(spec, options...) mountOptions := volume.MountOptionFromSpec(spec, options...)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions) err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil { if err != nil {

View File

@ -35,7 +35,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumehelper" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec"
) )
// This is the primary entrypoint for volume plugins. // This is the primary entrypoint for volume plugins.
@ -135,7 +134,7 @@ func (plugin *awsElasticBlockStorePlugin) newMounterInternal(spec *volume.Spec,
}, },
fsType: fsType, fsType: fsType,
readOnly: readOnly, readOnly: readOnly,
diskMounter: &mount.SafeFormatAndMount{Interface: plugin.host.GetMounter(plugin.GetPluginName()), Runner: exec.New()}}, nil diskMounter: volumehelper.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host)}, nil
} }
func (plugin *awsElasticBlockStorePlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) { func (plugin *awsElasticBlockStorePlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) {

View File

@ -24,6 +24,7 @@ go_library(
"//pkg/util/strings:go_default_library", "//pkg/util/strings:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/volumehelper:go_default_library",
"//vendor/github.com/Azure/azure-sdk-for-go/arm/compute:go_default_library", "//vendor/github.com/Azure/azure-sdk-for-go/arm/compute:go_default_library",
"//vendor/github.com/Azure/azure-sdk-for-go/arm/storage:go_default_library", "//vendor/github.com/Azure/azure-sdk-for-go/arm/storage:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",

View File

@ -35,6 +35,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec" "k8s.io/utils/exec"
) )
@ -232,7 +233,7 @@ func (attacher *azureDiskAttacher) MountDevice(spec *volume.Spec, devicePath str
options := []string{} options := []string{}
if notMnt { if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} diskMounter := volumehelper.NewSafeFormatAndMountFromHost(azureDataDiskPluginName, attacher.plugin.host)
mountOptions := volume.MountOptionFromSpec(spec, options...) mountOptions := volume.MountOptionFromSpec(spec, options...)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, *volumeSource.FSType, mountOptions) err = diskMounter.FormatAndMount(devicePath, deviceMountPath, *volumeSource.FSType, mountOptions)
if err != nil { if err != nil {

View File

@ -29,7 +29,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/utils/exec" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
) )
type cinderDiskAttacher struct { type cinderDiskAttacher struct {
@ -285,7 +285,7 @@ func (attacher *cinderDiskAttacher) MountDevice(spec *volume.Spec, devicePath st
options = append(options, "ro") options = append(options, "ro")
} }
if notMnt { if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} diskMounter := volumehelper.NewSafeFormatAndMountFromHost(cinderVolumePluginName, attacher.host)
mountOptions := volume.MountOptionFromSpec(spec, options...) mountOptions := volume.MountOptionFromSpec(spec, options...)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions) err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil { if err != nil {

View File

@ -36,7 +36,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumehelper" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec"
) )
// This is the primary entrypoint for volume plugins. // This is the primary entrypoint for volume plugins.
@ -139,7 +138,7 @@ func (plugin *cinderPlugin) newMounterInternal(spec *volume.Spec, podUID types.U
}, },
fsType: fsType, fsType: fsType,
readOnly: readOnly, readOnly: readOnly,
blockDeviceMounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}}, nil blockDeviceMounter: volumehelper.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host)}, nil
} }
func (plugin *cinderPlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) { func (plugin *cinderPlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) {

View File

@ -20,6 +20,7 @@ go_library(
"//pkg/util/strings:go_default_library", "//pkg/util/strings:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",
"//pkg/volume/util/volumehelper:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",

View File

@ -28,6 +28,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec" "k8s.io/utils/exec"
) )
@ -111,7 +112,7 @@ func (attacher *fcAttacher) MountDevice(spec *volume.Spec, devicePath string, de
options = append(options, "ro") options = append(options, "ro")
} }
if notMnt { if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Exec: attacher.host.GetExec(fcPluginName)}
mountOptions := volume.MountOptionFromSpec(spec, options...) mountOptions := volume.MountOptionFromSpec(spec, options...)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions) err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil { if err != nil {
@ -192,7 +193,7 @@ func volumeSpecToMounter(spec *volume.Spec, host volume.VolumeHost) (*fcDiskMoun
}, },
fsType: fc.FSType, fsType: fc.FSType,
readOnly: readOnly, readOnly: readOnly,
mounter: &mount.SafeFormatAndMount{Interface: host.GetMounter(fcPluginName), Runner: exec.New()}, mounter: volumehelper.NewSafeFormatAndMountFromHost(fcPluginName, host),
}, nil }, nil
} }

View File

@ -103,10 +103,10 @@ func (plugin *fcPlugin) GetAccessModes() []v1.PersistentVolumeAccessMode {
func (plugin *fcPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.Mounter, error) { func (plugin *fcPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.Mounter, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newMounterInternal(spec, pod.UID, &FCUtil{}, plugin.host.GetMounter(plugin.GetPluginName())) return plugin.newMounterInternal(spec, pod.UID, &FCUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
} }
func (plugin *fcPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Mounter, error) { func (plugin *fcPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec) (volume.Mounter, error) {
// fc volumes used directly in a pod have a ReadOnly flag set by the pod author. // fc volumes used directly in a pod have a ReadOnly flag set by the pod author.
// fc volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV // fc volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV
fc, readOnly, err := getVolumeSource(spec) fc, readOnly, err := getVolumeSource(spec)
@ -138,7 +138,7 @@ func (plugin *fcPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID,
plugin: plugin}, plugin: plugin},
fsType: fc.FSType, fsType: fc.FSType,
readOnly: readOnly, readOnly: readOnly,
mounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}, mounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: exec},
}, nil }, nil
} }

View File

@ -141,7 +141,8 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
fakeManager := NewFakeDiskManager() fakeManager := NewFakeDiskManager()
defer fakeManager.Cleanup() defer fakeManager.Cleanup()
fakeMounter := &mount.FakeMounter{} fakeMounter := &mount.FakeMounter{}
mounter, err := plug.(*fcPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter) fakeExec := mount.NewFakeExec(nil)
mounter, err := plug.(*fcPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter, fakeExec)
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)
} }
@ -210,7 +211,8 @@ func doTestPluginNilMounter(t *testing.T, spec *volume.Spec) {
fakeManager := NewFakeDiskManager() fakeManager := NewFakeDiskManager()
defer fakeManager.Cleanup() defer fakeManager.Cleanup()
fakeMounter := &mount.FakeMounter{} fakeMounter := &mount.FakeMounter{}
mounter, err := plug.(*fcPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter) fakeExec := mount.NewFakeExec(nil)
mounter, err := plug.(*fcPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter, fakeExec)
if err == nil { if err == nil {
t.Errorf("Error failed to make a new Mounter is expected: %v", err) t.Errorf("Error failed to make a new Mounter is expected: %v", err)
} }

View File

@ -24,7 +24,6 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/utils/exec"
) )
type attacherDefaults flexVolumeAttacher type attacherDefaults flexVolumeAttacher
@ -59,7 +58,7 @@ func (a *attacherDefaults) MountDevice(spec *volume.Spec, devicePath string, dev
options = append(options, "rw") options = append(options, "rw")
} }
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Exec: a.plugin.host.GetExec(a.plugin.GetPluginName())}
return diskMounter.FormatAndMount(devicePath, deviceMountPath, volSource.FSType, options) return diskMounter.FormatAndMount(devicePath, deviceMountPath, volSource.FSType, options)
} }

View File

@ -19,7 +19,6 @@ package flexvolume
import ( import (
"strconv" "strconv"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/utils/exec" "k8s.io/utils/exec"
) )
@ -29,9 +28,6 @@ type flexVolumeMounter struct {
*flexVolume *flexVolume
// Runner used to setup the volume. // Runner used to setup the volume.
runner exec.Interface runner exec.Interface
// blockDeviceMounter provides the interface to create filesystem if the
// filesystem doesn't exist.
blockDeviceMounter mount.Interface
// the considered volume spec // the considered volume spec
spec *volume.Spec spec *volume.Spec
readOnly bool readOnly bool

View File

@ -176,10 +176,9 @@ func (plugin *flexVolumePlugin) newMounterInternal(spec *volume.Spec, pod *api.P
podServiceAccountName: pod.Spec.ServiceAccountName, podServiceAccountName: pod.Spec.ServiceAccountName,
volName: spec.Name(), volName: spec.Name(),
}, },
runner: runner, runner: runner,
spec: spec, spec: spec,
readOnly: readOnly, readOnly: readOnly,
blockDeviceMounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: runner},
}, nil }, nil
} }

View File

@ -31,7 +31,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/utils/exec" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
) )
type gcePersistentDiskAttacher struct { type gcePersistentDiskAttacher struct {
@ -208,7 +208,7 @@ func (attacher *gcePersistentDiskAttacher) MountDevice(spec *volume.Spec, device
options = append(options, "ro") options = append(options, "ro")
} }
if notMnt { if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} diskMounter := volumehelper.NewSafeFormatAndMountFromHost(gcePersistentDiskPluginName, attacher.host)
mountOptions := volume.MountOptionFromSpec(spec, options...) mountOptions := volume.MountOptionFromSpec(spec, options...)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions) err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil { if err != nil {

View File

@ -112,10 +112,10 @@ func (plugin *iscsiPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volume.V
} }
} }
return plugin.newMounterInternal(spec, pod.UID, &ISCSIUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), secret) return plugin.newMounterInternal(spec, pod.UID, &ISCSIUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()), secret)
} }
func (plugin *iscsiPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, secret map[string]string) (volume.Mounter, error) { func (plugin *iscsiPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec, secret map[string]string) (volume.Mounter, error) {
// iscsi volumes used directly in a pod have a ReadOnly flag set by the pod author. // iscsi volumes used directly in a pod have a ReadOnly flag set by the pod author.
// iscsi volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV // iscsi volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV
iscsi, readOnly, err := getVolumeSource(spec) iscsi, readOnly, err := getVolumeSource(spec)
@ -147,7 +147,7 @@ func (plugin *iscsiPlugin) newMounterInternal(spec *volume.Spec, podUID types.UI
plugin: plugin}, plugin: plugin},
fsType: iscsi.FSType, fsType: iscsi.FSType,
readOnly: readOnly, readOnly: readOnly,
mounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}, mounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: exec},
deviceUtil: ioutil.NewDeviceHandler(ioutil.NewIOHandler()), deviceUtil: ioutil.NewDeviceHandler(ioutil.NewIOHandler()),
mountOptions: volume.MountOptionFromSpec(spec), mountOptions: volume.MountOptionFromSpec(spec),
}, nil }, nil
@ -155,10 +155,10 @@ func (plugin *iscsiPlugin) newMounterInternal(spec *volume.Spec, podUID types.UI
func (plugin *iscsiPlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) { func (plugin *iscsiPlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) {
// Inject real implementations here, test through the internal function. // Inject real implementations here, test through the internal function.
return plugin.newUnmounterInternal(volName, podUID, &ISCSIUtil{}, plugin.host.GetMounter(plugin.GetPluginName())) return plugin.newUnmounterInternal(volName, podUID, &ISCSIUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
} }
func (plugin *iscsiPlugin) newUnmounterInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Unmounter, error) { func (plugin *iscsiPlugin) newUnmounterInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface, exec mount.Exec) (volume.Unmounter, error) {
return &iscsiDiskUnmounter{ return &iscsiDiskUnmounter{
iscsiDisk: &iscsiDisk{ iscsiDisk: &iscsiDisk{
podUID: podUID, podUID: podUID,

View File

@ -141,7 +141,8 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
fakeManager := NewFakeDiskManager() fakeManager := NewFakeDiskManager()
defer fakeManager.Cleanup() defer fakeManager.Cleanup()
fakeMounter := &mount.FakeMounter{} fakeMounter := &mount.FakeMounter{}
mounter, err := plug.(*iscsiPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter, nil) fakeExec := mount.NewFakeExec(nil)
mounter, err := plug.(*iscsiPlugin).newMounterInternal(spec, types.UID("poduid"), fakeManager, fakeMounter, fakeExec, nil)
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)
} }
@ -178,7 +179,7 @@ func doTestPlugin(t *testing.T, spec *volume.Spec) {
fakeManager2 := NewFakeDiskManager() fakeManager2 := NewFakeDiskManager()
defer fakeManager2.Cleanup() defer fakeManager2.Cleanup()
unmounter, err := plug.(*iscsiPlugin).newUnmounterInternal("vol1", types.UID("poduid"), fakeManager2, fakeMounter) unmounter, err := plug.(*iscsiPlugin).newUnmounterInternal("vol1", types.UID("poduid"), fakeManager2, fakeMounter, fakeExec)
if err != nil { if err != nil {
t.Errorf("Failed to make a new Unmounter: %v", err) t.Errorf("Failed to make a new Unmounter: %v", err)
} }

View File

@ -26,7 +26,6 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
], ],
) )

View File

@ -30,7 +30,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/utils/exec" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
) )
type photonPersistentDiskAttacher struct { type photonPersistentDiskAttacher struct {
@ -209,7 +209,7 @@ func (attacher *photonPersistentDiskAttacher) MountDevice(spec *volume.Spec, dev
options := []string{} options := []string{}
if notMnt { if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} diskMounter := volumehelper.NewSafeFormatAndMountFromHost(photonPersistentDiskPluginName, attacher.host)
mountOptions := volume.MountOptionFromSpec(spec) mountOptions := volume.MountOptionFromSpec(spec)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions) err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil { if err != nil {

View File

@ -31,7 +31,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumehelper" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec"
) )
// This is the primary entrypoint for volume plugins. // This is the primary entrypoint for volume plugins.
@ -116,7 +115,7 @@ func (plugin *photonPersistentDiskPlugin) newMounterInternal(spec *volume.Spec,
plugin: plugin, plugin: plugin,
}, },
fsType: fsType, fsType: fsType,
diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}}, nil diskMounter: volumehelper.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host)}, nil
} }
func (plugin *photonPersistentDiskPlugin) newUnmounterInternal(volName string, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Unmounter, error) { func (plugin *photonPersistentDiskPlugin) newUnmounterInternal(volName string, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Unmounter, error) {

View File

@ -43,7 +43,6 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
], ],
) )

View File

@ -29,7 +29,6 @@ import (
kstrings "k8s.io/kubernetes/pkg/util/strings" kstrings "k8s.io/kubernetes/pkg/util/strings"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/volumehelper" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec"
) )
// This is the primary entrypoint for volume plugins. // This is the primary entrypoint for volume plugins.
@ -115,7 +114,7 @@ func (plugin *portworxVolumePlugin) newMounterInternal(spec *volume.Spec, podUID
}, },
fsType: fsType, fsType: fsType,
readOnly: readOnly, readOnly: readOnly,
diskMounter: &mount.SafeFormatAndMount{Interface: plugin.host.GetMounter(plugin.GetPluginName()), Runner: exec.New()}}, nil diskMounter: volumehelper.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host)}, nil
} }
func (plugin *portworxVolumePlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) { func (plugin *portworxVolumePlugin) NewUnmounter(volName string, podUID types.UID) (volume.Unmounter, error) {

View File

@ -158,7 +158,7 @@ func (plugin *rbdPlugin) newMounterInternal(spec *volume.Spec, podUID types.UID,
Pool: pool, Pool: pool,
ReadOnly: readOnly, ReadOnly: readOnly,
manager: manager, manager: manager,
mounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}, mounter: volumehelper.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host),
plugin: plugin, plugin: plugin,
MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, spec.Name(), plugin.host)), MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, spec.Name(), plugin.host)),
}, },
@ -183,7 +183,7 @@ func (plugin *rbdPlugin) newUnmounterInternal(volName string, podUID types.UID,
podUID: podUID, podUID: podUID,
volName: volName, volName: volName,
manager: manager, manager: manager,
mounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}, mounter: volumehelper.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host),
plugin: plugin, plugin: plugin,
MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, volName, plugin.host)), MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, volName, plugin.host)),
}, },

View File

@ -52,7 +52,6 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
], ],
) )

View File

@ -34,7 +34,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumehelper" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec"
) )
type sioVolume struct { type sioVolume struct {
@ -143,10 +142,7 @@ func (v *sioVolume) SetUpAt(dir string, fsGroup *int64) error {
} }
glog.V(4).Info(log("setup created mount point directory %s", dir)) glog.V(4).Info(log("setup created mount point directory %s", dir))
diskMounter := &mount.SafeFormatAndMount{ diskMounter := volumehelper.NewSafeFormatAndMountFromHost(v.plugin.GetPluginName(), v.plugin.host)
Interface: v.plugin.mounter,
Runner: exec.New(),
}
err = diskMounter.FormatAndMount(devicePath, dir, v.fsType, options) err = diskMounter.FormatAndMount(devicePath, dir, v.fsType, options)
if err != nil { if err != nil {

View File

@ -36,7 +36,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumehelper" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec"
) )
// ProbeVolumePlugins is the primary entrypoint for volume plugins. // ProbeVolumePlugins is the primary entrypoint for volume plugins.
@ -137,7 +136,7 @@ func (plugin *storageosPlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod
MetricsProvider: volume.NewMetricsStatFS(getPath(pod.UID, volNamespace, volName, spec.Name(), plugin.host)), MetricsProvider: volume.NewMetricsStatFS(getPath(pod.UID, volNamespace, volName, spec.Name(), plugin.host)),
}, },
devicePath: storageosDevicePath, devicePath: storageosDevicePath,
diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}, diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: plugin.host.GetExec(plugin.GetPluginName())},
}, nil }, nil
} }

View File

@ -9,6 +9,7 @@ go_library(
name = "go_default_library", name = "go_default_library",
srcs = ["volumehelper.go"], srcs = ["volumehelper.go"],
deps = [ deps = [
"//pkg/util/mount:go_default_library",
"//pkg/volume:go_default_library", "//pkg/volume:go_default_library",
"//pkg/volume/util/types:go_default_library", "//pkg/volume/util/types:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library",

View File

@ -23,6 +23,7 @@ import (
"strings" "strings"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/kubernetes/pkg/volume/util/types"
) )
@ -127,3 +128,11 @@ func SplitUniqueName(uniqueName v1.UniqueVolumeName) (string, string, error) {
pluginName := fmt.Sprintf("%s/%s", components[0], components[1]) pluginName := fmt.Sprintf("%s/%s", components[0], components[1])
return pluginName, components[2], nil return pluginName, components[2], nil
} }
// NewSafeFormatAndMountFromHost creates a new SafeFormatAndMount with Mounter
// and Exec taken from given VolumeHost.
func NewSafeFormatAndMountFromHost(pluginName string, host volume.VolumeHost) *mount.SafeFormatAndMount {
mounter := host.GetMounter(pluginName)
exec := host.GetExec(pluginName)
return &mount.SafeFormatAndMount{Interface: mounter, Exec: exec}
}

View File

@ -28,7 +28,6 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",
], ],
) )

View File

@ -29,7 +29,7 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/utils/exec" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
) )
type vsphereVMDKAttacher struct { type vsphereVMDKAttacher struct {
@ -195,7 +195,7 @@ func (attacher *vsphereVMDKAttacher) MountDevice(spec *volume.Spec, devicePath s
options := []string{} options := []string{}
if notMnt { if notMnt {
diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()} diskMounter := volumehelper.NewSafeFormatAndMountFromHost(vsphereVolumePluginName, attacher.host)
mountOptions := volume.MountOptionFromSpec(spec, options...) mountOptions := volume.MountOptionFromSpec(spec, options...)
err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions) err = diskMounter.FormatAndMount(devicePath, deviceMountPath, volumeSource.FSType, mountOptions)
if err != nil { if err != nil {

View File

@ -32,7 +32,6 @@ import (
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/util" "k8s.io/kubernetes/pkg/volume/util"
"k8s.io/kubernetes/pkg/volume/util/volumehelper" "k8s.io/kubernetes/pkg/volume/util/volumehelper"
"k8s.io/utils/exec"
) )
// This is the primary entrypoint for volume plugins. // This is the primary entrypoint for volume plugins.
@ -116,7 +115,7 @@ func (plugin *vsphereVolumePlugin) newMounterInternal(spec *volume.Spec, podUID
plugin: plugin, plugin: plugin,
}, },
fsType: fsType, fsType: fsType,
diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Runner: exec.New()}}, nil diskMounter: volumehelper.NewSafeFormatAndMountFromHost(plugin.GetPluginName(), plugin.host)}, nil
} }
func (plugin *vsphereVolumePlugin) newUnmounterInternal(volName string, podUID types.UID, manager vdManager, mounter mount.Interface) (volume.Unmounter, error) { func (plugin *vsphereVolumePlugin) newUnmounterInternal(volName string, podUID types.UID, manager vdManager, mounter mount.Interface) (volume.Unmounter, error) {