Merge pull request #6809 from markturansky/pv_union

Refactor Volumes to use InternalVolume instead of API types
This commit is contained in:
Dawn Chen 2015-04-14 11:56:49 -07:00
commit f471ca8e0c
22 changed files with 200 additions and 127 deletions

View File

@ -54,7 +54,7 @@ func (vh *volumeHost) GetKubeClient() client.Interface {
return vh.kubelet.kubeClient return vh.kubelet.kubeClient
} }
func (vh *volumeHost) NewWrapperBuilder(spec *api.Volume, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) { func (vh *volumeHost) NewWrapperBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, podRef, opts) b, err := vh.kubelet.newVolumeBuilderFromPlugins(spec, podRef, opts)
if err == nil && b == nil { if err == nil && b == nil {
return nil, errUnsupportedVolumeType return nil, errUnsupportedVolumeType
@ -62,7 +62,7 @@ func (vh *volumeHost) NewWrapperBuilder(spec *api.Volume, podRef *api.ObjectRefe
return b, nil return b, nil
} }
func (vh *volumeHost) NewWrapperCleaner(spec *api.Volume, podUID types.UID) (volume.Cleaner, error) { func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID) (volume.Cleaner, error) {
plugin, err := vh.kubelet.volumePluginMgr.FindPluginBySpec(spec) plugin, err := vh.kubelet.volumePluginMgr.FindPluginBySpec(spec)
if err != nil { if err != nil {
return nil, err return nil, err
@ -78,7 +78,7 @@ func (vh *volumeHost) NewWrapperCleaner(spec *api.Volume, podUID types.UID) (vol
return c, nil return c, nil
} }
func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *api.Volume, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) { func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
plugin, err := kl.volumePluginMgr.FindPluginBySpec(spec) plugin, err := kl.volumePluginMgr.FindPluginBySpec(spec)
if err != nil { if err != nil {
return nil, fmt.Errorf("can't use volume plugins for %s: %v", spew.Sprintf("%#v", *spec), err) return nil, fmt.Errorf("can't use volume plugins for %s: %v", spew.Sprintf("%#v", *spec), err)
@ -112,7 +112,8 @@ func (kl *Kubelet) mountExternalVolumes(pod *api.Pod) (volumeMap, error) {
} }
// Try to use a plugin for this volume. // Try to use a plugin for this volume.
builder, err := kl.newVolumeBuilderFromPlugins(volSpec, podRef, volume.VolumeOptions{rootContext}) internal := volume.NewSpecFromVolume(volSpec)
builder, err := kl.newVolumeBuilderFromPlugins(internal, podRef, volume.VolumeOptions{rootContext})
if err != nil { if err != nil {
glog.Errorf("Could not create volume builder for pod %s: %v", pod.UID, err) glog.Errorf("Could not create volume builder for pod %s: %v", pod.UID, err)
return nil, err return nil, err

View File

@ -58,11 +58,8 @@ func (plugin *awsElasticBlockStorePlugin) Name() string {
return awsElasticBlockStorePluginName return awsElasticBlockStorePluginName
} }
func (plugin *awsElasticBlockStorePlugin) CanSupport(spec *api.Volume) bool { func (plugin *awsElasticBlockStorePlugin) CanSupport(spec *volume.Spec) bool {
if spec.AWSElasticBlockStore != nil { return spec.PersistentVolumeSource.AWSElasticBlockStore != nil || spec.VolumeSource.AWSElasticBlockStore != nil
return true
}
return false
} }
func (plugin *awsElasticBlockStorePlugin) GetAccessModes() []api.AccessModeType { func (plugin *awsElasticBlockStorePlugin) GetAccessModes() []api.AccessModeType {
@ -71,19 +68,26 @@ func (plugin *awsElasticBlockStorePlugin) GetAccessModes() []api.AccessModeType
} }
} }
func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) { func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
// Inject real implementations here, test through the internal function. // 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{}, mount.New())
} }
func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *api.Volume, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) { func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) {
volumeID := spec.AWSElasticBlockStore.VolumeID var ebs *api.AWSElasticBlockStoreVolumeSource
fsType := spec.AWSElasticBlockStore.FSType if spec.VolumeSource.AWSElasticBlockStore != nil {
partition := "" ebs = spec.VolumeSource.AWSElasticBlockStore
if spec.AWSElasticBlockStore.Partition != 0 { } else {
partition = strconv.Itoa(spec.AWSElasticBlockStore.Partition) ebs = spec.PersistentVolumeSource.AWSElasticBlockStore
} }
readOnly := spec.AWSElasticBlockStore.ReadOnly
volumeID := ebs.VolumeID
fsType := ebs.FSType
partition := ""
if ebs.Partition != 0 {
partition = strconv.Itoa(ebs.Partition)
}
readOnly := ebs.ReadOnly
return &awsElasticBlockStore{ return &awsElasticBlockStore{
podUID: podUID, podUID: podUID,

View File

@ -37,7 +37,7 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/aws-ebs" { if plug.Name() != "kubernetes.io/aws-ebs" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }
@ -106,7 +106,7 @@ func TestPlugin(t *testing.T) {
}, },
}, },
} }
builder, err := plug.(*awsElasticBlockStorePlugin).newBuilderInternal(spec, types.UID("poduid"), &fakePDManager{}, &mount.FakeMounter{}) builder, err := plug.(*awsElasticBlockStorePlugin).newBuilderInternal(volume.NewSpecFromVolume(spec), types.UID("poduid"), &fakePDManager{}, &mount.FakeMounter{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }

View File

@ -66,34 +66,31 @@ func (plugin *emptyDirPlugin) Name() string {
return emptyDirPluginName return emptyDirPluginName
} }
func (plugin *emptyDirPlugin) CanSupport(spec *api.Volume) bool { func (plugin *emptyDirPlugin) CanSupport(spec *volume.Spec) bool {
if plugin.legacyMode { if plugin.legacyMode {
// Legacy mode instances can be cleaned up but not created anew. // Legacy mode instances can be cleaned up but not created anew.
return false return false
} }
if util.AllPtrFieldsNil(&spec.VolumeSource) { if spec.VolumeSource.EmptyDir != nil {
return true
}
if spec.EmptyDir != nil {
return true return true
} }
return false return false
} }
func (plugin *emptyDirPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) { 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. // Inject real implementations here, test through the internal function.
return plugin.newBuilderInternal(spec, podRef, plugin.mounter, &realMountDetector{plugin.mounter}, opts) return plugin.newBuilderInternal(spec, podRef, plugin.mounter, &realMountDetector{plugin.mounter}, opts)
} }
func (plugin *emptyDirPlugin) newBuilderInternal(spec *api.Volume, podRef *api.ObjectReference, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions) (volume.Builder, error) { func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, podRef *api.ObjectReference, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions) (volume.Builder, error) {
if plugin.legacyMode { if plugin.legacyMode {
// Legacy mode instances can be cleaned up but not created anew. // Legacy mode instances can be cleaned up but not created anew.
return nil, fmt.Errorf("legacy mode: can not create new instances") return nil, fmt.Errorf("legacy mode: can not create new instances")
} }
medium := api.StorageTypeDefault medium := api.StorageTypeDefault
if spec.EmptyDir != nil { // Support a non-specified source as EmptyDir. if spec.VolumeSource.EmptyDir != nil { // Support a non-specified source as EmptyDir.
medium = spec.EmptyDir.Medium medium = spec.VolumeSource.EmptyDir.Medium
} }
return &emptyDir{ return &emptyDir{
podUID: podRef.UID, podUID: podRef.UID,

View File

@ -48,11 +48,11 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/empty-dir" { if plug.Name() != "kubernetes.io/empty-dir" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if !plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) {
t.Errorf("Expected true") t.Errorf("Expected false")
} }
} }
@ -74,7 +74,7 @@ func TestPlugin(t *testing.T) {
} }
mounter := mount.FakeMounter{} mounter := mount.FakeMounter{}
mountDetector := fakeMountDetector{} mountDetector := fakeMountDetector{}
builder, err := plug.(*emptyDirPlugin).newBuilderInternal(spec, &api.ObjectReference{UID: types.UID("poduid")}, &mounter, &mountDetector, volume.VolumeOptions{""}) builder, err := plug.(*emptyDirPlugin).newBuilderInternal(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, &mounter, &mountDetector, volume.VolumeOptions{""})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -133,7 +133,7 @@ func TestPluginTmpfs(t *testing.T) {
} }
mounter := mount.FakeMounter{} mounter := mount.FakeMounter{}
mountDetector := fakeMountDetector{} mountDetector := fakeMountDetector{}
builder, err := plug.(*emptyDirPlugin).newBuilderInternal(spec, &api.ObjectReference{UID: types.UID("poduid")}, &mounter, &mountDetector, volume.VolumeOptions{""}) builder, err := plug.(*emptyDirPlugin).newBuilderInternal(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, &mounter, &mountDetector, volume.VolumeOptions{""})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -197,7 +197,7 @@ func TestPluginBackCompat(t *testing.T) {
spec := &api.Volume{ spec := &api.Volume{
Name: "vol1", Name: "vol1",
} }
builder, err := plug.NewBuilder(spec, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}) builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -217,12 +217,12 @@ func TestPluginLegacy(t *testing.T) {
if plug.Name() != "empty" { if plug.Name() != "empty" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}) { if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
spec := api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}} spec := api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}
if _, err := plug.(*emptyDirPlugin).newBuilderInternal(&spec, &api.ObjectReference{UID: types.UID("poduid")}, &mount.FakeMounter{}, &fakeMountDetector{}, volume.VolumeOptions{""}); err == nil { if _, err := plug.(*emptyDirPlugin).newBuilderInternal(volume.NewSpecFromVolume(&spec), &api.ObjectReference{UID: types.UID("poduid")}, &mount.FakeMounter{}, &fakeMountDetector{}, volume.VolumeOptions{""}); err == nil {
t.Errorf("Expected failiure") t.Errorf("Expected failiure")
} }

