Inject mounter into volume plugins

This commit is contained in:
Paul Morie
2015-05-04 10:43:10 -04:00
parent 72f9e940a8
commit b538642464
22 changed files with 109 additions and 87 deletions

View File

@@ -68,9 +68,9 @@ func (plugin *awsElasticBlockStorePlugin) GetAccessModes() []api.AccessModeType
}
}
func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
// Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, podRef.UID, &AWSDiskUtil{}, mount.New())
return plugin.newBuilderInternal(spec, podRef.UID, &AWSDiskUtil{}, mounter)
}
func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) {
@@ -103,9 +103,9 @@ func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec,
}, nil
}
func (plugin *awsElasticBlockStorePlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
func (plugin *awsElasticBlockStorePlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, &AWSDiskUtil{}, mount.New())
return plugin.newCleanerInternal(volName, podUID, &AWSDiskUtil{}, mounter)
}
func (plugin *awsElasticBlockStorePlugin) newCleanerInternal(volName string, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Cleaner, error) {

View File

@@ -30,21 +30,14 @@ import (
// This is the primary entrypoint for volume plugins.
func ProbeVolumePlugins() []volume.VolumePlugin {
return ProbeVolumePluginsWithMounter(mount.New())
}
// ProbePluginsWithMounter is a convenience for testing other plugins which wrap this one.
//FIXME: alternative: pass mount.Interface to all ProbeVolumePlugins() functions? Opinions?
func ProbeVolumePluginsWithMounter(mounter mount.Interface) []volume.VolumePlugin {
return []volume.VolumePlugin{
&emptyDirPlugin{nil, mounter, false},
&emptyDirPlugin{nil, mounter, true},
&emptyDirPlugin{nil, false},
&emptyDirPlugin{nil, true},
}
}
type emptyDirPlugin struct {
host volume.VolumeHost
mounter mount.Interface
legacyMode bool // if set, plugin answers to the legacy name
}
@@ -78,9 +71,8 @@ func (plugin *emptyDirPlugin) CanSupport(spec *volume.Spec) bool {
return false
}
func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
// Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, podRef, plugin.mounter, &realMountDetector{plugin.mounter}, opts)
func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, podRef, mounter, &realMountDetector{mounter}, opts)
}
func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, podRef *api.ObjectReference, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions) (volume.Builder, error) {
@@ -104,9 +96,9 @@ func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, podRef *api.
}, nil
}
func (plugin *emptyDirPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
func (plugin *emptyDirPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, plugin.mounter, &realMountDetector{plugin.mounter})
return plugin.newCleanerInternal(volName, podUID, mounter, &realMountDetector{mounter})
}
func (plugin *emptyDirPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface, mountDetector mountDetector) (volume.Cleaner, error) {

View File

@@ -1,3 +1,5 @@
// +build linux
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
@@ -21,6 +23,7 @@ import (
"syscall"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
"github.com/golang/glog"
)
// Defined by Linux - the type number for tmpfs mounts.
@@ -32,6 +35,7 @@ type realMountDetector struct {
}
func (m *realMountDetector) GetMountMedium(path string) (storageMedium, bool, error) {
glog.V(5).Infof("Determining mount medium of %v", path)
isMnt, err := m.mounter.IsMountPoint(path)
if err != nil {
return 0, false, fmt.Errorf("IsMountPoint(%q): %v", path, err)
@@ -40,6 +44,8 @@ func (m *realMountDetector) GetMountMedium(path string) (storageMedium, bool, er
if err := syscall.Statfs(path, &buf); err != nil {
return 0, false, fmt.Errorf("statfs(%q): %v", path, err)
}
glog.V(5).Info("Statfs_t of %v: %+v", path, buf)
if buf.Type == linuxTmpfsMagic {
return mediumMemory, isMnt, nil
}

View File

@@ -197,7 +197,7 @@ func TestPluginBackCompat(t *testing.T) {
spec := &api.Volume{
Name: "vol1",
}
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""})
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}, nil)
if err != nil {
t.Errorf("Failed to make a new Builder: %v", err)
}

View File

@@ -75,9 +75,9 @@ func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.AccessModeType {
}
}
func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
// Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, podRef.UID, &GCEDiskUtil{}, mount.New())
return plugin.newBuilderInternal(spec, podRef.UID, &GCEDiskUtil{}, mounter)
}
func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) {
@@ -116,9 +116,9 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod
}, nil
}
func (plugin *gcePersistentDiskPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
func (plugin *gcePersistentDiskPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, &GCEDiskUtil{}, mount.New())
return plugin.newCleanerInternal(volName, podUID, &GCEDiskUtil{}, mounter)
}
func (plugin *gcePersistentDiskPlugin) newCleanerInternal(volName string, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Cleaner, error) {

View File

@@ -186,11 +186,11 @@ func TestPluginLegacy(t *testing.T) {
}
spec := &api.Volume{VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}
if _, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}); err == nil {
if _, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}, nil); err == nil {
t.Errorf("Expected failiure")
}
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"))
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), nil)
if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err)
}

