Honor ReadOnly flag from persistent-volume plugin

This commit is contained in:
markturansky 2015-06-26 16:37:11 -04:00
parent 1367076d2e
commit 124bb22f92
8 changed files with 43 additions and 19 deletions

View File

@ -45,6 +45,7 @@ type awsElasticBlockStorePlugin struct {
} }
var _ volume.VolumePlugin = &awsElasticBlockStorePlugin{} var _ volume.VolumePlugin = &awsElasticBlockStorePlugin{}
var _ volume.PersistentVolumePlugin = &awsElasticBlockStorePlugin{}
const ( const (
awsElasticBlockStorePluginName = "kubernetes.io/aws-ebs" 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) { 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 var ebs *api.AWSElasticBlockStoreVolumeSource
if spec.VolumeSource.AWSElasticBlockStore != nil { if spec.VolumeSource.AWSElasticBlockStore != nil {
ebs = spec.VolumeSource.AWSElasticBlockStore ebs = spec.VolumeSource.AWSElasticBlockStore
readOnly = ebs.ReadOnly
} else { } else {
ebs = spec.PersistentVolumeSource.AWSElasticBlockStore ebs = spec.PersistentVolumeSource.AWSElasticBlockStore
readOnly = spec.ReadOnly
} }
volumeID := ebs.VolumeID volumeID := ebs.VolumeID
@ -87,7 +93,6 @@ func (plugin *awsElasticBlockStorePlugin) newBuilderInternal(spec *volume.Spec,
if ebs.Partition != 0 { if ebs.Partition != 0 {
partition = strconv.Itoa(ebs.Partition) partition = strconv.Itoa(ebs.Partition)
} }
readOnly := ebs.ReadOnly
return &awsElasticBlockStore{ return &awsElasticBlockStore{
podUID: podUID, podUID: podUID,

View File

@ -40,6 +40,7 @@ type gcePersistentDiskPlugin struct {
} }
var _ volume.VolumePlugin = &gcePersistentDiskPlugin{} var _ volume.VolumePlugin = &gcePersistentDiskPlugin{}
var _ volume.PersistentVolumePlugin = &gcePersistentDiskPlugin{}
const ( const (
gcePersistentDiskPluginName = "kubernetes.io/gce-pd" 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) { 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 var gce *api.GCEPersistentDiskVolumeSource
if spec.VolumeSource.GCEPersistentDisk != nil { if spec.VolumeSource.GCEPersistentDisk != nil {
gce = spec.VolumeSource.GCEPersistentDisk gce = spec.VolumeSource.GCEPersistentDisk
readOnly = gce.ReadOnly
} else { } else {
gce = spec.PersistentVolumeSource.GCEPersistentDisk gce = spec.PersistentVolumeSource.GCEPersistentDisk
readOnly = spec.ReadOnly
} }
pdName := gce.PDName pdName := gce.PDName
@ -83,7 +90,6 @@ func (plugin *gcePersistentDiskPlugin) newBuilderInternal(spec *volume.Spec, pod
if gce.Partition != 0 { if gce.Partition != 0 {
partition = strconv.Itoa(gce.Partition) partition = strconv.Itoa(gce.Partition)
} }
readOnly := gce.ReadOnly
return &gcePersistentDiskBuilder{ return &gcePersistentDiskBuilder{
gcePersistentDisk: &gcePersistentDisk{ gcePersistentDisk: &gcePersistentDisk{

View File

@ -39,6 +39,7 @@ type glusterfsPlugin struct {
} }
var _ volume.VolumePlugin = &glusterfsPlugin{} var _ volume.VolumePlugin = &glusterfsPlugin{}
var _ volume.PersistentVolumePlugin = &glusterfsPlugin{}
const ( const (
glusterfsPluginName = "kubernetes.io/glusterfs" 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) { 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 ep_name := source.EndpointsName
ns := pod.Namespace ns := pod.Namespace
ep, err := plugin.host.GetKubeClient().Endpoints(ns).Get(ep_name) 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()) 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 { if spec.VolumeSource.Glusterfs != nil {
return spec.VolumeSource.Glusterfs return spec.VolumeSource.Glusterfs, spec.VolumeSource.Glusterfs.ReadOnly
} else { } 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) { 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{ return &glusterfsBuilder{
glusterfs: &glusterfs{ glusterfs: &glusterfs{
volName: spec.Name, volName: spec.Name,
@ -96,7 +99,7 @@ func (plugin *glusterfsPlugin) newBuilderInternal(spec *volume.Spec, ep *api.End
}, },
hosts: ep, hosts: ep,
path: source.Path, path: source.Path,
readonly: source.ReadOnly, readonly: readOnly,
exe: exe}, nil exe: exe}, nil
} }

View File

@ -39,6 +39,7 @@ type iscsiPlugin struct {
} }
var _ volume.VolumePlugin = &iscsiPlugin{} var _ volume.VolumePlugin = &iscsiPlugin{}
var _ volume.PersistentVolumePlugin = &iscsiPlugin{}
const ( const (
iscsiPluginName = "kubernetes.io/iscsi" 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) { 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 var iscsi *api.ISCSIVolumeSource
if spec.VolumeSource.ISCSI != nil { if spec.VolumeSource.ISCSI != nil {
iscsi = spec.VolumeSource.ISCSI iscsi = spec.VolumeSource.ISCSI
readOnly = iscsi.ReadOnly
} else { } else {
iscsi = spec.PersistentVolumeSource.ISCSI iscsi = spec.PersistentVolumeSource.ISCSI
readOnly = spec.ReadOnly
} }
lun := strconv.Itoa(iscsi.Lun) lun := strconv.Itoa(iscsi.Lun)
@ -99,9 +105,8 @@ func (plugin *iscsiPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UI
manager: manager, manager: manager,
mounter: mounter, mounter: mounter,
plugin: plugin}, plugin: plugin},
fsType: iscsi.FSType, fsType: iscsi.FSType,
readOnly: iscsi.ReadOnly, readOnly: readOnly,
}, nil }, nil
} }

View File

@ -78,7 +78,7 @@ func (plugin *persistentClaimPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod,
return nil, err 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 { if err != nil {
glog.Errorf("Error creating builder for claim: %+v\n", claim.Name) glog.Errorf("Error creating builder for claim: %+v\n", claim.Name)
return nil, err return nil, err

View File

@ -134,6 +134,7 @@ type Spec struct {
Name string Name string
VolumeSource api.VolumeSource VolumeSource api.VolumeSource
PersistentVolumeSource api.PersistentVolumeSource PersistentVolumeSource api.PersistentVolumeSource
ReadOnly bool
} }
// NewSpecFromVolume creates an Spec from an api.Volume // 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 // NewSpecFromPersistentVolume creates an Spec from an api.PersistentVolume
func NewSpecFromPersistentVolume(pv *api.PersistentVolume) *Spec { func NewSpecFromPersistentVolume(pv *api.PersistentVolume, readOnly bool) *Spec {
return &Spec{ return &Spec{
Name: pv.Name, Name: pv.Name,
PersistentVolumeSource: pv.Spec.PersistentVolumeSource, PersistentVolumeSource: pv.Spec.PersistentVolumeSource,
ReadOnly: readOnly,
} }
} }

View File

@ -43,7 +43,7 @@ func TestSpecSourceConverters(t *testing.T) {
}, },
} }
converted = NewSpecFromPersistentVolume(pv) converted = NewSpecFromPersistentVolume(pv, false)
if converted.PersistentVolumeSource.AWSElasticBlockStore == nil { if converted.PersistentVolumeSource.AWSElasticBlockStore == nil {
t.Errorf("Unexpected nil AWSElasticBlockStore: %+v", converted) t.Errorf("Unexpected nil AWSElasticBlockStore: %+v", converted)
} }

View File

@ -39,6 +39,7 @@ type rbdPlugin struct {
} }
var _ volume.VolumePlugin = &rbdPlugin{} var _ volume.VolumePlugin = &rbdPlugin{}
var _ volume.PersistentVolumePlugin = &rbdPlugin{}
const ( const (
rbdPluginName = "kubernetes.io/rbd" 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) { func (plugin *rbdPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, _ volume.VolumeOptions, mounter mount.Interface) (volume.Builder, error) {
secret := "" secret := ""
source := plugin.getRBDVolumeSource(spec) source, _ := plugin.getRBDVolumeSource(spec)
if source.SecretRef != nil { if source.SecretRef != nil {
kubeClient := plugin.host.GetKubeClient() 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) 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 { if spec.VolumeSource.RBD != nil {
return spec.VolumeSource.RBD return spec.VolumeSource.RBD, spec.VolumeSource.RBD.ReadOnly
} else { } 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) { 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 pool := source.RBDPool
if pool == "" { if pool == "" {
pool = "rbd" pool = "rbd"
@ -126,7 +129,7 @@ func (plugin *rbdPlugin) newBuilderInternal(spec *volume.Spec, podUID types.UID,
volName: spec.Name, volName: spec.Name,
Image: source.RBDImage, Image: source.RBDImage,
Pool: pool, Pool: pool,
ReadOnly: source.ReadOnly, ReadOnly: readOnly,
manager: manager, manager: manager,
mounter: mounter, mounter: mounter,
plugin: plugin, plugin: plugin,