View File

@ -59,16 +59,13 @@ func (plugin *gcePersistentDiskPlugin) Name() string {
return gcePersistentDiskPluginName return gcePersistentDiskPluginName
} }
func (plugin *gcePersistentDiskPlugin) CanSupport(spec *api.Volume) bool { func (plugin *gcePersistentDiskPlugin) CanSupport(spec *volume.Spec) bool {
if plugin.legacyMode { if plugin.legacyMode {
// Legacy mode instances can be cleaned up but not created anew. // Legacy mode instances can be cleaned up but not created anew.
return false return false
} }
if spec.GCEPersistentDisk != nil { return spec.VolumeSource.GCEPersistentDisk != nil || spec.PersistentVolumeSource.GCEPersistentDisk != nil
return true
}
return false
} }
func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.AccessModeType { func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.AccessModeType {
@ -78,24 +75,31 @@ func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.AccessModeType {
} }
} }
func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) { func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
// Inject real implementations here, test through the internal function. // 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{}, mount.New())
} }
func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *api.Volume, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) { func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) {
if plugin.legacyMode { if plugin.legacyMode {
// Legacy mode instances can be cleaned up but not created anew. // Legacy mode instances can be cleaned up but not created anew.
return nil, fmt.Errorf("legacy mode: can not create new instances") return nil, fmt.Errorf("legacy mode: can not create new instances")
} }
pdName := spec.GCEPersistentDisk.PDName var gce *api.GCEPersistentDiskVolumeSource
fsType := spec.GCEPersistentDisk.FSType if spec.VolumeSource.GCEPersistentDisk != nil {
partition := "" gce = spec.VolumeSource.GCEPersistentDisk
if spec.GCEPersistentDisk.Partition != 0 { } else {
partition = strconv.Itoa(spec.GCEPersistentDisk.Partition) gce = spec.PersistentVolumeSource.GCEPersistentDisk
} }
readOnly := spec.GCEPersistentDisk.ReadOnly
pdName := gce.PDName
fsType := gce.FSType
partition := ""
if gce.Partition != 0 {
partition = strconv.Itoa(gce.Partition)
}
readOnly := gce.ReadOnly
return &gcePersistentDisk{ return &gcePersistentDisk{
podUID: podUID, podUID: podUID,

View File

@ -37,7 +37,7 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/gce-pd" { if plug.Name() != "kubernetes.io/gce-pd" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }
@ -113,7 +113,7 @@ func TestPlugin(t *testing.T) {
} }
fakeManager := &fakePDManager{} fakeManager := &fakePDManager{}
fakeMounter := &mount.FakeMounter{} fakeMounter := &mount.FakeMounter{}
builder, err := plug.(*gcePersistentDiskPlugin).newBuilderInternal(spec, types.UID("poduid"), fakeManager, fakeMounter) builder, err := plug.(*gcePersistentDiskPlugin).newBuilderInternal(volume.NewSpecFromVolume(spec), types.UID("poduid"), fakeManager, fakeMounter)
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -181,11 +181,12 @@ func TestPluginLegacy(t *testing.T) {
if plug.Name() != "gce-pd" { if plug.Name() != "gce-pd" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}) { if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
if _, err := plug.NewBuilder(&api.Volume{VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}); err == nil { 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 {
t.Errorf("Expected failiure") t.Errorf("Expected failiure")
} }

View File

@ -58,19 +58,16 @@ func (plugin *gitRepoPlugin) Name() string {
return gitRepoPluginName return gitRepoPluginName
} }
func (plugin *gitRepoPlugin) CanSupport(spec *api.Volume) bool { func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool {
if plugin.legacyMode { if plugin.legacyMode {
// Legacy mode instances can be cleaned up but not created anew. // Legacy mode instances can be cleaned up but not created anew.
return false return false
} }
if spec.GitRepo != nil { return spec.VolumeSource.GitRepo != nil
return true
}
return false
} }
func (plugin *gitRepoPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) { func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
if plugin.legacyMode { if plugin.legacyMode {
// Legacy mode instances can be cleaned up but not created anew. // Legacy mode instances can be cleaned up but not created anew.
return nil, fmt.Errorf("legacy mode: can not create new instances") return nil, fmt.Errorf("legacy mode: can not create new instances")
@ -78,8 +75,8 @@ func (plugin *gitRepoPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectRefe
return &gitRepo{ return &gitRepo{
podRef: *podRef, podRef: *podRef,
volName: spec.Name, volName: spec.Name,
source: spec.GitRepo.Repository, source: spec.VolumeSource.GitRepo.Repository,
revision: spec.GitRepo.Revision, revision: spec.VolumeSource.GitRepo.Revision,
exec: exec.New(), exec: exec.New(),
plugin: plugin, plugin: plugin,
legacyMode: false, legacyMode: false,
@ -119,7 +116,7 @@ func (gr *gitRepo) SetUp() error {
} }
// This is the spec for the volume that this plugin wraps. // This is the spec for the volume that this plugin wraps.
var wrappedVolumeSpec = &api.Volume{ var wrappedVolumeSpec = &volume.Spec{
Name: "not-used", Name: "not-used",
VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}},
} }

View File

@ -50,7 +50,7 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/git-repo" { if plug.Name() != "kubernetes.io/git-repo" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }
@ -118,7 +118,7 @@ func TestPlugin(t *testing.T) {
}, },
}, },
} }
builder, err := plug.NewBuilder(spec, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}) builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }
@ -169,11 +169,12 @@ func TestPluginLegacy(t *testing.T) {
if plug.Name() != "git" { if plug.Name() != "git" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}) { if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
if _, err := plug.NewBuilder(&api.Volume{VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{""}); err == nil { 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 {
t.Errorf("Expected failiure") t.Errorf("Expected failiure")
} }

View File

@ -53,11 +53,8 @@ func (plugin *glusterfsPlugin) Name() string {
return glusterfsPluginName return glusterfsPluginName
} }
func (plugin *glusterfsPlugin) CanSupport(spec *api.Volume) bool { func (plugin *glusterfsPlugin) CanSupport(spec *volume.Spec) bool {
if spec.VolumeSource.Glusterfs != nil { return spec.VolumeSource.Glusterfs != nil || spec.PersistentVolumeSource.Glusterfs != nil
return true
}
return false
} }
func (plugin *glusterfsPlugin) GetAccessModes() []api.AccessModeType { func (plugin *glusterfsPlugin) GetAccessModes() []api.AccessModeType {
@ -68,7 +65,7 @@ func (plugin *glusterfsPlugin) GetAccessModes() []api.AccessModeType {
} }
} }
func (plugin *glusterfsPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) { func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
ep_name := spec.VolumeSource.Glusterfs.EndpointsName ep_name := spec.VolumeSource.Glusterfs.EndpointsName
ns := api.NamespaceDefault ns := api.NamespaceDefault
ep, err := plugin.host.GetKubeClient().Endpoints(ns).Get(ep_name) ep, err := plugin.host.GetKubeClient().Endpoints(ns).Get(ep_name)
@ -80,7 +77,7 @@ func (plugin *glusterfsPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectRe
return plugin.newBuilderInternal(spec, ep, podRef, mount.New(), exec.New()) return plugin.newBuilderInternal(spec, ep, podRef, mount.New(), exec.New())
} }
func (plugin *glusterfsPlugin) newBuilderInternal(spec *api.Volume, ep *api.Endpoints, podRef *api.ObjectReference, mounter mount.Interface, exe exec.Interface) (volume.Builder, error) { func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.Endpoints, podRef *api.ObjectReference, mounter mount.Interface, exe exec.Interface) (volume.Builder, error) {
return &glusterfs{ return &glusterfs{
volName: spec.Name, volName: spec.Name,
hosts: ep, hosts: ep,

View File

@ -37,10 +37,10 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/glusterfs" { if plug.Name() != "kubernetes.io/glusterfs" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }
@ -94,7 +94,7 @@ func TestPlugin(t *testing.T) {
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) }, func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
}, },
} }
builder, err := plug.(*glusterfsPlugin).newBuilderInternal(spec, ep, &api.ObjectReference{UID: types.UID("poduid")}, &mount.FakeMounter{}, &fake) builder, err := plug.(*glusterfsPlugin).newBuilderInternal(volume.NewSpecFromVolume(spec), ep, &api.ObjectReference{UID: types.UID("poduid")}, &mount.FakeMounter{}, &fake)
volumePath := builder.GetPath() volumePath := builder.GetPath()
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)