View File

@@ -25,6 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
volumeutil "github.com/GoogleCloudPlatform/kubernetes/pkg/volume/util"
)
@@ -66,7 +67,7 @@ func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.GitRepo != nil
}
func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
if plugin.legacyMode {
// Legacy mode instances can be cleaned up but not created anew.
return nil, fmt.Errorf("legacy mode: can not create new instances")
@@ -80,10 +81,11 @@ func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectRef
plugin: plugin,
legacyMode: false,
opts: opts,
mounter: mounter,
}, nil
}
func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
legacy := false
if plugin.legacyMode {
legacy = true
@@ -93,6 +95,7 @@ func (plugin *gitRepoPlugin) NewCleaner(volName string, podUID types.UID) (volum
volName: volName,
plugin: plugin,
legacyMode: legacy,
mounter: mounter,
}, nil
}
@@ -107,6 +110,7 @@ type gitRepo struct {
plugin *gitRepoPlugin
legacyMode bool
opts volume.VolumeOptions
mounter mount.Interface
}
// SetUp creates new directory and clones a git repo.
@@ -130,7 +134,7 @@ func (gr *gitRepo) SetUpAt(dir string) error {
}
// Wrap EmptyDir, let it do the setup.
wrapped, err := gr.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &gr.podRef, gr.opts)
wrapped, err := gr.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &gr.podRef, gr.opts, gr.mounter)
if err != nil {
return err
}
@@ -193,7 +197,7 @@ func (gr *gitRepo) TearDown() error {
// TearDownAt simply deletes everything in the directory.
func (gr *gitRepo) TearDownAt(dir string) error {
// Wrap EmptyDir, let it do the teardown.
wrapped, err := gr.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, gr.podRef.UID)
wrapped, err := gr.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, gr.podRef.UID, gr.mounter)
if err != nil {
return err
}

View File

@@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/exec"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume/empty_dir"
)
@@ -118,7 +119,7 @@ func TestPlugin(t *testing.T) {
},
},
}
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""})
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}, mount.New())
if err != nil {
t.Errorf("Failed to make a new Builder: %v", err)
}
@@ -140,7 +141,7 @@ func TestPlugin(t *testing.T) {
}
}
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"))
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), mount.New())
if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err)
}
@@ -174,11 +175,11 @@ func TestPluginLegacy(t *testing.T) {
}
spec := &api.Volume{VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}
if _, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}); err == nil {
if _, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}, nil); err == nil {
t.Errorf("Expected failiure")
}
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"))
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), nil)
if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err)
}

View File

