diff --git a/pkg/volume/aws_ebs/aws_ebs.go b/pkg/volume/aws_ebs/aws_ebs.go index 89ab85dc1c..84cc8d1bb6 100644 --- a/pkg/volume/aws_ebs/aws_ebs.go +++ b/pkg/volume/aws_ebs/aws_ebs.go @@ -45,6 +45,7 @@ type awsElasticBlockStorePlugin struct { } var _ volume.VolumePlugin = &awsElasticBlockStorePlugin{} +var _ volume.PersistentVolumePlugin = &awsElasticBlockStorePlugin{} const ( awsElasticBlockStorePluginName = "kubernetes.io/aws-ebs" @@ -74,11 +75,16 @@ func (plugin *awsElasticBlockStorePlugin) NewBuilder(spec *volume.Spec, pod *api } func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager ebsManager, mounter mount.Interface) (volume.Builder, error) { + // EBSs used directly in a pod have a ReadOnly flag set by the pod author. + // EBSs used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV + var readOnly bool var ebs *api.AWSElasticBlockStoreVolumeSource if spec.VolumeSource.AWSElasticBlockStore != nil { ebs = spec.VolumeSource.AWSElasticBlockStore + readOnly = ebs.ReadOnly } else { ebs = spec.PersistentVolumeSource.AWSElasticBlockStore + readOnly = spec.ReadOnly } volumeID := ebs.VolumeID @@ -87,7 +93,6 @@ func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec, if ebs.Partition != 0 { partition = strconv.Itoa(ebs.Partition) } - readOnly := ebs.ReadOnly return &awsElasticBlockStore{ podUID: podUID, diff --git a/pkg/volume/gce_pd/gce_pd.go b/pkg/volume/gce_pd/gce_pd.go index e22442fd9f..7489065d8e 100644 --- a/pkg/volume/gce_pd/gce_pd.go +++ b/pkg/volume/gce_pd/gce_pd.go @@ -40,6 +40,7 @@ type gcePersistentDiskPlugin struct { } var _ volume.VolumePlugin = &gcePersistentDiskPlugin{} +var _ volume.PersistentVolumePlugin = &gcePersistentDiskPlugin{} const ( gcePersistentDiskPluginName = "kubernetes.io/gce-pd" @@ -70,11 +71,17 @@ func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *volume.Spec, pod *api.Po } func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager pdManager, mounter mount.Interface) (volume.Builder, error) { + // GCEPDs used directly in a pod have a ReadOnly flag set by the pod author. + // GCEPDs used as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV + var readOnly bool + var gce *api.GCEPersistentDiskVolumeSource if spec.VolumeSource.GCEPersistentDisk != nil { gce = spec.VolumeSource.GCEPersistentDisk + readOnly = gce.ReadOnly } else { gce = spec.PersistentVolumeSource.GCEPersistentDisk + readOnly = spec.ReadOnly } pdName := gce.PDName @@ -83,7 +90,6 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod if gce.Partition != 0 { partition = strconv.Itoa(gce.Partition) } - readOnly := gce.ReadOnly return &gcePersistentDiskBuilder{ gcePersistentDisk: &gcePersistentDisk{ diff --git a/pkg/volume/glusterfs/glusterfs.go b/pkg/volume/glusterfs/glusterfs.go index d9f85967ab..8df45a7cbb 100644 --- a/pkg/volume/glusterfs/glusterfs.go +++ b/pkg/volume/glusterfs/glusterfs.go @@ -39,6 +39,7 @@ type glusterfsPlugin struct { } var _ volume.VolumePlugin = &glusterfsPlugin{} +var _ volume.PersistentVolumePlugin = &glusterfsPlugin{} const ( glusterfsPluginName = "kubernetes.io/glusterfs" @@ -65,7 +66,7 @@ func (plugin *glusterfsPlugin) GetAccessModes() []api.PersistentVolumeAccessMode } func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { - source := plugin.getGlusterVolumeSource(spec) + source, _ := plugin.getGlusterVolumeSource(spec) ep_name := source.EndpointsName ns := pod.Namespace ep, err := plugin.host.GetKubeClient().Endpoints(ns).Get(ep_name) @@ -77,16 +78,18 @@ func (plugin *glusterfsPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ vol return plugin.newBuilderInternal(spec, ep, pod, mounter, exec.New()) } -func (plugin *glusterfsPlugin) getGlusterVolumeSource(spec *volume.Spec) *api.GlusterfsVolumeSource { +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 as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV if spec.VolumeSource.Glusterfs != nil { - return spec.VolumeSource.Glusterfs + return spec.VolumeSource.Glusterfs, spec.VolumeSource.Glusterfs.ReadOnly } else { - return spec.PersistentVolumeSource.Glusterfs + return spec.PersistentVolumeSource.Glusterfs, spec.ReadOnly } } func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.Endpoints, pod *api.Pod, mounter mount.Interface, exe exec.Interface) (volume.Builder, error) { - source := plugin.getGlusterVolumeSource(spec) + source, readOnly := plugin.getGlusterVolumeSource(spec) return &glusterfsBuilder{ glusterfs: &glusterfs{ volName: spec.Name, @@ -96,7 +99,7 @@ func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.End }, hosts: ep, path: source.Path, - readonly: source.ReadOnly, + readonly: readOnly, exe: exe}, nil } diff --git a/pkg/volume/iscsi/iscsi.go b/pkg/volume/iscsi/iscsi.go index 99064aa9df..587b9e3865 100644 --- a/pkg/volume/iscsi/iscsi.go +++ b/pkg/volume/iscsi/iscsi.go @@ -39,6 +39,7 @@ type iscsiPlugin struct { } var _ volume.VolumePlugin = &iscsiPlugin{} +var _ volume.PersistentVolumePlugin = &iscsiPlugin{} const ( iscsiPluginName = "kubernetes.io/iscsi" @@ -80,11 +81,16 @@ func (plugin *iscsiPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume. } func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface) (volume.Builder, error) { + // iscsi volumes used directly in a pod have a ReadOnly flag set by the pod author. + // 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 iscsi *api.ISCSIVolumeSource if spec.VolumeSource.ISCSI != nil { iscsi = spec.VolumeSource.ISCSI + readOnly = iscsi.ReadOnly } else { iscsi = spec.PersistentVolumeSource.ISCSI + readOnly = spec.ReadOnly } lun := strconv.Itoa(iscsi.Lun) @@ -99,9 +105,8 @@ func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UI manager: manager, mounter: mounter, plugin: plugin}, - fsType: iscsi.FSType, - readOnly: iscsi.ReadOnly, + readOnly: readOnly, }, nil } diff --git a/pkg/volume/persistent_claim/persistent_claim.go b/pkg/volume/persistent_claim/persistent_claim.go index 486ad0d82b..737f6b8443 100644 --- a/pkg/volume/persistent_claim/persistent_claim.go +++ b/pkg/volume/persistent_claim/persistent_claim.go @@ -78,7 +78,7 @@ func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, return nil, err } - builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv), pod, opts, mounter) + builder, err := plugin.host.NewWrapperBuilder(volume.NewSpecFromPersistentVolume(pv, spec.ReadOnly), pod, opts, mounter) if err != nil { glog.Errorf("Error creating builder for claim: %+v\n", claim.Name) return nil, err diff --git a/pkg/volume/plugins.go b/pkg/volume/plugins.go index d94807fd89..28f80bd3e8 100644 --- a/pkg/volume/plugins.go +++ b/pkg/volume/plugins.go @@ -134,6 +134,7 @@ type Spec struct { Name string VolumeSource api.VolumeSource PersistentVolumeSource api.PersistentVolumeSource + ReadOnly bool } // NewSpecFromVolume creates an Spec from an api.Volume @@ -145,10 +146,11 @@ func NewSpecFromVolume(vs *api.Volume) *Spec { } // NewSpecFromPersistentVolume creates an Spec from an api.PersistentVolume -func NewSpecFromPersistentVolume(pv *api.PersistentVolume) *Spec { +func NewSpecFromPersistentVolume(pv *api.PersistentVolume, readOnly bool) *Spec { return &Spec{ Name: pv.Name, PersistentVolumeSource: pv.Spec.PersistentVolumeSource, + ReadOnly: readOnly, } } diff --git a/pkg/volume/plugins_test.go b/pkg/volume/plugins_test.go index 30ffd0755f..a5930ac7eb 100644 --- a/pkg/volume/plugins_test.go +++ b/pkg/volume/plugins_test.go @@ -43,7 +43,7 @@ func TestSpecSourceConverters(t *testing.T) { }, } - converted = NewSpecFromPersistentVolume(pv) + converted = NewSpecFromPersistentVolume(pv, false) if converted.PersistentVolumeSource.AWSElasticBlockStore == nil { t.Errorf("Unexpected nil AWSElasticBlockStore: %+v", converted) } diff --git a/pkg/volume/rbd/rbd.go b/pkg/volume/rbd/rbd.go index 1bcb12fc70..e5eac04c82 100644 --- a/pkg/volume/rbd/rbd.go +++ b/pkg/volume/rbd/rbd.go @@ -39,6 +39,7 @@ type rbdPlugin struct { } var _ volume.VolumePlugin = &rbdPlugin{} +var _ volume.PersistentVolumePlugin = &rbdPlugin{} const ( rbdPluginName = "kubernetes.io/rbd" @@ -74,7 +75,7 @@ func (plugin *rbdPlugin) GetAccessModes() []api.PersistentVolumeAccessMode { func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) { secret := "" - source := plugin.getRBDVolumeSource(spec) + source, _ := plugin.getRBDVolumeSource(spec) if source.SecretRef != nil { kubeClient := plugin.host.GetKubeClient() @@ -97,16 +98,18 @@ func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.Vo return plugin.newBuilderInternal(spec, pod.UID, &RBDUtil{}, mounter, secret) } -func (plugin *rbdPlugin) getRBDVolumeSource(spec *volume.Spec) *api.RBDVolumeSource { +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 as a PersistentVolume gets the ReadOnly flag indirectly through the persistent-claim volume used to mount the PV if spec.VolumeSource.RBD != nil { - return spec.VolumeSource.RBD + return spec.VolumeSource.RBD, spec.VolumeSource.RBD.ReadOnly } else { - return spec.PersistentVolumeSource.RBD + return spec.PersistentVolumeSource.RBD, spec.ReadOnly } } func (plugin *rbdPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, manager diskManager, mounter mount.Interface, secret string) (volume.Builder, error) { - source := plugin.getRBDVolumeSource(spec) + source, readOnly := plugin.getRBDVolumeSource(spec) pool := source.RBDPool if pool == "" { pool = "rbd" @@ -126,7 +129,7 @@ func (plugin *rbdPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID, volName: spec.Name, Image: source.RBDImage, Pool: pool, - ReadOnly: source.ReadOnly, + ReadOnly: readOnly, manager: manager, mounter: mounter, plugin: plugin,