View File

@ -47,11 +47,8 @@ func (plugin *hostPathPlugin) Name() string {
return hostPathPluginName return hostPathPluginName
} }
func (plugin *hostPathPlugin) CanSupport(spec *api.Volume) bool { func (plugin *hostPathPlugin) CanSupport(spec *volume.Spec) bool {
if spec.HostPath != nil { return spec.VolumeSource.HostPath != nil || spec.PersistentVolumeSource.HostPath != nil
return true
}
return false
} }
func (plugin *hostPathPlugin) GetAccessModes() []api.AccessModeType { func (plugin *hostPathPlugin) GetAccessModes() []api.AccessModeType {
@ -60,8 +57,12 @@ func (plugin *hostPathPlugin) GetAccessModes() []api.AccessModeType {
} }
} }
func (plugin *hostPathPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) { func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
return &hostPath{spec.HostPath.Path}, nil if spec.VolumeSource.HostPath != nil {
return &hostPath{spec.VolumeSource.HostPath.Path}, nil
} else {
return &hostPath{spec.PersistentVolumeSource.HostPath.Path}, nil
}
} }
func (plugin *hostPathPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { func (plugin *hostPathPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {

View File

@ -35,10 +35,10 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/host-path" { if plug.Name() != "kubernetes.io/host-path" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }
@ -68,7 +68,7 @@ func TestPlugin(t *testing.T) {
Name: "vol1", Name: "vol1",
VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{"/vol1"}}, VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{"/vol1"}},
} }
builder, err := plug.NewBuilder(spec, &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{}) builder, err := plug.NewBuilder(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }

View File

@ -52,8 +52,8 @@ func (plugin *ISCSIPlugin) Name() string {
return ISCSIPluginName return ISCSIPluginName
} }
func (plugin *ISCSIPlugin) CanSupport(spec *api.Volume) bool { func (plugin *ISCSIPlugin) CanSupport(spec *volume.Spec) bool {
if spec.ISCSI == nil { if spec.VolumeSource.ISCSI == nil {
return false return false
} }
// see if iscsiadm is there // see if iscsiadm is there
@ -72,22 +72,23 @@ func (plugin *ISCSIPlugin) GetAccessModes() []api.AccessModeType {
} }
} }
func (plugin *ISCSIPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) { func (plugin *ISCSIPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
// Inject real implementations here, test through the internal function. // 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{}, mount.New())
} }
func (plugin *ISCSIPlugin) newBuilderInternal(spec *api.Volume, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Builder, error) { func (plugin *ISCSIPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Builder, error) {
lun := strconv.Itoa(spec.ISCSI.Lun) iscsi := spec.VolumeSource.ISCSI
lun := strconv.Itoa(iscsi.Lun)
return &iscsiDisk{ return &iscsiDisk{
podUID: podUID, podUID: podUID,
volName: spec.Name, volName: spec.Name,
portal: spec.ISCSI.TargetPortal, portal: iscsi.TargetPortal,
iqn: spec.ISCSI.IQN, iqn: iscsi.IQN,
lun: lun, lun: lun,
fsType: spec.ISCSI.FSType, fsType: iscsi.FSType,
readOnly: spec.ISCSI.ReadOnly, readOnly: iscsi.ReadOnly,
manager: manager, manager: manager,
mounter: mounter, mounter: mounter,
plugin: plugin, plugin: plugin,

View File

@ -81,7 +81,7 @@ func TestPlugin(t *testing.T) {
}, },
}, },
} }
builder, err := plug.(*ISCSIPlugin).newBuilderInternal(spec, types.UID("poduid"), &fakeDiskManager{}, &mount.FakeMounter{}) builder, err := plug.(*ISCSIPlugin).newBuilderInternal(volume.NewSpecFromVolume(spec), types.UID("poduid"), &fakeDiskManager{}, &mount.FakeMounter{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }

View File

@ -50,11 +50,8 @@ func (plugin *nfsPlugin) Name() string {
return nfsPluginName return nfsPluginName
} }
func (plugin *nfsPlugin) CanSupport(spec *api.Volume) bool { func (plugin *nfsPlugin) CanSupport(spec *volume.Spec) bool {
if spec.VolumeSource.NFS != nil { return spec.VolumeSource.NFS != nil
return true
}
return false
} }
func (plugin *nfsPlugin) GetAccessModes() []api.AccessModeType { func (plugin *nfsPlugin) GetAccessModes() []api.AccessModeType {
@ -65,11 +62,11 @@ func (plugin *nfsPlugin) GetAccessModes() []api.AccessModeType {
} }
} }
func (plugin *nfsPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) { func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, _ volume.VolumeOptions) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, podRef, plugin.mounter) return plugin.newBuilderInternal(spec, podRef, plugin.mounter)
} }
func (plugin *nfsPlugin) newBuilderInternal(spec *api.Volume, podRef *api.ObjectReference, mounter nfsMountInterface) (volume.Builder, error) { func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, podRef *api.ObjectReference, mounter nfsMountInterface) (volume.Builder, error) {
return &nfs{ return &nfs{
volName: spec.Name, volName: spec.Name,
server: spec.VolumeSource.NFS.Server, server: spec.VolumeSource.NFS.Server,

View File

@ -37,10 +37,10 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/nfs" { if plug.Name() != "kubernetes.io/nfs" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{NFS: &api.NFSVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{NFS: &api.NFSVolumeSource{}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plug.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }
@ -108,7 +108,7 @@ func TestPlugin(t *testing.T) {
VolumeSource: api.VolumeSource{NFS: &api.NFSVolumeSource{"localhost", "/tmp", false}}, VolumeSource: api.VolumeSource{NFS: &api.NFSVolumeSource{"localhost", "/tmp", false}},
} }
fake := &fakeNFSMounter{} fake := &fakeNFSMounter{}
builder, err := plug.(*nfsPlugin).newBuilderInternal(spec, &api.ObjectReference{UID: types.UID("poduid")}, fake) builder, err := plug.(*nfsPlugin).newBuilderInternal(volume.NewSpecFromVolume(spec), &api.ObjectReference{UID: types.UID("poduid")}, fake)
volumePath := builder.GetPath() volumePath := builder.GetPath()
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)

View File

@ -56,13 +56,13 @@ type VolumePlugin interface {
// CanSupport tests whether the plugin supports a given volume // CanSupport tests whether the plugin supports a given volume
// specification from the API. The spec pointer should be considered // specification from the API. The spec pointer should be considered
// const. // const.
CanSupport(spec *api.Volume) bool CanSupport(spec *Spec) bool
// NewBuilder creates a new volume.Builder from an API specification. // NewBuilder creates a new volume.Builder from an API specification.
// Ownership of the spec pointer in *not* transferred. // Ownership of the spec pointer in *not* transferred.
// - spec: The api.Volume spec // - spec: The api.Volume spec
// - podRef: a reference to the enclosing pod // - podRef: a reference to the enclosing pod
NewBuilder(spec *api.Volume, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error) NewBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error)
// NewCleaner creates a new volume.Cleaner from recoverable state. // NewCleaner creates a new volume.Cleaner from recoverable state.
// - name: The volume name, as per the api.Volume spec. // - name: The volume name, as per the api.Volume spec.
@ -105,12 +105,12 @@ type VolumeHost interface {
// the provided spec. This is used to implement volume plugins which // the provided spec. This is used to implement volume plugins which
// "wrap" other plugins. For example, the "secret" volume is // "wrap" other plugins. For example, the "secret" volume is
// implemented in terms of the "emptyDir" volume. // implemented in terms of the "emptyDir" volume.
NewWrapperBuilder(spec *api.Volume, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error) NewWrapperBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error)
// NewWrapperCleaner finds an appropriate plugin with which to handle // NewWrapperCleaner finds an appropriate plugin with which to handle
// the provided spec. See comments on NewWrapperBuilder for more // the provided spec. See comments on NewWrapperBuilder for more
// context. // context.
NewWrapperCleaner(spec *api.Volume, podUID types.UID) (Cleaner, error) NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error)
} }
// VolumePluginMgr tracks registered plugins. // VolumePluginMgr tracks registered plugins.
@ -119,6 +119,29 @@ type VolumePluginMgr struct {
plugins map[string]VolumePlugin plugins map[string]VolumePlugin
} }
// Spec is an internal representation of a volume. All API volume types translate to Spec.
type Spec struct {
Name string
VolumeSource api.VolumeSource
PersistentVolumeSource api.PersistentVolumeSource
}
// NewSpecFromVolume creates an Spec from an api.Volume
func NewSpecFromVolume(vs *api.Volume) *Spec {
return &Spec{
Name: vs.Name,
VolumeSource: vs.VolumeSource,
}
}
// NewSpecFromPersistentVolume creates an Spec from an api.PersistentVolume
func NewSpecFromPersistentVolume(pv *api.PersistentVolume) *Spec {
return &Spec{
Name: pv.Name,
PersistentVolumeSource: pv.Spec.PersistentVolumeSource,
}
}
// InitPlugins initializes each plugin. All plugins must have unique names. // InitPlugins initializes each plugin. All plugins must have unique names.
// This must be called exactly once before any New* methods are called on any // This must be called exactly once before any New* methods are called on any
// plugins. // plugins.
@ -152,7 +175,7 @@ func (pm *VolumePluginMgr) InitPlugins(plugins []VolumePlugin, host VolumeHost)
// FindPluginBySpec looks for a plugin that can support a given volume // FindPluginBySpec looks for a plugin that can support a given volume
// specification. If no plugins can support or more than one plugin can // specification. If no plugins can support or more than one plugin can
// support it, return error. // support it, return error.
func (pm *VolumePluginMgr) FindPluginBySpec(spec *api.Volume) (VolumePlugin, error) { func (pm *VolumePluginMgr) FindPluginBySpec(spec *Spec) (VolumePlugin, error) {
pm.mutex.Lock() pm.mutex.Lock()
defer pm.mutex.Unlock() defer pm.mutex.Unlock()

View File

@ -0,0 +1,53 @@
/*
Copyright 2015 Google Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package volume
import (
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
)
func TestSpecSourceConverters(t *testing.T) {
v := &api.Volume{
Name: "foo",
VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}},
}
converted := NewSpecFromVolume(v)
if converted.VolumeSource.EmptyDir == nil {
t.Errorf("Unexpected nil EmptyDir: %+v", converted)
}
if v.Name != converted.Name {
t.Errorf("Expected %v but got %v", v.Name, converted.Name)
}
pv := &api.PersistentVolume{
ObjectMeta: api.ObjectMeta{Name: "bar"},
Spec: api.PersistentVolumeSpec{
PersistentVolumeSource: api.PersistentVolumeSource{AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{}},
},
}
converted = NewSpecFromPersistentVolume(pv)
if converted.PersistentVolumeSource.AWSElasticBlockStore == nil {
t.Errorf("Unexpected nil AWSElasticBlockStore: %+v", converted)
}
if pv.Name != converted.Name {
t.Errorf("Expected %v but got %v", pv.Name, converted.Name)
}
}

View File

@ -50,20 +50,16 @@ func (plugin *secretPlugin) Name() string {
return secretPluginName return secretPluginName
} }
func (plugin *secretPlugin) CanSupport(spec *api.Volume) bool { func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool {
if spec.Secret != nil { return spec.VolumeSource.Secret != nil
return true
}
return false
} }
func (plugin *secretPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) { func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
return plugin.newBuilderInternal(spec, podRef, opts) return plugin.newBuilderInternal(spec, podRef, opts)
} }
func (plugin *secretPlugin) newBuilderInternal(spec *api.Volume, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) { func (plugin *secretPlugin) newBuilderInternal(spec *volume.Spec, podRef *api.ObjectReference, opts volume.VolumeOptions) (volume.Builder, error) {
return &secretVolume{spec.Name, *podRef, plugin, spec.Secret.SecretName, &opts}, nil return &secretVolume{spec.Name, *podRef, plugin, spec.VolumeSource.Secret.SecretName, &opts}, nil
} }
func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) { func (plugin *secretPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
@ -89,7 +85,7 @@ func (sv *secretVolume) SetUp() error {
} }
// This is the spec for the volume that this plugin wraps. // This is the spec for the volume that this plugin wraps.
var wrappedVolumeSpec = &api.Volume{ var wrappedVolumeSpec = &volume.Spec{
Name: "not-used", Name: "not-used",
VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageTypeMemory}}, VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageTypeMemory}},
} }

View File

@ -53,7 +53,7 @@ func TestCanSupport(t *testing.T) {
if plugin.Name() != secretPluginName { if plugin.Name() != secretPluginName {
t.Errorf("Wrong name: %s", plugin.Name()) t.Errorf("Wrong name: %s", plugin.Name())
} }
if !plugin.CanSupport(&api.Volume{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: ""}}}) { if !plugin.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: ""}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }
@ -97,7 +97,7 @@ func TestPlugin(t *testing.T) {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
builder, err := plugin.NewBuilder(volumeSpec, &api.ObjectReference{UID: types.UID(testPodUID)}, volume.VolumeOptions{}) builder, err := plugin.NewBuilder(volume.NewSpecFromVolume(volumeSpec), &api.ObjectReference{UID: types.UID(testPodUID)}, volume.VolumeOptions{})
if err != nil { if err != nil {
t.Errorf("Failed to make a new Builder: %v", err) t.Errorf("Failed to make a new Builder: %v", err)
} }

View File

@ -55,7 +55,7 @@ func (f *fakeVolumeHost) GetKubeClient() client.Interface {
return f.kubeClient return f.kubeClient
} }
func (f *fakeVolumeHost) NewWrapperBuilder(spec *api.Volume, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error) { func (f *fakeVolumeHost) NewWrapperBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error) {
plug, err := f.pluginMgr.FindPluginBySpec(spec) plug, err := f.pluginMgr.FindPluginBySpec(spec)
if err != nil { if err != nil {
return nil, err return nil, err
@ -63,7 +63,7 @@ func (f *fakeVolumeHost) NewWrapperBuilder(spec *api.Volume, podRef *api.ObjectR
return plug.NewBuilder(spec, podRef, opts) return plug.NewBuilder(spec, podRef, opts)
} }
func (f *fakeVolumeHost) NewWrapperCleaner(spec *api.Volume, podUID types.UID) (Cleaner, error) { func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID) (Cleaner, error) {
plug, err := f.pluginMgr.FindPluginBySpec(spec) plug, err := f.pluginMgr.FindPluginBySpec(spec)
if err != nil { if err != nil {
return nil, err return nil, err
@ -90,12 +90,12 @@ func (plugin *FakeVolumePlugin) Name() string {
return plugin.PluginName return plugin.PluginName
} }
func (plugin *FakeVolumePlugin) CanSupport(spec *api.Volume) bool { func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool {
// TODO: maybe pattern-match on spec.Name to decide? // TODO: maybe pattern-match on spec.Name to decide?
return true return true
} }
func (plugin *FakeVolumePlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error) { func (plugin *FakeVolumePlugin) NewBuilder(spec *Spec, podRef *api.ObjectReference, opts VolumeOptions) (Builder, error) {
return &FakeVolume{podRef.UID, spec.Name, plugin}, nil return &FakeVolume{podRef.UID, spec.Name, plugin}, nil
} }