From 5b23fc39b21866b4848cae7d5d5ce2835037247c Mon Sep 17 00:00:00 2001 From: markturansky Date: Tue, 12 May 2015 16:40:31 -0400 Subject: [PATCH 1/3] added ISCSI volume plugin to PersistentVolumeSource --- pkg/api/types.go | 3 +++ pkg/api/v1/types.go | 3 +++ pkg/api/v1beta1/types.go | 3 +++ pkg/api/v1beta2/types.go | 3 +++ pkg/api/v1beta3/conversion_generated.go | 8 ++++++++ pkg/api/v1beta3/types.go | 3 +++ pkg/api/validation/validation.go | 4 ++++ pkg/volume/iscsi/iscsi_test.go | 22 ++++++++++++++++++++++ 8 files changed, 49 insertions(+) diff --git a/pkg/api/types.go b/pkg/api/types.go index c4a516e8210..b6ef3421b2b 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -228,6 +228,9 @@ type PersistentVolumeSource struct { NFS *NFSVolumeSource `json:"nfs"` // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime RBD *RBDVolumeSource `json:"rbd"` + // ISCSIVolumeSource represents an ISCSI resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi"` } type PersistentVolumeClaimVolumeSource struct { diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index 057569ad4db..803d0a45c78 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -253,6 +253,9 @@ type PersistentVolumeSource struct { NFS *NFSVolumeSource `json:"nfs,omitempty" description:"NFS volume resource provisioned by an admin"` // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime RBD *RBDVolumeSource `json:"rbd" description:"rados block volume that will be mounted on the host machine"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi" description:"an iSCSI disk resource provisioned by an admin"` } type PersistentVolume struct { diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index 2f82854ad82..c54887c9ae9 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -156,6 +156,9 @@ type PersistentVolumeSource struct { NFS *NFSVolumeSource `json:"nfs" description:"NFS volume resource provisioned by an admin"` // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime RBD *RBDVolumeSource `json:"rbd" description:"rados block volume that will be mounted on the host machine"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi" description:"an iSCSI disk resource provisioned by an admin"` } type PersistentVolumeClaimVolumeSource struct { diff --git a/pkg/api/v1beta2/types.go b/pkg/api/v1beta2/types.go index e27ac6a6244..aa280d4931b 100644 --- a/pkg/api/v1beta2/types.go +++ b/pkg/api/v1beta2/types.go @@ -113,6 +113,9 @@ type PersistentVolumeSource struct { NFS *NFSVolumeSource `json:"nfs" description:"NFS volume resource provisioned by an admin"` // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime RBD *RBDVolumeSource `json:"rbd" description:"rados block volume that will be mounted on the host machine"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi" description:"an iSCSI disk resource provisioned by an admin"` } type PersistentVolumeClaimVolumeSource struct { diff --git a/pkg/api/v1beta3/conversion_generated.go b/pkg/api/v1beta3/conversion_generated.go index 19ff15bbe1b..b6f4ccaecaf 100644 --- a/pkg/api/v1beta3/conversion_generated.go +++ b/pkg/api/v1beta3/conversion_generated.go @@ -2193,6 +2193,14 @@ func convert_api_VolumeSource_To_v1beta3_VolumeSource(in *api.VolumeSource, out } else { out.ISCSI = nil } + if in.ISCSI != nil { + out.ISCSI = new(ISCSIVolumeSource) + if err := convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } if in.Glusterfs != nil { out.Glusterfs = new(GlusterfsVolumeSource) if err := convert_api_GlusterfsVolumeSource_To_v1beta3_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { diff --git a/pkg/api/v1beta3/types.go b/pkg/api/v1beta3/types.go index edaeaa69a60..52a5f37f3f9 100644 --- a/pkg/api/v1beta3/types.go +++ b/pkg/api/v1beta3/types.go @@ -253,6 +253,9 @@ type PersistentVolumeSource struct { NFS *NFSVolumeSource `json:"nfs,omitempty" description:"NFS volume resource provisioned by an admin"` // RBD represents a Rados Block Device mount on the host that shares a pod's lifetime RBD *RBDVolumeSource `json:"rbd" description:"rados block volume that will be mounted on the host machine"` + // ISCSI represents an ISCSI Disk resource that is attached to a + // kubelet's host machine and then exposed to the pod. + ISCSI *ISCSIVolumeSource `json:"iscsi" description:"an iSCSI disk resource provisioned by an admin"` } type PersistentVolume struct { diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index ed9ab43a419..49a8db6ad38 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -518,6 +518,10 @@ func ValidatePersistentVolume(pv *api.PersistentVolume) errs.ValidationErrorList numVolumes++ allErrs = append(allErrs, validateRBD(pv.Spec.RBD).Prefix("rbd")...) } + if pv.Spec.ISCSI != nil { + numVolumes++ + allErrs = append(allErrs, validateISCSIVolumeSource(pv.Spec.ISCSI).Prefix("iscsi")...) + } if numVolumes != 1 { allErrs = append(allErrs, errs.NewFieldInvalid("", pv.Spec.PersistentVolumeSource, "exactly 1 volume type is required")) } diff --git a/pkg/volume/iscsi/iscsi_test.go b/pkg/volume/iscsi/iscsi_test.go index b3cdf9f494a..82ec3cc5c9d 100644 --- a/pkg/volume/iscsi/iscsi_test.go +++ b/pkg/volume/iscsi/iscsi_test.go @@ -39,6 +39,28 @@ func TestCanSupport(t *testing.T) { } } +func TestGetAccessModes(t *testing.T) { + plugMgr := volume.VolumePluginMgr{} + plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("/tmp/fake", nil, nil)) + + plug, err := plugMgr.FindPersistentPluginByName("kubernetes.io/iscsi") + if err != nil { + t.Errorf("Can't find the plugin by name") + } + if !contains(plug.GetAccessModes(), api.ReadWriteOnce) || !contains(plug.GetAccessModes(), api.ReadOnlyMany) { + t.Errorf("Expected two AccessModeTypes: %s and %s", api.ReadWriteOnce, api.ReadOnlyMany) + } +} + +func contains(modes []api.AccessModeType, mode api.AccessModeType) bool { + for _, m := range modes { + if m == mode { + return true + } + } + return false +} + type fakeDiskManager struct { attachCalled bool detachCalled bool From 77c39edcc958a593f8b3442beb1e5f28027a8b8c Mon Sep 17 00:00:00 2001 From: markturansky Date: Fri, 22 May 2015 15:18:48 -0400 Subject: [PATCH 2/3] rebased and regenerated conversions --- pkg/api/v1/conversion_generated.go | 16 ++++++++++++++++ pkg/api/v1beta3/conversion_generated.go | 24 ++++++++++++++++-------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/pkg/api/v1/conversion_generated.go b/pkg/api/v1/conversion_generated.go index 21d2b1de640..987755c05e8 100644 --- a/pkg/api/v1/conversion_generated.go +++ b/pkg/api/v1/conversion_generated.go @@ -1285,6 +1285,14 @@ func convert_api_PersistentVolumeSource_To_v1_PersistentVolumeSource(in *api.Per } else { out.RBD = nil } + if in.ISCSI != nil { + out.ISCSI = new(ISCSIVolumeSource) + if err := convert_api_ISCSIVolumeSource_To_v1_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } return nil } @@ -3511,6 +3519,14 @@ func convert_v1_PersistentVolumeSource_To_api_PersistentVolumeSource(in *Persist } else { out.RBD = nil } + if in.ISCSI != nil { + out.ISCSI = new(api.ISCSIVolumeSource) + if err := convert_v1_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } return nil } diff --git a/pkg/api/v1beta3/conversion_generated.go b/pkg/api/v1beta3/conversion_generated.go index b6f4ccaecaf..2fa068b6e0a 100644 --- a/pkg/api/v1beta3/conversion_generated.go +++ b/pkg/api/v1beta3/conversion_generated.go @@ -1192,6 +1192,14 @@ func convert_api_PersistentVolumeSource_To_v1beta3_PersistentVolumeSource(in *ap } else { out.RBD = nil } + if in.ISCSI != nil { + out.ISCSI = new(ISCSIVolumeSource) + if err := convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } return nil } @@ -2193,14 +2201,6 @@ func convert_api_VolumeSource_To_v1beta3_VolumeSource(in *api.VolumeSource, out } else { out.ISCSI = nil } - if in.ISCSI != nil { - out.ISCSI = new(ISCSIVolumeSource) - if err := convert_api_ISCSIVolumeSource_To_v1beta3_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { - return err - } - } else { - out.ISCSI = nil - } if in.Glusterfs != nil { out.Glusterfs = new(GlusterfsVolumeSource) if err := convert_api_GlusterfsVolumeSource_To_v1beta3_GlusterfsVolumeSource(in.Glusterfs, out.Glusterfs, s); err != nil { @@ -3395,6 +3395,14 @@ func convert_v1beta3_PersistentVolumeSource_To_api_PersistentVolumeSource(in *Pe } else { out.RBD = nil } + if in.ISCSI != nil { + out.ISCSI = new(api.ISCSIVolumeSource) + if err := convert_v1beta3_ISCSIVolumeSource_To_api_ISCSIVolumeSource(in.ISCSI, out.ISCSI, s); err != nil { + return err + } + } else { + out.ISCSI = nil + } return nil } From 63ddfa537e7917912a9d29c0fa0607441bc7adcb Mon Sep 17 00:00:00 2001 From: markturansky Date: Fri, 22 May 2015 15:23:34 -0400 Subject: [PATCH 3/3] fixed missing PV check in CanSupport --- pkg/volume/iscsi/iscsi.go | 4 +++- pkg/volume/iscsi/iscsi_test.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/volume/iscsi/iscsi.go b/pkg/volume/iscsi/iscsi.go index 3695642b7fe..bfc8e5986c9 100644 --- a/pkg/volume/iscsi/iscsi.go +++ b/pkg/volume/iscsi/iscsi.go @@ -53,9 +53,11 @@ func (plugin *ISCSIPlugin) Name() string { } func (plugin *ISCSIPlugin) CanSupport(spec *volume.Spec) bool { - if spec.VolumeSource.ISCSI == nil { + if spec.VolumeSource.ISCSI == nil && spec.PersistentVolumeSource.ISCSI == nil { return false } + // TODO: turn this into a func so CanSupport can be unit tested without + // having to make system calls // see if iscsiadm is there _, err := plugin.execCommand("iscsiadm", []string{"-h"}) if err == nil { diff --git a/pkg/volume/iscsi/iscsi_test.go b/pkg/volume/iscsi/iscsi_test.go index 82ec3cc5c9d..aacbf00fef5 100644 --- a/pkg/volume/iscsi/iscsi_test.go +++ b/pkg/volume/iscsi/iscsi_test.go @@ -52,7 +52,7 @@ func TestGetAccessModes(t *testing.T) { } } -func contains(modes []api.AccessModeType, mode api.AccessModeType) bool { +func contains(modes []api.PersistentVolumeAccessMode, mode api.PersistentVolumeAccessMode) bool { for _, m := range modes { if m == mode { return true