expand volume.Spec to include full Volume and PV

pull/6/head
markturansky 2015-08-12 15:11:03 -04:00
parent b6f2f396ba
commit 0e7f73ad67
32 changed files with 148 additions and 142 deletions

View File

@ -390,7 +390,7 @@ func (c *mockBinderClient) UpdatePersistentVolumeClaimStatus(claim *api.Persiste
func newMockRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) { func newMockRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) {
return &mockRecycler{ return &mockRecycler{
path: spec.PersistentVolumeSource.HostPath.Path, path: spec.PersistentVolume.Spec.HostPath.Path,
}, nil }, nil
} }

View File

@ -73,7 +73,7 @@ func (vh *volumeHost) NewWrapperCleaner(spec *volume.Spec, podUID types.UID, mou
// Not found but not an error // Not found but not an error
return nil, nil return nil, nil
} }
c, err := plugin.NewCleaner(spec.Name, podUID, mounter) c, err := plugin.NewCleaner(spec.Name(), podUID, mounter)
if err == nil && c == nil { if err == nil && c == nil {
return nil, errUnsupportedVolumeType return nil, errUnsupportedVolumeType
} }
@ -87,7 +87,7 @@ func (vh *volumeHost) GetCloudProvider() cloudprovider.Interface {
func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (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", spec.Name, err) return nil, fmt.Errorf("can't use volume plugins for %s: %v", spec.Name(), err)
} }
if plugin == nil { if plugin == nil {
// Not found but not an error // Not found but not an error
@ -95,9 +95,9 @@ func (kl *Kubelet) newVolumeBuilderFromPlugins(spec *volume.Spec, pod *api.Pod,
} }
builder, err := plugin.NewBuilder(spec, pod, opts, mounter) builder, err := plugin.NewBuilder(spec, pod, opts, mounter)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to instantiate volume plugin for %s: %v", spec.Name, err) return nil, fmt.Errorf("failed to instantiate volume plugin for %s: %v", spec.Name(), err)
} }
glog.V(3).Infof("Used volume plugin %q for %s", plugin.Name(), spec.Name) glog.V(3).Infof("Used volume plugin %q for %s", plugin.Name(), spec.Name())
return builder, nil return builder, nil
} }

View File