@@ -64,7 +64,7 @@ func (plugin *glusterfsPlugin) GetAccessModes() []api.AccessModeType {
}
}
func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
ep_name := spec.VolumeSource.Glusterfs.EndpointsName
ns := podRef.Namespace
ep, err := plugin.host.GetKubeClient().Endpoints(ns).Get(ep_name)
@@ -73,7 +73,7 @@ func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectR
return nil, err
}
glog.V(1).Infof("Glusterfs: endpoints %v", ep)
return plugin.newBuilderInternal(spec, ep, podRef, mount.New(), exec.New())
return plugin.newBuilderInternal(spec, ep, podRef, mounter, exec.New())
}
func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.Endpoints, podRef *api.ObjectReference, mounter mount.Interface, exe exec.Interface) (volume.Builder, error) {
@@ -89,8 +89,8 @@ func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.End
}, nil
}
func (plugin *glusterfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mount.New())
func (plugin *glusterfsPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mounter)
}
func (plugin *glusterfsPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {

View File

@@ -21,6 +21,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
)
@@ -57,7 +58,7 @@ func (plugin *hostPathPlugin) GetAccessModes() []api.AccessModeType {
}
}
func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions, _ mount.Interface) (volume.Builder, error) {
if spec.VolumeSource.HostPath != nil {
return &hostPath{spec.VolumeSource.HostPath.Path}, nil
} else {
@@ -65,7 +66,7 @@ func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectRe
}
}
func (plugin *hostPathPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
func (plugin *hostPathPlugin) NewCleaner(volName string, podUID types.UID, _ mount.Interface) (volume.Cleaner, error) {
return &hostPath{""}, nil
}

View File

@@ -68,7 +68,7 @@ func TestPlugin(t *testing.T) {
Name: "vol1",
VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{"/vol1"}},
}
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{})
builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{}, nil)
if err != nil {
t.Errorf("Failed to make a new Builder: %v", err)
}
@@ -85,7 +85,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Expected success, got: %v", err)
}
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"))
cleaner, err := plug.NewCleaner("vol1", types.UID("poduid"), nil)
if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err)
}

View File

@@ -72,9 +72,9 @@ func (plugin *ISCSIPlugin) GetAccessModes() []api.AccessModeType {
}
}
func (plugin *ISCSIPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
func (plugin *ISCSIPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
// Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, podRef.UID, &ISCSIUtil{}, mount.New())
return plugin.newBuilderInternal(spec, podRef.UID, &ISCSIUtil{}, mounter)
}
func (plugin *ISCSIPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Builder, error) {
@@ -95,9 +95,9 @@ func (plugin *ISCSIPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UI
}, nil
}
func (plugin *ISCSIPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
func (plugin *ISCSIPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
// Inject real implementations here, test through the internal function.
return plugin.newCleanerInternal(volName, podUID, &ISCSIUtil{}, mount.New())
return plugin.newCleanerInternal(volName, podUID, &ISCSIUtil{}, mounter)
}
func (plugin *ISCSIPlugin) newCleanerInternal(volName string, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Cleaner, error) {

View File

@@ -64,7 +64,7 @@ func (plugin *nfsPlugin) GetAccessModes() []api.AccessModeType {
}
}
func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions, _ mount.Interface) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, podRef, plugin.mounter)
}
@@ -80,7 +80,7 @@ func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, podRef *api.Objec
}, nil
}
func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
func (plugin *nfsPlugin) NewCleaner(volName string, podUID types.UID, _ mount.Interface) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, plugin.mounter)
}

View File

