StorageOS: Use VolumeHost.GetExec() to execute stuff in volume plugins

pull/6/head
Jan Safranek 2017-08-22 15:57:08 +02:00
parent 07dea6b447
commit bf296b3e31
4 changed files with 23 additions and 24 deletions

View File

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

View File

@ -110,10 +110,10 @@ func (plugin *storageosPlugin) NewMounter(spec *volume.Spec, pod *v1.Pod, _ volu
return nil, err
}
return plugin.newMounterInternal(spec, pod, apiCfg, &storageosUtil{}, plugin.host.GetMounter(plugin.GetPluginName()))
return plugin.newMounterInternal(spec, pod, apiCfg, &storageosUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
}
func (plugin *storageosPlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod, apiCfg *storageosAPIConfig, manager storageosManager, mounter mount.Interface) (volume.Mounter, error) {
func (plugin *storageosPlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod, apiCfg *storageosAPIConfig, manager storageosManager, mounter mount.Interface, exec mount.Exec) (volume.Mounter, error) {
volName, volNamespace, fsType, readOnly, err := getVolumeInfoFromSpec(spec)
if err != nil {
@ -132,19 +132,20 @@ func (plugin *storageosPlugin) newMounterInternal(spec *volume.Spec, pod *v1.Pod
apiCfg: apiCfg,
manager: manager,
mounter: mounter,
exec: exec,
plugin: plugin,
MetricsProvider: volume.NewMetricsStatFS(getPath(pod.UID, volNamespace, volName, spec.Name(), plugin.host)),
},
devicePath: storageosDevicePath,
diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: plugin.host.GetExec(plugin.GetPluginName())},
diskMounter: &mount.SafeFormatAndMount{Interface: mounter, Exec: exec},
}, nil
}
func (plugin *storageosPlugin) NewUnmounter(pvName string, podUID types.UID) (volume.Unmounter, error) {
return plugin.newUnmounterInternal(pvName, podUID, &storageosUtil{}, plugin.host.GetMounter(plugin.GetPluginName()))
return plugin.newUnmounterInternal(pvName, podUID, &storageosUtil{}, plugin.host.GetMounter(plugin.GetPluginName()), plugin.host.GetExec(plugin.GetPluginName()))
}
func (plugin *storageosPlugin) newUnmounterInternal(pvName string, podUID types.UID, manager storageosManager, mounter mount.Interface) (volume.Unmounter, error) {
func (plugin *storageosPlugin) newUnmounterInternal(pvName string, podUID types.UID, manager storageosManager, mounter mount.Interface, exec mount.Exec) (volume.Unmounter, error) {
// Parse volume namespace & name from mountpoint if mounted
volNamespace, volName, err := getVolumeInfo(pvName, podUID, plugin.host)
@ -160,6 +161,7 @@ func (plugin *storageosPlugin) newUnmounterInternal(pvName string, podUID types.
volNamespace: volNamespace,
manager: manager,
mounter: mounter,
exec: exec,
plugin: plugin,
MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, volNamespace, volName, pvName, plugin.host)),
},
@ -303,6 +305,7 @@ type storageos struct {
apiCfg *storageosAPIConfig
manager storageosManager
mounter mount.Interface
exec mount.Exec
plugin *storageosPlugin
volume.MetricsProvider
}

View File