@ -60,7 +60,8 @@ func (plugin *awsElasticBlockStorePlugin) Name() string {
} }
func (plugin *awsElasticBlockStorePlugin) CanSupport(spec *volume.Spec) bool { func (plugin *awsElasticBlockStorePlugin) CanSupport(spec *volume.Spec) bool {
return spec.PersistentVolumeSource.AWSElasticBlockStore != nil || spec.VolumeSource.AWSElasticBlockStore != nil return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.AWSElasticBlockStore != nil) ||
(spec.Volume != nil && spec.Volume.AWSElasticBlockStore != nil)
} }
func (plugin *awsElasticBlockStorePlugin) GetAccessModes() []api.PersistentVolumeAccessMode { func (plugin *awsElasticBlockStorePlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
@ -79,11 +80,11 @@ func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec,
// EBSs used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV // EBSs used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV
var readOnly bool var readOnly bool
var ebs *api.AWSElasticBlockStoreVolumeSource var ebs *api.AWSElasticBlockStoreVolumeSource
if spec.VolumeSource.AWSElasticBlockStore != nil { if spec.Volume != nil && spec.Volume.AWSElasticBlockStore != nil {
ebs = spec.VolumeSource.AWSElasticBlockStore ebs = spec.Volume.AWSElasticBlockStore
readOnly = ebs.ReadOnly readOnly = ebs.ReadOnly
} else { } else {
ebs = spec.PersistentVolumeSource.AWSElasticBlockStore ebs = spec.PersistentVolume.Spec.AWSElasticBlockStore
readOnly = spec.ReadOnly readOnly = spec.ReadOnly
} }
@ -97,7 +98,7 @@ func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec,
return &awsElasticBlockStoreBuilder{ return &awsElasticBlockStoreBuilder{
awsElasticBlockStore: &awsElasticBlockStore{ awsElasticBlockStore: &awsElasticBlockStore{
podUID: podUID, podUID: podUID,
volName: spec.Name, volName: spec.Name(),
volumeID: volumeID, volumeID: volumeID,
manager: manager, manager: manager,
mounter: mounter, mounter: mounter,

View File

@ -39,10 +39,10 @@ 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(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if !plug.CanSupport(&volume.Spec{Name: "foo", PersistentVolumeSource: api.PersistentVolumeSource{AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{AWSElasticBlockStore: &api.AWSElasticBlockStoreVolumeSource{}}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }

View File

@ -52,7 +52,7 @@ func (plugin *cephfsPlugin) Name() string {
} }
func (plugin *cephfsPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *cephfsPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.CephFS != nil || spec.PersistentVolumeSource.CephFS != nil return (spec.Volume != nil && spec.Volume.CephFS != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.CephFS != nil)
} }
func (plugin *cephfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { func (plugin *cephfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
@ -99,7 +99,7 @@ func (plugin *cephfsPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U
return &cephfsBuilder{ return &cephfsBuilder{
cephfs: &cephfs{ cephfs: &cephfs{
podUID: podUID, podUID: podUID,
volName: spec.Name, volName: spec.Name(),
mon: cephvs.Monitors, mon: cephvs.Monitors,
secret: secret, secret: secret,
id: id, id: id,
@ -125,10 +125,10 @@ func (plugin *cephfsPlugin) newCleanerInternal(volName string, podUID types.UID,
} }
func (plugin *cephfsPlugin) getVolumeSource(spec *volume.Spec) *api.CephFSVolumeSource { func (plugin *cephfsPlugin) getVolumeSource(spec *volume.Spec) *api.CephFSVolumeSource {
if spec.VolumeSource.CephFS != nil { if spec.Volume != nil && spec.Volume.CephFS != nil {
return spec.VolumeSource.CephFS return spec.Volume.CephFS
} else { } else {
return spec.PersistentVolumeSource.CephFS return spec.PersistentVolume.Spec.CephFS
} }
} }

View File

@ -36,10 +36,10 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/cephfs" { if plug.Name() != "kubernetes.io/cephfs" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{CephFS: &api.CephFSVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{CephFS: &api.CephFSVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }

View File

@ -53,7 +53,7 @@ func (plugin *cinderPlugin) Name() string {
} }
func (plugin *cinderPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *cinderPlugin) CanSupport(spec *volume.Spec) bool {
return spec.PersistentVolumeSource.Cinder != nil || spec.VolumeSource.Cinder != nil return (spec.Volume != nil && spec.Volume.Cinder != nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Cinder != nil)
} }
func (plugin *cinderPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { func (plugin *cinderPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
@ -68,10 +68,10 @@ func (plugin *cinderPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume
func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager cdManager, mounter mount.Interface) (volume.Builder, error) { func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager cdManager, mounter mount.Interface) (volume.Builder, error) {
var cinder *api.CinderVolumeSource var cinder *api.CinderVolumeSource
if spec.VolumeSource.Cinder != nil { if spec.Volume != nil && spec.Volume.Cinder != nil {
cinder = spec.VolumeSource.Cinder cinder = spec.Volume.Cinder
} else { } else {
cinder = spec.PersistentVolumeSource.Cinder cinder = spec.PersistentVolume.Spec.Cinder
} }
pdName := cinder.VolumeID pdName := cinder.VolumeID
@ -81,7 +81,7 @@ func (plugin *cinderPlugin) newBuilderInternal(spec *volume.Spec, podUID types.U
return &cinderVolumeBuilder{ return &cinderVolumeBuilder{
cinderVolume: &cinderVolume{ cinderVolume: &cinderVolume{
podUID: podUID, podUID: podUID,
volName: spec.Name, volName: spec.Name(),
pdName: pdName, pdName: pdName,
mounter: mounter, mounter: mounter,
manager: manager, manager: manager,

View File

@ -37,13 +37,11 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/cinder" { if plug.Name() != "kubernetes.io/cinder" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&volume.Spec{ if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{Cinder: &api.CinderVolumeSource{}}}}) {
Name: "foo",
VolumeSource: api.VolumeSource{Cinder: &api.CinderVolumeSource{}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if !plug.CanSupport(&volume.Spec{Name: "foo", PersistentVolumeSource: api.PersistentVolumeSource{Cinder: &api.CinderVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{Cinder: &api.CinderVolumeSource{}}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }

View File

@ -61,19 +61,19 @@ func (plugin *downwardAPIPlugin) Name() string {
} }
func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *downwardAPIPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.DownwardAPI != nil return spec.Volume != nil && spec.Volume.DownwardAPI != nil
} }
func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *downwardAPIPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
v := &downwardAPIVolume{ v := &downwardAPIVolume{
volName: spec.Name, volName: spec.Name(),
pod: pod, pod: pod,
podUID: pod.UID, podUID: pod.UID,
plugin: plugin, plugin: plugin,
mounter: mounter, mounter: mounter,
} }
v.fieldReferenceFileNames = make(map[string]string) v.fieldReferenceFileNames = make(map[string]string)
for _, fileInfo := range spec.VolumeSource.DownwardAPI.Items { for _, fileInfo := range spec.Volume.DownwardAPI.Items {
v.fieldReferenceFileNames[fileInfo.FieldRef.FieldPath] = path.Clean(fileInfo.Path) v.fieldReferenceFileNames[fileInfo.FieldRef.FieldPath] = path.Clean(fileInfo.Path)
} }
return &downwardAPIVolumeBuilder{ return &downwardAPIVolumeBuilder{
@ -97,8 +97,7 @@ type downwardAPIVolume struct {
// This is the spec for the volume that this plugin wraps. // This is the spec for the volume that this plugin wraps.
var wrappedVolumeSpec = &volume.Spec{ var wrappedVolumeSpec = &volume.Spec{
Name: "not-used", Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}}},
VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}},
} }
// downwardAPIVolumeBuilder fetches info from downward API from the pod // downwardAPIVolumeBuilder fetches info from downward API from the pod

View File

@ -63,7 +63,7 @@ func (plugin *emptyDirPlugin) Name() string {
} }
func (plugin *emptyDirPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *emptyDirPlugin) CanSupport(spec *volume.Spec) bool {
if spec.VolumeSource.EmptyDir != nil { if spec.Volume != nil && spec.Volume.EmptyDir != nil {
return true return true
} }
return false return false
@ -75,12 +75,12 @@ func (plugin *emptyDirPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts v
func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions, chconRunner chconRunner) (volume.Builder, error) { func (plugin *emptyDirPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface, mountDetector mountDetector, opts volume.VolumeOptions, chconRunner chconRunner) (volume.Builder, error) {
medium := api.StorageMediumDefault medium := api.StorageMediumDefault
if spec.VolumeSource.EmptyDir != nil { // Support a non-specified source as EmptyDir. if spec.Volume.EmptyDir != nil { // Support a non-specified source as EmptyDir.
medium = spec.VolumeSource.EmptyDir.Medium medium = spec.Volume.EmptyDir.Medium
} }
return &emptyDir{ return &emptyDir{
pod: pod, pod: pod,
volName: spec.Name, volName: spec.Name(),
medium: medium, medium: medium,
mounter: mounter, mounter: mounter,
mountDetector: mountDetector, mountDetector: mountDetector,

View File

@ -47,10 +47,10 @@ 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(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }

View File

@ -55,7 +55,8 @@ func (plugin *gcePersistentDiskPlugin) Name() string {
} }
func (plugin *gcePersistentDiskPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *gcePersistentDiskPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.GCEPersistentDisk != nil || spec.PersistentVolumeSource.GCEPersistentDisk != nil return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.GCEPersistentDisk != nil) ||
(spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil)
} }
func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
@ -76,11 +77,11 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod
var readOnly bool var readOnly bool
var gce *api.GCEPersistentDiskVolumeSource var gce *api.GCEPersistentDiskVolumeSource
if spec.VolumeSource.GCEPersistentDisk != nil { if spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil {
gce = spec.VolumeSource.GCEPersistentDisk gce = spec.Volume.GCEPersistentDisk
readOnly = gce.ReadOnly readOnly = gce.ReadOnly
} else { } else {
gce = spec.PersistentVolumeSource.GCEPersistentDisk gce = spec.PersistentVolume.Spec.GCEPersistentDisk
readOnly = spec.ReadOnly readOnly = spec.ReadOnly
} }
@ -94,7 +95,7 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod
return &gcePersistentDiskBuilder{ return &gcePersistentDiskBuilder{
gcePersistentDisk: &gcePersistentDisk{ gcePersistentDisk: &gcePersistentDisk{
podUID: podUID, podUID: podUID,
volName: spec.Name, volName: spec.Name(),
pdName: pdName, pdName: pdName,
partition: partition, partition: partition,
mounter: mounter, mounter: mounter,

View File

@ -39,10 +39,10 @@ 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(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if !plug.CanSupport(&volume.Spec{Name: "foo", PersistentVolumeSource: api.PersistentVolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{}}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }

View File

@ -54,20 +54,20 @@ func (plugin *gitRepoPlugin) Name() string {
} }
func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *gitRepoPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.GitRepo != nil return spec.Volume != nil && spec.Volume.GitRepo != nil
} }
func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *gitRepoPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
return &gitRepoVolumeBuilder{ return &gitRepoVolumeBuilder{
gitRepoVolume: &gitRepoVolume{ gitRepoVolume: &gitRepoVolume{
volName: spec.Name, volName: spec.Name(),
podUID: pod.UID, podUID: pod.UID,
mounter: mounter, mounter: mounter,
plugin: plugin, plugin: plugin,
}, },
pod: *pod, pod: *pod,
source: spec.VolumeSource.GitRepo.Repository, source: spec.Volume.GitRepo.Repository,
revision: spec.VolumeSource.GitRepo.Revision, revision: spec.Volume.GitRepo.Revision,
exec: exec.New(), exec: exec.New(),
opts: opts, opts: opts,
}, nil }, nil
@ -124,8 +124,7 @@ func (b *gitRepoVolumeBuilder) IsReadOnly() bool {
// This is the spec for the volume that this plugin wraps. // This is the spec for the volume that this plugin wraps.
var wrappedVolumeSpec = &volume.Spec{ var wrappedVolumeSpec = &volume.Spec{
Name: "not-used", Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}},
} }
// SetUpAt creates new directory and clones a git repo. // SetUpAt creates new directory and clones a git repo.

View File

@ -51,7 +51,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(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
} }

View File

@ -54,7 +54,8 @@ func (plugin *glusterfsPlugin) Name() string {
} }
func (plugin *glusterfsPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *glusterfsPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.Glusterfs != nil || spec.PersistentVolumeSource.Glusterfs != nil return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.Glusterfs != nil) ||
(spec.Volume != nil && spec.Volume.Glusterfs != nil)
} }
func (plugin *glusterfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { func (plugin *glusterfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
@ -81,10 +82,10 @@ func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ vol
func (plugin *glusterfsPlugin) getGlusterVolumeSource(spec *volume.Spec) (*api.GlusterfsVolumeSource, bool) { func (plugin *glusterfsPlugin) getGlusterVolumeSource(spec *volume.Spec) (*api.GlusterfsVolumeSource, bool) {
// Glusterfs volumes used directly in a pod have a ReadOnly flag set by the pod author. // Glusterfs volumes used directly in a pod have a ReadOnly flag set by the pod author.
// Glusterfs volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV // Glusterfs volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV
if spec.VolumeSource.Glusterfs != nil { if spec.Volume != nil && spec.Volume.Glusterfs != nil {
return spec.VolumeSource.Glusterfs, spec.VolumeSource.Glusterfs.ReadOnly return spec.Volume.Glusterfs, spec.Volume.Glusterfs.ReadOnly
} else { } else {
return spec.PersistentVolumeSource.Glusterfs, spec.ReadOnly return spec.PersistentVolume.Spec.Glusterfs, spec.ReadOnly
} }
} }
@ -92,7 +93,7 @@ func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.End
source, readOnly := plugin.getGlusterVolumeSource(spec) source, readOnly := plugin.getGlusterVolumeSource(spec)
return &glusterfsBuilder{ return &glusterfsBuilder{
glusterfs: &glusterfs{ glusterfs: &glusterfs{
volName: spec.Name, volName: spec.Name(),
mounter: mounter, mounter: mounter,
pod: pod, pod: pod,
plugin: plugin, plugin: plugin,

View File

@ -39,13 +39,13 @@ 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(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if !plug.CanSupport(&volume.Spec{Name: "foo", PersistentVolumeSource: api.PersistentVolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{Glusterfs: &api.GlusterfsVolumeSource{}}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }

View File

@ -60,7 +60,8 @@ func (plugin *hostPathPlugin) Name() string {
} }
func (plugin *hostPathPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *hostPathPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.HostPath != nil || spec.PersistentVolumeSource.HostPath != nil return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.HostPath != nil) ||
(spec.Volume != nil && spec.Volume.HostPath != nil)
} }
func (plugin *hostPathPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { func (plugin *hostPathPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
@ -70,14 +71,14 @@ func (plugin *hostPathPlugin) GetAccessModes() []api.PersistentVolumeAccessMode
} }
func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, _ mount.Interface) (volume.Builder, error) { func (plugin *hostPathPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, _ mount.Interface) (volume.Builder, error) {
if spec.VolumeSource.HostPath != nil { if spec.Volume != nil && spec.Volume.HostPath != nil {
return &hostPathBuilder{ return &hostPathBuilder{
hostPath: &hostPath{path: spec.VolumeSource.HostPath.Path}, hostPath: &hostPath{path: spec.Volume.HostPath.Path},
readOnly: false, readOnly: false,
}, nil }, nil
} else { } else {
return &hostPathBuilder{ return &hostPathBuilder{
hostPath: &hostPath{path: spec.PersistentVolumeSource.HostPath.Path}, hostPath: &hostPath{path: spec.PersistentVolume.Spec.HostPath.Path},
readOnly: spec.ReadOnly, readOnly: spec.ReadOnly,
}, nil }, nil
} }
@ -92,10 +93,10 @@ func (plugin *hostPathPlugin) NewRecycler(spec *volume.Spec) (volume.Recycler, e
} }
func newRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) { func newRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) {
if spec.PersistentVolumeSource.HostPath == nil { if spec.PersistentVolume == nil || spec.PersistentVolume.Spec.HostPath == nil {
return nil, fmt.Errorf("spec.PersistentVolumeSource.HostPath is nil") return nil, fmt.Errorf("spec.PersistentVolumeSource.HostPath is nil")
} }
return &hostPathRecycler{spec.Name, spec.PersistentVolumeSource.HostPath.Path, host}, nil return &hostPathRecycler{spec.Name(), spec.PersistentVolume.Spec.HostPath.Path, host}, nil
} }
// HostPath volumes represent a bare host file or directory mount. // HostPath volumes represent a bare host file or directory mount.

View File

@ -37,13 +37,13 @@ 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(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{HostPath: &api.HostPathVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if !plug.CanSupport(&volume.Spec{Name: "foo", PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{}}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }
@ -65,7 +65,7 @@ func TestRecycler(t *testing.T) {
plugMgr := volume.VolumePluginMgr{} plugMgr := volume.VolumePluginMgr{}
plugMgr.InitPlugins([]volume.VolumePlugin{&hostPathPlugin{nil, newMockRecycler}}, volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) plugMgr.InitPlugins([]volume.VolumePlugin{&hostPathPlugin{nil, newMockRecycler}}, volume.NewFakeVolumeHost("/tmp/fake", nil, nil))
spec := &volume.Spec{PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/foo"}}} spec := &volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{HostPath: &api.HostPathVolumeSource{Path: "/foo"}}}}}
plug, err := plugMgr.FindRecyclablePluginBySpec(spec) plug, err := plugMgr.FindRecyclablePluginBySpec(spec)
if err != nil { if err != nil {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
@ -74,8 +74,8 @@ func TestRecycler(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Failed to make a new Recyler: %v", err) t.Errorf("Failed to make a new Recyler: %v", err)
} }
if recycler.GetPath() != spec.PersistentVolumeSource.HostPath.Path { if recycler.GetPath() != spec.PersistentVolume.Spec.HostPath.Path {
t.Errorf("Expected %s but got %s", spec.PersistentVolumeSource.HostPath.Path, recycler.GetPath()) t.Errorf("Expected %s but got %s", spec.PersistentVolume.Spec.HostPath.Path, recycler.GetPath())
} }
if err := recycler.Recycle(); err != nil { if err := recycler.Recycle(); err != nil {
t.Errorf("Mock Recycler expected to return nil but got %s", err) t.Errorf("Mock Recycler expected to return nil but got %s", err)
@ -84,7 +84,7 @@ func TestRecycler(t *testing.T) {
func newMockRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) { func newMockRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) {
return &mockRecycler{ return &mockRecycler{
path: spec.PersistentVolumeSource.HostPath.Path, path: spec.PersistentVolume.Spec.HostPath.Path,
}, nil }, nil
} }

View File

@ -54,7 +54,7 @@ func (plugin *iscsiPlugin) Name() string {
} }
func (plugin *iscsiPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *iscsiPlugin) CanSupport(spec *volume.Spec) bool {
if spec.VolumeSource.ISCSI == nil && spec.PersistentVolumeSource.ISCSI == nil { if (spec.Volume != nil && spec.Volume.ISCSI == nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.ISCSI == nil) {
return false return false
} }
// TODO: turn this into a func so CanSupport can be unit tested without // TODO: turn this into a func so CanSupport can be unit tested without
@ -85,11 +85,11 @@ func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UI
// 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
var readOnly bool var readOnly bool
var iscsi *api.ISCSIVolumeSource var iscsi *api.ISCSIVolumeSource
if spec.VolumeSource.ISCSI != nil { if spec.Volume != nil && spec.Volume.ISCSI != nil {
iscsi = spec.VolumeSource.ISCSI iscsi = spec.Volume.ISCSI
readOnly = iscsi.ReadOnly readOnly = iscsi.ReadOnly
} else { } else {
iscsi = spec.PersistentVolumeSource.ISCSI iscsi = spec.PersistentVolume.Spec.ISCSI
readOnly = spec.ReadOnly readOnly = spec.ReadOnly
} }
@ -98,7 +98,7 @@ func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UI
return &iscsiDiskBuilder{ return &iscsiDiskBuilder{
iscsiDisk: &iscsiDisk{ iscsiDisk: &iscsiDisk{
podUID: podUID, podUID: podUID,
volName: spec.Name, volName: spec.Name(),
portal: iscsi.TargetPortal, portal: iscsi.TargetPortal,
iqn: iscsi.IQN, iqn: iscsi.IQN,
lun: lun, lun: lun,

View File

@ -39,7 +39,7 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/iscsi" { if plug.Name() != "kubernetes.io/iscsi" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }

View File

@ -59,7 +59,8 @@ func (plugin *nfsPlugin) Name() string {
} }
func (plugin *nfsPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *nfsPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.NFS != nil || spec.PersistentVolumeSource.NFS != nil return (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.NFS != nil) ||
(spec.Volume != nil && spec.Volume.NFS != nil)
} }
func (plugin *nfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { func (plugin *nfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode {
@ -77,16 +78,16 @@ func (plugin *nfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.Vo
func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface) (volume.Builder, error) { func (plugin *nfsPlugin) newBuilderInternal(spec *volume.Spec, pod *api.Pod, mounter mount.Interface) (volume.Builder, error) {
var source *api.NFSVolumeSource var source *api.NFSVolumeSource
var readOnly bool var readOnly bool
if spec.VolumeSource.NFS != nil { if spec.Volume != nil && spec.Volume.NFS != nil {
source = spec.VolumeSource.NFS source = spec.Volume.NFS
readOnly = spec.VolumeSource.NFS.ReadOnly readOnly = spec.Volume.NFS.ReadOnly
} else { } else {
source = spec.PersistentVolumeSource.NFS source = spec.PersistentVolume.Spec.NFS
readOnly = spec.ReadOnly readOnly = spec.ReadOnly
} }
return &nfsBuilder{ return &nfsBuilder{
nfs: &nfs{ nfs: &nfs{
volName: spec.Name, volName: spec.Name(),
mounter: mounter, mounter: mounter,
pod: pod, pod: pod,
plugin: plugin, plugin: plugin,
@ -236,13 +237,13 @@ func (c *nfsCleaner) TearDownAt(dir string) error {
} }
func newRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) { func newRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) {
if spec.PersistentVolumeSource.NFS == nil { if spec.PersistentVolume == nil || spec.PersistentVolume.Spec.NFS == nil {
return nil, fmt.Errorf("spec.PersistentVolumeSource.NFS is nil") return nil, fmt.Errorf("spec.PersistentVolumeSource.NFS is nil")
} }
return &nfsRecycler{ return &nfsRecycler{
name: spec.Name, name: spec.Name(),
server: spec.PersistentVolumeSource.NFS.Server, server: spec.PersistentVolume.Spec.NFS.Server,
path: spec.PersistentVolumeSource.NFS.Path, path: spec.PersistentVolume.Spec.NFS.Path,
host: host, host: host,
}, nil }, nil
} }

View File

@ -38,13 +38,13 @@ 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(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{NFS: &api.NFSVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{NFS: &api.NFSVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if !plug.CanSupport(&volume.Spec{Name: "foo", PersistentVolumeSource: api.PersistentVolumeSource{NFS: &api.NFSVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{NFS: &api.NFSVolumeSource{}}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }
@ -64,9 +64,9 @@ func TestGetAccessModes(t *testing.T) {
func TestRecycler(t *testing.T) { func TestRecycler(t *testing.T) {
plugMgr := volume.VolumePluginMgr{} plugMgr := volume.VolumePluginMgr{}
plugMgr.InitPlugins([]volume.VolumePlugin{&nfsPlugin{newRecyclerFunc: newMockRecycler}}, volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) plugMgr.InitPlugins([]volume.VolumePlugin{&nfsPlugin{nil, newMockRecycler}}, volume.NewFakeVolumeHost("/tmp/fake", nil, nil))
spec := &volume.Spec{PersistentVolumeSource: api.PersistentVolumeSource{NFS: &api.NFSVolumeSource{Path: "/foo"}}} spec := &volume.Spec{PersistentVolume: &api.PersistentVolume{Spec: api.PersistentVolumeSpec{PersistentVolumeSource: api.PersistentVolumeSource{NFS: &api.NFSVolumeSource{Path: "/foo"}}}}}
plug, err := plugMgr.FindRecyclablePluginBySpec(spec) plug, err := plugMgr.FindRecyclablePluginBySpec(spec)
if err != nil { if err != nil {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
@ -75,8 +75,8 @@ func TestRecycler(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Failed to make a new Recyler: %v", err) t.Errorf("Failed to make a new Recyler: %v", err)
} }
if recycler.GetPath() != spec.PersistentVolumeSource.NFS.Path { if recycler.GetPath() != spec.PersistentVolume.Spec.NFS.Path {
t.Errorf("Expected %s but got %s", spec.PersistentVolumeSource.NFS.Path, recycler.GetPath()) t.Errorf("Expected %s but got %s", spec.PersistentVolume.Spec.NFS.Path, recycler.GetPath())
} }
if err := recycler.Recycle(); err != nil { if err := recycler.Recycle(); err != nil {
t.Errorf("Mock Recycler expected to return nil but got %s", err) t.Errorf("Mock Recycler expected to return nil but got %s", err)
@ -85,7 +85,7 @@ func TestRecycler(t *testing.T) {
func newMockRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) { func newMockRecycler(spec *volume.Spec, host volume.VolumeHost) (volume.Recycler, error) {
return &mockRecycler{ return &mockRecycler{
path: spec.PersistentVolumeSource.NFS.Path, path: spec.PersistentVolume.Spec.NFS.Path,
}, nil }, nil
} }

View File

@ -49,13 +49,13 @@ func (plugin *persistentClaimPlugin) Name() string {
} }
func (plugin *persistentClaimPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *persistentClaimPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.PersistentVolumeClaim != nil return spec.Volume != nil && spec.Volume.PersistentVolumeClaim != nil
} }
func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
claim, err := plugin.host.GetKubeClient().PersistentVolumeClaims(pod.Namespace).Get(spec.VolumeSource.PersistentVolumeClaim.ClaimName) claim, err := plugin.host.GetKubeClient().PersistentVolumeClaims(pod.Namespace).Get(spec.Volume.PersistentVolumeClaim.ClaimName)
if err != nil { if err != nil {
glog.Errorf("Error finding claim: %+v\n", spec.VolumeSource.PersistentVolumeClaim.ClaimName) glog.Errorf("Error finding claim: %+v\n", spec.Volume.PersistentVolumeClaim.ClaimName)
return nil, err return nil, err
} }

View File

@ -51,13 +51,13 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/persistent-claim" { if plug.Name() != "kubernetes.io/persistent-claim" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if !plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{}}}) { if !plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plug.CanSupport(&volume.Spec{VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{GitRepo: &api.GitRepoVolumeSource{}}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
if plug.CanSupport(&volume.Spec{VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }
@ -247,10 +247,7 @@ func TestNewBuilder(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
spec := &volume.Spec{ spec := &volume.Spec{Volume: &api.Volume{VolumeSource: item.podVolume}}
Name: "vol1",
VolumeSource: item.podVolume,
}
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil)
@ -305,10 +302,7 @@ func TestNewBuilderClaimNotBound(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("Can't find the plugin by name") t.Errorf("Can't find the plugin by name")
} }
spec := &volume.Spec{ spec := &volume.Spec{Volume: &api.Volume{VolumeSource: podVolume}}
Name: "vol1",
VolumeSource: podVolume,
}
pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}} pod := &api.Pod{ObjectMeta: api.ObjectMeta{UID: types.UID("poduid")}}
builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil) builder, err := plug.NewBuilder(spec, pod, volume.VolumeOptions{}, nil)
if builder != nil { if builder != nil {

View File

@ -135,12 +135,23 @@ type VolumePluginMgr struct {
// Spec is an internal representation of a volume. All API volume types translate to Spec. // Spec is an internal representation of a volume. All API volume types translate to Spec.
type Spec struct { type Spec struct {
Name string Volume *api.Volume
VolumeSource api.VolumeSource PersistentVolume *api.PersistentVolume
PersistentVolumeSource api.PersistentVolumeSource
ReadOnly bool ReadOnly bool
} }
// Name returns the name of either Volume or PersistentVolume, one of which must not be nil.
func (spec *Spec) Name() string {
switch {
case spec.Volume != nil:
return spec.Volume.Name
case spec.PersistentVolume != nil:
return spec.PersistentVolume.Name
default:
return ""
}
}
// VolumeConfig is how volume plugins receive configuration. An instance specific to the plugin will be passed to // VolumeConfig is how volume plugins receive configuration. An instance specific to the plugin will be passed to
// the plugin's ProbeVolumePlugins(config) func. Reasonable defaults will be provided by the binary hosting // the plugin's ProbeVolumePlugins(config) func. Reasonable defaults will be provided by the binary hosting
// the plugins while allowing override of those default values. Those config values are then set to an instance of // the plugins while allowing override of those default values. Those config values are then set to an instance of
@ -166,16 +177,14 @@ type VolumeConfig struct {
// NewSpecFromVolume creates an Spec from an api.Volume // NewSpecFromVolume creates an Spec from an api.Volume
func NewSpecFromVolume(vs *api.Volume) *Spec { func NewSpecFromVolume(vs *api.Volume) *Spec {
return &Spec{ return &Spec{
Name: vs.Name, Volume: vs,
VolumeSource: vs.VolumeSource,
} }
} }
// NewSpecFromPersistentVolume creates an Spec from an api.PersistentVolume // NewSpecFromPersistentVolume creates an Spec from an api.PersistentVolume
func NewSpecFromPersistentVolume(pv *api.PersistentVolume, readOnly bool) *Spec { func NewSpecFromPersistentVolume(pv *api.PersistentVolume, readOnly bool) *Spec {
return &Spec{ return &Spec{
Name: pv.Name, PersistentVolume: pv,
PersistentVolumeSource: pv.Spec.PersistentVolumeSource,
ReadOnly: readOnly, ReadOnly: readOnly,
} }
} }

View File

@ -29,11 +29,11 @@ func TestSpecSourceConverters(t *testing.T) {
} }
converted := NewSpecFromVolume(v) converted := NewSpecFromVolume(v)
if converted.VolumeSource.EmptyDir == nil { if converted.Volume.EmptyDir == nil {
t.Errorf("Unexpected nil EmptyDir: %+v", converted) t.Errorf("Unexpected nil EmptyDir: %+v", converted)
} }
if v.Name != converted.Name { if v.Name != converted.Name() {
t.Errorf("Expected %v but got %v", v.Name, converted.Name) t.Errorf("Expected %v but got %v", v.Name, converted.Name())
} }
pv := &api.PersistentVolume{ pv := &api.PersistentVolume{
@ -44,10 +44,10 @@ func TestSpecSourceConverters(t *testing.T) {
} }
converted = NewSpecFromPersistentVolume(pv, false) converted = NewSpecFromPersistentVolume(pv, false)
if converted.PersistentVolumeSource.AWSElasticBlockStore == nil { if converted.PersistentVolume.Spec.AWSElasticBlockStore == nil {
t.Errorf("Unexpected nil AWSElasticBlockStore: %+v", converted) t.Errorf("Unexpected nil AWSElasticBlockStore: %+v", converted)
} }
if pv.Name != converted.Name { if pv.Name != converted.Name() {
t.Errorf("Expected %v but got %v", pv.Name, converted.Name) t.Errorf("Expected %v but got %v", pv.Name, converted.Name())
} }
} }

View File

@ -54,7 +54,7 @@ func (plugin *rbdPlugin) Name() string {
} }
func (plugin *rbdPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *rbdPlugin) CanSupport(spec *volume.Spec) bool {
if spec.VolumeSource.RBD == nil && spec.PersistentVolumeSource.RBD == nil { if (spec.Volume != nil && spec.Volume.RBD == nil) || (spec.PersistentVolume != nil && spec.PersistentVolume.Spec.RBD == nil) {
return false return false
} }
// see if rbd is there // see if rbd is there
@ -101,10 +101,10 @@ func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.Vo
func (plugin *rbdPlugin) getRBDVolumeSource(spec *volume.Spec) (*api.RBDVolumeSource, bool) { func (plugin *rbdPlugin) getRBDVolumeSource(spec *volume.Spec) (*api.RBDVolumeSource, bool) {
// rbd volumes used directly in a pod have a ReadOnly flag set by the pod author. // rbd volumes used directly in a pod have a ReadOnly flag set by the pod author.
// rbd volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV // rbd volumes used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV
if spec.VolumeSource.RBD != nil { if spec.Volume != nil && spec.Volume.RBD != nil {
return spec.VolumeSource.RBD, spec.VolumeSource.RBD.ReadOnly return spec.Volume.RBD, spec.Volume.RBD.ReadOnly
} else { } else {
return spec.PersistentVolumeSource.RBD, spec.ReadOnly return spec.PersistentVolume.Spec.RBD, spec.ReadOnly
} }
} }
@ -126,7 +126,7 @@ func (plugin *rbdPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID,
return &rbdBuilder{ return &rbdBuilder{
rbd: &rbd{ rbd: &rbd{
podUID: podUID, podUID: podUID,
volName: spec.Name, volName: spec.Name(),
Image: source.RBDImage, Image: source.RBDImage,
Pool: pool, Pool: pool,
ReadOnly: readOnly, ReadOnly: readOnly,

View File

@ -39,7 +39,7 @@ func TestCanSupport(t *testing.T) {
if plug.Name() != "kubernetes.io/rbd" { if plug.Name() != "kubernetes.io/rbd" {
t.Errorf("Wrong name: %s", plug.Name()) t.Errorf("Wrong name: %s", plug.Name())
} }
if plug.CanSupport(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{}}) { if plug.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{}}}) {
t.Errorf("Expected false") t.Errorf("Expected false")
} }
} }

View File

@ -56,13 +56,13 @@ func (plugin *secretPlugin) Name() string {
} }
func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool { func (plugin *secretPlugin) CanSupport(spec *volume.Spec) bool {
return spec.VolumeSource.Secret != nil return spec.Volume != nil && spec.Volume.Secret != nil
} }
func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { func (plugin *secretPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
return &secretVolumeBuilder{ return &secretVolumeBuilder{
secretVolume: &secretVolume{spec.Name, pod.UID, plugin, mounter}, secretVolume: &secretVolume{spec.Name(), pod.UID, plugin, mounter},
secretName: spec.VolumeSource.Secret.SecretName, secretName: spec.Volume.Secret.SecretName,
pod: *pod, pod: *pod,
opts: &opts}, nil opts: &opts}, nil
} }
@ -102,8 +102,7 @@ func (b *secretVolumeBuilder) 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 = &volume.Spec{ var wrappedVolumeSpec = &volume.Spec{
Name: "not-used", Volume: &api.Volume{VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}}},
VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{Medium: api.StorageMediumMemory}},
} }
func (b *secretVolumeBuilder) getMetaDir() string { func (b *secretVolumeBuilder) getMetaDir() string {

View File

@ -55,9 +55,12 @@ 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(&volume.Spec{Name: "foo", VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: ""}}}) { if !plugin.CanSupport(&volume.Spec{Volume: &api.Volume{VolumeSource: api.VolumeSource{Secret: &api.SecretVolumeSource{SecretName: ""}}}}) {
t.Errorf("Expected true") t.Errorf("Expected true")
} }
if plugin.CanSupport(&volume.Spec{}) {
t.Errorf("Expected false")
}
} }
func TestPlugin(t *testing.T) { func TestPlugin(t *testing.T) {

View File

@ -75,7 +75,7 @@ func (f *fakeVolumeHost) NewWrapperCleaner(spec *Spec, podUID types.UID, mounter
if err != nil { if err != nil {
return nil, err return nil, err
} }
return plug.NewCleaner(spec.Name, podUID, mounter) return plug.NewCleaner(spec.Name(), podUID, mounter)
} }
func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin { func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin {
@ -112,12 +112,12 @@ func (plugin *FakeVolumePlugin) Name() string {
} }
func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) 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 *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) { func (plugin *FakeVolumePlugin) NewBuilder(spec *Spec, pod *api.Pod, opts VolumeOptions, mounter mount.Interface) (Builder, error) {
return &FakeVolume{pod.UID, spec.Name, plugin}, nil return &FakeVolume{pod.UID, spec.Name(), plugin}, nil
} }
func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (Cleaner, error) { func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID, mounter mount.Interface) (Cleaner, error) {