@@ -20,6 +20,7 @@ import (
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
"github.com/golang/glog"
)
@@ -50,7 +51,7 @@ func (plugin *persistentClaimPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.PersistentVolumeClaimVolumeSource != nil
}
func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
claim, err := plugin.host.GetKubeClient().PersistentVolumeClaims(podRef.Namespace).Get(spec.VolumeSource.PersistentVolumeClaimVolumeSource.ClaimName)
if err != nil {
glog.Errorf("Error finding claim: %+v\n", spec.VolumeSource.PersistentVolumeClaimVolumeSource.ClaimName)
@@ -67,7 +68,7 @@ func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, podRef *api.O
return nil, err
}
builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv), podRef, opts)
builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv), podRef, opts, mounter)
if err != nil {
glog.Errorf("Error creating builder for claim: %+v\n", claim.Name)
return nil, err
@@ -76,6 +77,6 @@ func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, podRef *api.O
return builder, nil
}
func (plugin *persistentClaimPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
func (plugin *persistentClaimPlugin) NewCleaner(_ string, _ types.UID, _ mount.Interface) (volume.Cleaner, error) {
return nil, fmt.Errorf("This will never be called directly. The PV backing this claim has a cleaner. Kubelet uses that cleaner, not this one, when removing orphaned volumes.")
}

View File

@@ -169,7 +169,7 @@ func TestNewBuilder(t *testing.T) {
Name: "vol1",
VolumeSource: item.podVolume,
}
builder, err := plug.NewBuilder(spec, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{})
builder, err := plug.NewBuilder(spec, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{}, nil)
if err != nil {
t.Errorf("Failed to make a new Builder: %v", err)
}
@@ -229,7 +229,7 @@ func TestNewBuilderClaimNotBound(t *testing.T) {
Name: "vol1",
VolumeSource: podVolume,
}
builder, err := plug.NewBuilder(spec, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{})
builder, err := plug.NewBuilder(spec, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{}, nil)
if builder != nil {
t.Errorf("Expected a nil builder if the claim wasn't bound")
}

View File

@@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
"github.com/golang/glog"
)
@@ -62,12 +63,12 @@ type VolumePlugin interface {
// Ownership of the spec pointer in *not* transferred.
// - spec: The api.Volume spec
// - podRef: a reference to the enclosing pod
NewBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error)
NewBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions, mounter mount.Interface) (Builder, error)
// NewCleaner creates a new volume.Cleaner from recoverable state.
// - name: The volume name, as per the api.Volume spec.
// - podUID: The UID of the enclosing pod
NewCleaner(name string, podUID types.UID) (Cleaner, error)
NewCleaner(name string, podUID types.UID, mounter mount.Interface) (Cleaner, error)
}
// PersistentVolumePlugin is an extended interface of VolumePlugin and is used
@@ -105,12 +106,12 @@ type VolumeHost interface {
// the provided spec. This is used to implement volume plugins which
// "wrap" other plugins. For example, the "secret" volume is
// implemented in terms of the "emptyDir" volume.
NewWrapperBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error)
NewWrapperBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions, mounter mount.Interface) (Builder, error)
// NewWrapperCleaner finds an appropriate plugin with which to handle
// the provided spec. See comments on NewWrapperBuilder for more
// context.
NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error)
NewWrapperCleaner(spec *Spec, podUID types.UID, mounter mount.Interface) (Cleaner, error)
}
// VolumePluginMgr tracks registered plugins.

View File