@ -184,7 +184,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Couldn't get secret from %v/%v", pod.Namespace, secretName)
}
mounter, err := plug.(*storageosPlugin).newMounterInternal(volume.NewSpecFromVolume(spec), pod, apiCfg, fakeManager, &mount.FakeMounter{})
mounter, err := plug.(*storageosPlugin).newMounterInternal(volume.NewSpecFromVolume(spec), pod, apiCfg, fakeManager, &mount.FakeMounter{}, mount.NewFakeExec(nil))
if err != nil {
t.Fatalf("Failed to make a new Mounter: %v", err)
}
@ -218,7 +218,7 @@ func TestPlugin(t *testing.T) {
// Test Unmounter
fakeManager = &fakePDManager{}
unmounter, err := plug.(*storageosPlugin).newUnmounterInternal("vol1-pvname", types.UID("poduid"), fakeManager, &mount.FakeMounter{})
unmounter, err := plug.(*storageosPlugin).newUnmounterInternal("vol1-pvname", types.UID("poduid"), fakeManager, &mount.FakeMounter{}, mount.NewFakeExec(nil))
if err != nil {
t.Errorf("Failed to make a new Unmounter: %v", err)
}
@ -362,7 +362,7 @@ func TestPersistentClaimReadOnlyFlag(t *testing.T) {
fakeManager := &fakePDManager{}
fakeConfig := &fakeConfig{}
apiCfg := fakeConfig.GetAPIConfig()
mounter, err := plug.(*storageosPlugin).newMounterInternal(spec, pod, apiCfg, fakeManager, &mount.FakeMounter{})
mounter, err := plug.(*storageosPlugin).newMounterInternal(spec, pod, apiCfg, fakeManager, &mount.FakeMounter{}, mount.NewFakeExec(nil))
if !mounter.GetAttributes().ReadOnly {
t.Errorf("Expected true for mounter.IsReadOnly")

View File

@ -23,7 +23,7 @@ import (
"path"
"strings"
"k8s.io/utils/exec"
"k8s.io/kubernetes/pkg/util/mount"
"github.com/golang/glog"
storageosapi "github.com/storageos/go-api"
@ -177,7 +177,7 @@ func (u *storageosUtil) AttachVolume(b *storageosMounter) (string, error) {
case modeBlock:
return srcPath, nil
case modeFile:
return attachFileDevice(srcPath)
return attachFileDevice(srcPath, b.exec)
default:
return "", fmt.Errorf(ErrDeviceNotSupported)
}
@ -192,7 +192,7 @@ func (u *storageosUtil) DetachVolume(b *storageosUnmounter, devicePath string) e
if _, err := os.Stat(devicePath); os.IsNotExist(err) {
return nil
}
return removeLoopDevice(devicePath)
return removeLoopDevice(devicePath, b.exec)
}
// Mount mounts the volume on the host.
@ -295,8 +295,8 @@ func pathDeviceType(path string) (deviceType, error) {
// attachFileDevice takes a path to a regular file and makes it available as an
// attached block device.
func attachFileDevice(path string) (string, error) {
blockDevicePath, err := getLoopDevice(path)
func attachFileDevice(path string, exec mount.Exec) (string, error) {
blockDevicePath, err := getLoopDevice(path, exec)
if err != nil && err.Error() != ErrDeviceNotFound {
return "", err
}
@ -304,7 +304,7 @@ func attachFileDevice(path string) (string, error) {
// If no existing loop device for the path, create one
if blockDevicePath == "" {
glog.V(4).Infof("Creating device for path: %s", path)
blockDevicePath, err = makeLoopDevice(path)
blockDevicePath, err = makeLoopDevice(path, exec)
if err != nil {
return "", err
}
@ -313,7 +313,7 @@ func attachFileDevice(path string) (string, error) {
}
// Returns the full path to the loop device associated with the given path.
func getLoopDevice(path string) (string, error) {
func getLoopDevice(path string, exec mount.Exec) (string, error) {
_, err := os.Stat(path)
if os.IsNotExist(err) {
return "", errors.New(ErrNotAvailable)
@ -322,9 +322,8 @@ func getLoopDevice(path string) (string, error) {
return "", fmt.Errorf("not attachable: %v", err)
}
exec := exec.New()
args := []string{"-j", path}
out, err := exec.Command(losetupPath, args...).CombinedOutput()
out, err := exec.Run(losetupPath, args...)
if err != nil {
glog.V(2).Infof("Failed device discover command for path %s: %v", path, err)
return "", err
@ -332,10 +331,9 @@ func getLoopDevice(path string) (string, error) {
return parseLosetupOutputForDevice(out)
}
func makeLoopDevice(path string) (string, error) {
exec := exec.New()
func makeLoopDevice(path string, exec mount.Exec) (string, error) {
args := []string{"-f", "--show", path}
out, err := exec.Command(losetupPath, args...).CombinedOutput()
out, err := exec.Run(losetupPath, args...)
if err != nil {
glog.V(2).Infof("Failed device create command for path %s: %v", path, err)
return "", err
@ -343,10 +341,9 @@ func makeLoopDevice(path string) (string, error) {
return parseLosetupOutputForDevice(out)
}
func removeLoopDevice(device string) error {
exec := exec.New()
func removeLoopDevice(device string, exec mount.Exec) error {
args := []string{"-d", device}
out, err := exec.Command(losetupPath, args...).CombinedOutput()
out, err := exec.Run(losetupPath, args...)
if err != nil {
if !strings.Contains(string(out), "No such device or address") {
return err