mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Add GetAccessModes to volume plugin interface
This commit is contained in:
		@@ -195,6 +195,32 @@ type VolumeSource struct {
 | 
			
		||||
	NFS *NFSVolumeSource `json:"nfs"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PersistentVolumeSource is similar to VolumeSource but meant for the administrator who creates PVs.
 | 
			
		||||
// Exactly one of its members must be set.
 | 
			
		||||
type PersistentVolumeSource struct {
 | 
			
		||||
	// GCEPersistentDisk represents a GCE Disk resource that is attached to a
 | 
			
		||||
	// kubelet's host machine and then exposed to the pod.
 | 
			
		||||
	GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"persistentDisk"`
 | 
			
		||||
	// HostPath represents a directory on the host.
 | 
			
		||||
	// This is useful for development and testing only.
 | 
			
		||||
	// on-host storage is not supported in any way
 | 
			
		||||
	HostPath *HostPathVolumeSource `json:"hostPath"`
 | 
			
		||||
	// NFS represents an NFS mount on the host that shares a pod's lifetime
 | 
			
		||||
	NFS *NFSVolumeSource `json:"nfs"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// used by VolumeSources to describe their mounting/access modes
 | 
			
		||||
type AccessModeType string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// can be mounted read/write mode to exactly 1 host
 | 
			
		||||
	ReadWriteOnce AccessModeType = "ReadWriteOnce"
 | 
			
		||||
	// can be mounted in read-only mode to many hosts
 | 
			
		||||
	ReadOnlyMany AccessModeType = "ReadOnlyMany"
 | 
			
		||||
	// can be mounted in read/write mode to many hosts
 | 
			
		||||
	ReadWriteMany AccessModeType = "ReadWriteMany"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// HostPathVolumeSource represents a host directory mapped into a pod.
 | 
			
		||||
type HostPathVolumeSource struct {
 | 
			
		||||
	Path string `json:"path"`
 | 
			
		||||
 
 | 
			
		||||
@@ -109,6 +109,32 @@ type VolumeSource struct {
 | 
			
		||||
	NFS *NFSVolumeSource `json:"nfs" description:"NFS volume that will be mounted in the host machine "`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PersistentVolumeSource is similar to VolumeSource but meant for the administrator who creates PVs.
 | 
			
		||||
// Exactly one of its members must be set.
 | 
			
		||||
type PersistentVolumeSource struct {
 | 
			
		||||
	// GCEPersistentDisk represents a GCE Disk resource that is attached to a
 | 
			
		||||
	// kubelet's host machine and then exposed to the pod.
 | 
			
		||||
	GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"persistentDisk" description:"GCE disk resource attached to the host machine on demand"`
 | 
			
		||||
	// HostPath represents a directory on the host.
 | 
			
		||||
	// This is useful for development and testing only.
 | 
			
		||||
	// on-host storage is not supported in any way
 | 
			
		||||
	HostPath *HostPathVolumeSource `json:"hostPath" description:"Persistent hostPath volume useful for development and testing"`
 | 
			
		||||
	// NFS represents an NFS mount on the host that shares a pod's lifetime
 | 
			
		||||
	NFS *NFSVolumeSource `json:"nfs" description:"Persistent NFS volume that will be mounted in the host machine"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// used by VolumeSources to describe their mounting/access modes
 | 
			
		||||
type AccessModeType string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// can be mounted read/write mode to exactly 1 host
 | 
			
		||||
	ReadWriteOnce AccessModeType = "ReadWriteOnce"
 | 
			
		||||
	// can be mounted in read-only mode to many hosts
 | 
			
		||||
	ReadOnlyMany AccessModeType = "ReadOnlyMany"
 | 
			
		||||
	// can be mounted in read/write mode to many hosts
 | 
			
		||||
	ReadWriteMany AccessModeType = "ReadWriteMany"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// HostPathVolumeSource represents bare host directory volume.
 | 
			
		||||
type HostPathVolumeSource struct {
 | 
			
		||||
	Path string `json:"path" description:"path of the directory on the host"`
 | 
			
		||||
 
 | 
			
		||||
@@ -82,6 +82,32 @@ type VolumeSource struct {
 | 
			
		||||
	NFS *NFSVolumeSource `json:"nfs" description:"NFS volume that will be mounted in the host machine"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PersistentVolumeSource is similar to VolumeSource but meant for the administrator who creates PVs.
 | 
			
		||||
// Exactly one of its members must be set.
 | 
			
		||||
type PersistentVolumeSource struct {
 | 
			
		||||
	// GCEPersistentDisk represents a GCE Disk resource that is attached to a
 | 
			
		||||
	// kubelet's host machine and then exposed to the pod.
 | 
			
		||||
	GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"persistentDisk" description:"GCE disk resource attached to the host machine on demand"`
 | 
			
		||||
	// HostPath represents a directory on the host.
 | 
			
		||||
	// This is useful for development and testing only.
 | 
			
		||||
	// on-host storage is not supported in any way
 | 
			
		||||
	HostPath *HostPathVolumeSource `json:"hostPath" description:"Persistent hostPath volume useful for development and testing"`
 | 
			
		||||
	// NFS represents an NFS mount on the host that shares a pod's lifetime
 | 
			
		||||
	NFS *NFSVolumeSource `json:"nfs" description:"Persistent NFS volume that will be mounted in the host machine"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// used by VolumeSources to describe their mounting/access modes
 | 
			
		||||
type AccessModeType string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// can be mounted read/write mode to exactly 1 host
 | 
			
		||||
	ReadWriteOnce AccessModeType = "ReadWriteOnce"
 | 
			
		||||
	// can be mounted in read-only mode to many hosts
 | 
			
		||||
	ReadOnlyMany AccessModeType = "ReadOnlyMany"
 | 
			
		||||
	// can be mounted in read/write mode to many hosts
 | 
			
		||||
	ReadWriteMany AccessModeType = "ReadWriteMany"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// HostPathVolumeSource represents bare host directory volume.
 | 
			
		||||
//
 | 
			
		||||
// https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md#hostdir
 | 
			
		||||
 
 | 
			
		||||
@@ -214,6 +214,32 @@ type VolumeSource struct {
 | 
			
		||||
	NFS *NFSVolumeSource `json:"nfs" description:"NFS volume that will be mounted in the host machine"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PersistentVolumeSource is similar to VolumeSource but meant for the administrator who creates PVs.
 | 
			
		||||
// Exactly one of its members must be set.
 | 
			
		||||
type PersistentVolumeSource struct {
 | 
			
		||||
	// GCEPersistentDisk represents a GCE Disk resource that is attached to a
 | 
			
		||||
	// kubelet's host machine and then exposed to the pod.
 | 
			
		||||
	GCEPersistentDisk *GCEPersistentDiskVolumeSource `json:"persistentDisk" description:"GCE disk resource attached to the host machine on demand"`
 | 
			
		||||
	// HostPath represents a directory on the host.
 | 
			
		||||
	// This is useful for development and testing only.
 | 
			
		||||
	// on-host storage is not supported in any way
 | 
			
		||||
	HostPath *HostPathVolumeSource `json:"hostPath" description:"Persistent hostPath volume useful for development and testing"`
 | 
			
		||||
	// NFS represents an NFS mount on the host that shares a pod's lifetime
 | 
			
		||||
	NFS *NFSVolumeSource `json:"nfs" description:"Persistent NFS volume that will be mounted in the host machine"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// used by VolumeSources to describe their mounting/access modes
 | 
			
		||||
type AccessModeType string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// can be mounted read/write mode to exactly 1 host
 | 
			
		||||
	ReadWriteOnce AccessModeType = "ReadWriteOnce"
 | 
			
		||||
	// can be mounted in read-only mode to many hosts
 | 
			
		||||
	ReadOnlyMany AccessModeType = "ReadOnlyMany"
 | 
			
		||||
	// can be mounted in read/write mode to many hosts
 | 
			
		||||
	ReadWriteMany AccessModeType = "ReadWriteMany"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// HostPathVolumeSource represents bare host directory volume.
 | 
			
		||||
type HostPathVolumeSource struct {
 | 
			
		||||
	Path string `json:"path" description:"path of the directory on the host"`
 | 
			
		||||
 
 | 
			
		||||
@@ -71,6 +71,13 @@ func (plugin *gcePersistentDiskPlugin) CanSupport(spec *api.Volume) bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (plugin *gcePersistentDiskPlugin) GetAccessModes() []api.AccessModeType {
 | 
			
		||||
	return []api.AccessModeType{
 | 
			
		||||
		api.ReadWriteOnce,
 | 
			
		||||
		api.ReadOnlyMany,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (plugin *gcePersistentDiskPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference) (volume.Builder, error) {
 | 
			
		||||
	// Inject real implementations here, test through the internal function.
 | 
			
		||||
	return plugin.newBuilderInternal(spec, podRef.UID, &GCEDiskUtil{}, mount.New())
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,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/gce-pd")
 | 
			
		||||
	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 fakePDManager struct{}
 | 
			
		||||
 | 
			
		||||
// TODO(jonesdl) To fully test this, we could create a loopback device
 | 
			
		||||
 
 | 
			
		||||
@@ -54,6 +54,12 @@ func (plugin *hostPathPlugin) CanSupport(spec *api.Volume) bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (plugin *hostPathPlugin) GetAccessModes() []api.AccessModeType {
 | 
			
		||||
	return []api.AccessModeType{
 | 
			
		||||
		api.ReadWriteOnce,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (plugin *hostPathPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference) (volume.Builder, error) {
 | 
			
		||||
	return &hostPath{spec.HostPath.Path}, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,19 @@ 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/host-path")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("Can't find the plugin by name")
 | 
			
		||||
	}
 | 
			
		||||
	if len(plug.GetAccessModes()) != 1 || plug.GetAccessModes()[0] != api.ReadWriteOnce {
 | 
			
		||||
		t.Errorf("Expected %s AccessModeType", api.ReadWriteOnce)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPlugin(t *testing.T) {
 | 
			
		||||
	plugMgr := volume.VolumePluginMgr{}
 | 
			
		||||
	plugMgr.InitPlugins(ProbeVolumePlugins(), volume.NewFakeVolumeHost("fake", nil, nil))
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,14 @@ func (plugin *nfsPlugin) CanSupport(spec *api.Volume) bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (plugin *nfsPlugin) GetAccessModes() []api.AccessModeType {
 | 
			
		||||
	return []api.AccessModeType{
 | 
			
		||||
		api.ReadWriteOnce,
 | 
			
		||||
		api.ReadOnlyMany,
 | 
			
		||||
		api.ReadWriteMany,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (plugin *nfsPlugin) NewBuilder(spec *api.Volume, podRef *api.ObjectReference) (volume.Builder, error) {
 | 
			
		||||
	return plugin.newBuilderInternal(spec, podRef, plugin.mounter)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,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/nfs")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("Can't find the plugin by name")
 | 
			
		||||
	}
 | 
			
		||||
	if !contains(plug.GetAccessModes(), api.ReadWriteOnce) || !contains(plug.GetAccessModes(), api.ReadOnlyMany) || !contains(plug.GetAccessModes(), api.ReadWriteMany) {
 | 
			
		||||
		t.Errorf("Expected three AccessModeTypes:  %s, %s, and %s", api.ReadWriteOnce, api.ReadOnlyMany, api.ReadWriteMany)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func contains(modes []api.AccessModeType, mode api.AccessModeType) bool {
 | 
			
		||||
	for _, m := range modes {
 | 
			
		||||
		if m == mode {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type fakeNFSMounter struct {
 | 
			
		||||
	FakeMounter mount.FakeMounter
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -59,6 +59,14 @@ type VolumePlugin interface {
 | 
			
		||||
	NewCleaner(name string, podUID types.UID) (Cleaner, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PersistentVolumePlugin is an extended interface of VolumePlugin and is used
 | 
			
		||||
// by volumes that want to provide long term persistence of data
 | 
			
		||||
type PersistentVolumePlugin interface {
 | 
			
		||||
	VolumePlugin
 | 
			
		||||
	// GetAccessModes describes the ways a given volume can be accessed/mounted.
 | 
			
		||||
	GetAccessModes() []api.AccessModeType
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VolumeHost is an interface that plugins can use to access the kubelet.
 | 
			
		||||
type VolumeHost interface {
 | 
			
		||||
	// GetPluginDir returns the absolute path to a directory under which
 | 
			
		||||
@@ -173,3 +181,24 @@ func (pm *VolumePluginMgr) FindPluginByName(name string) (VolumePlugin, error) {
 | 
			
		||||
	}
 | 
			
		||||
	return pm.plugins[matches[0]], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindPersistentPluginBySpec looks for a plugin that can support a given volume
 | 
			
		||||
// specification.  If no plugins can support or more than one plugin can
 | 
			
		||||
// support it, return error.
 | 
			
		||||
func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *api.Volume) (PersistentVolumePlugin, error) {
 | 
			
		||||
	volumePlugin, err := pm.FindPluginBySpec(spec)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return volumePlugin.(PersistentVolumePlugin), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindPluginByName fetches a plugin by name or by legacy name.  If no plugin
 | 
			
		||||
// is found, returns error.
 | 
			
		||||
func (pm *VolumePluginMgr) FindPersistentPluginByName(name string) (PersistentVolumePlugin, error) {
 | 
			
		||||
	volumePlugin, err := pm.FindPluginByName(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return volumePlugin.(PersistentVolumePlugin), nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,7 @@ func (f *fakeVolumeHost) NewWrapperCleaner(spec *api.Volume, podUID types.UID) (
 | 
			
		||||
	return plug.NewCleaner(spec.Name, podUID)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FakeVolumePlugin is useful for for testing.  It tries to be a fully compliant
 | 
			
		||||
// FakeVolumePlugin is useful for testing.  It tries to be a fully compliant
 | 
			
		||||
// plugin, but all it does is make empty directories.
 | 
			
		||||
// Use as:
 | 
			
		||||
//   volume.RegisterPlugin(&FakePlugin{"fake-name"})
 | 
			
		||||
@@ -103,6 +103,10 @@ func (plugin *FakeVolumePlugin) NewCleaner(volName string, podUID types.UID) (Cl
 | 
			
		||||
	return &FakeVolume{podUID, volName, plugin}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (plugin *FakeVolumePlugin) GetAccessModes() []api.AccessModeType {
 | 
			
		||||
	return []api.AccessModeType{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type FakeVolume struct {
 | 
			
		||||
	PodUID  types.UID
 | 
			
		||||
	VolName string
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user