@@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
"github.com/GoogleCloudPlatform/kubernetes/pkg/volume"
volumeutil "github.com/GoogleCloudPlatform/kubernetes/pkg/volume/util"
"github.com/golang/glog"
@@ -55,20 +56,20 @@ func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.Secret != nil
}
func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, podRef, opts)
func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, podRef, opts, mounter)
}
func (plugin *secretPlugin) newBuilderInternal(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
return &secretVolume{spec.Name, *podRef, plugin, spec.VolumeSource.Secret.SecretName, &opts}, nil
func (plugin *secretPlugin) newBuilderInternal(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
return &secretVolume{spec.Name, *podRef, plugin, spec.VolumeSource.Secret.SecretName, &opts, mounter}, nil
}
func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID)
func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return plugin.newCleanerInternal(volName, podUID, mounter)
}
func (plugin *secretPlugin) newCleanerInternal(volName string, podUID types.UID) (volume.Cleaner, error) {
return &secretVolume{volName, api.ObjectReference{UID: podUID}, plugin, "", nil}, nil
func (plugin *secretPlugin) newCleanerInternal(volName string, podUID types.UID, mounter mount.Interface) (volume.Cleaner, error) {
return &secretVolume{volName, api.ObjectReference{UID: podUID}, plugin, "", nil, mounter}, nil
}
// secretVolume handles retrieving secrets from the API server
@@ -79,6 +80,7 @@ type secretVolume struct {
plugin *secretPlugin
secretName string
opts *volume.VolumeOptions
mounter mount.Interface
}
func (sv *secretVolume) SetUp() error {
@@ -99,7 +101,7 @@ func (sv *secretVolume) SetUpAt(dir string) error {
glog.V(3).Infof("Setting up volume %v for pod %v at %v", sv.volName, sv.podRef.UID, dir)
// Wrap EmptyDir, let it do the setup.
wrapped, err := sv.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &sv.podRef, *sv.opts)
wrapped, err := sv.plugin.host.NewWrapperBuilder(wrappedVolumeSpec, &sv.podRef, *sv.opts, sv.mounter)
if err != nil {
return err
}
@@ -161,7 +163,7 @@ func (sv *secretVolume) TearDownAt(dir string) error {
glog.V(3).Infof("Tearing down volume %v for pod %v at %v", sv.volName, sv.podRef.UID, dir)
// Wrap EmptyDir, let it do the teardown.
wrapped, err := sv.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, sv.podRef.UID)
wrapped, err := sv.plugin.host.NewWrapperCleaner(wrappedVolumeSpec, sv.podRef.UID, sv.mounter)
if err != nil {
return err
}

View File

@@ -39,7 +39,7 @@ func newTestHost(t *testing.T, client client.Interface) volume.VolumeHost {
t.Fatalf("can't make a temp rootdir: %v", err)
}
return volume.NewFakeVolumeHost(tempDir, client, empty_dir.ProbeVolumePluginsWithMounter(&mount.FakeMounter{}))
return volume.NewFakeVolumeHost(tempDir, client, empty_dir.ProbeVolumePlugins())
}
func TestCanSupport(t *testing.T) {
@@ -97,7 +97,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Can't find the plugin by name")
}
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), &api.ObjectReference{UID: types.UID(testPodUID)}, volume.VolumeOptions{})
builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), &api.ObjectReference{UID: types.UID(testPodUID)}, volume.VolumeOptions{}, &mount.FakeMounter{})
if err != nil {
t.Errorf("Failed to make a new Builder: %v", err)
}
@@ -139,7 +139,7 @@ func TestPlugin(t *testing.T) {
}
}
cleaner, err := plugin.NewCleaner(testVolumeName, types.UID(testPodUID))
cleaner, err := plugin.NewCleaner(testVolumeName, types.UID(testPodUID), mount.New())
if err != nil {
t.Errorf("Failed to make a new Cleaner: %v", err)
}

View File

@@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/types"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/mount"
)
// fakeVolumeHost is useful for testing volume plugins.
@@ -55,20 +56,20 @@ func (f *fakeVolumeHost) GetKubeClient() client.Interface {
return f.kubeClient
}
func (f *fakeVolumeHost) NewWrapperBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error) {
func (f *fakeVolumeHost) NewWrapperBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions, mounter mount.Interface) (Builder, error) {
plug, err := f.pluginMgr.FindPluginBySpec(spec)
if err != nil {
return nil, err
}
return plug.NewBuilder(spec, podRef, opts)
return plug.NewBuilder(spec, podRef, opts, mounter)
}
func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error) {
func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID, mounter mount.Interface) (Cleaner, error) {
plug, err := f.pluginMgr.FindPluginBySpec(spec)
if err != nil {
return nil, err
}
return plug.NewCleaner(spec.Name, podUID)
return plug.NewCleaner(spec.Name, podUID, mounter)
}
// FakeVolumePlugin is useful for testing. It tries to be a fully compliant
@@ -95,11 +96,11 @@ func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool {
return true
}
func (plugin *FakeVolumePlugin) NewBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error) {
func (plugin *FakeVolumePlugin) NewBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions, mounter mount.Interface) (Builder, error) {
return &FakeVolume{podRef.UID, spec.Name, plugin}, nil
}
func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID) (Cleaner, error) {
func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (Cleaner, error) {
return &FakeVolume{podUID, volName, plugin}, nil
}