mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
Merge pull request #6809 from markturansky/pv_union
Refactor Volumes to use InternalVolume instead of API types
This commit is contained in:
commit
f471ca8e0c
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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{}},
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
53
pkg/volume/plugins_test.go
Normal file
53
pkg/volume/plugins_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
@ -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}},
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user