Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap comments in pkg/volume #26807

Merged
merged 1 commit into from
Jun 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
157 changes: 93 additions & 64 deletions pkg/volume/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,24 @@ import (

// VolumeOptions contains option information about a volume.
type VolumeOptions struct {
// The rootcontext to use when performing mounts for a volume.
// This is a temporary measure in order to set the rootContext of tmpfs mounts correctly.
// it will be replaced and expanded on by future SecurityContext work.
// The rootcontext to use when performing mounts for a volume. This is a
// temporary measure in order to set the rootContext of tmpfs mounts
// correctly. it will be replaced and expanded on by future
// SecurityContext work.
RootContext string

// The attributes below are required by volume.Provisioner
// TODO: refactor all of this out of volumes when an admin can configure many kinds of provisioners.
// TODO: refactor all of this out of volumes when an admin can configure
// many kinds of provisioners.

// Capacity is the size of a volume.
Capacity resource.Quantity
// AccessModes of a volume
AccessModes []api.PersistentVolumeAccessMode
// Reclamation policy for a persistent volume
PersistentVolumeReclaimPolicy api.PersistentVolumeReclaimPolicy
// PV.Name of the appropriate PersistentVolume. Used to generate cloud volume name.
// PV.Name of the appropriate PersistentVolume. Used to generate cloud
// volume name.
PVName string
// Unique name of Kubernetes cluster.
ClusterName string
Expand Down Expand Up @@ -96,20 +99,23 @@ type PersistentVolumePlugin interface {
}

// RecyclableVolumePlugin is an extended interface of VolumePlugin and is used
// by persistent volumes that want to be recycled before being made available again to new claims
// by persistent volumes that want to be recycled before being made available
// again to new claims
type RecyclableVolumePlugin interface {
VolumePlugin
// NewRecycler creates a new volume.Recycler which knows how to reclaim this resource
// after the volume's release from a PersistentVolumeClaim
// NewRecycler creates a new volume.Recycler which knows how to reclaim
// this resource after the volume's release from a PersistentVolumeClaim
NewRecycler(pvName string, spec *Spec) (Recycler, error)
}

// DeletableVolumePlugin is an extended interface of VolumePlugin and is used by persistent volumes that want
// to be deleted from the cluster after their release from a PersistentVolumeClaim.
// DeletableVolumePlugin is an extended interface of VolumePlugin and is used
// by persistent volumes that want to be deleted from the cluster after their
// release from a PersistentVolumeClaim.
type DeletableVolumePlugin interface {
VolumePlugin
// NewDeleter creates a new volume.Deleter which knows how to delete this resource
// in accordance with the underlying storage provider after the volume's release from a claim
// NewDeleter creates a new volume.Deleter which knows how to delete this
// resource in accordance with the underlying storage provider after the
// volume's release from a claim
NewDeleter(spec *Spec) (Deleter, error)
}

Expand All @@ -119,11 +125,13 @@ const (
ProvisionedVolumeName = "placeholder-for-provisioning"
)

// ProvisionableVolumePlugin is an extended interface of VolumePlugin and is used to create volumes for the cluster.
// ProvisionableVolumePlugin is an extended interface of VolumePlugin and is
// used to create volumes for the cluster.
type ProvisionableVolumePlugin interface {
VolumePlugin
// NewProvisioner creates a new volume.Provisioner which knows how to create PersistentVolumes in accordance with
// the plugin's underlying storage provider
// NewProvisioner creates a new volume.Provisioner which knows how to
// create PersistentVolumes in accordance with the plugin's underlying
// storage provider
NewProvisioner(options VolumeOptions) (Provisioner, error)
}

Expand Down Expand Up @@ -212,42 +220,54 @@ func (spec *Spec) Name() string {
}
}

// VolumeConfig is how volume plugins receive configuration. An instance specific to the plugin will be passed to
// the plugin's ProbeVolumePlugins(config) func. Reasonable defaults will be provided by the binary hosting
// the plugins while allowing override of those default values. Those config values are then set to an instance of
// VolumeConfig and passed to the plugin.
// VolumeConfig is how volume plugins receive configuration. An instance
// specific to the plugin will be passed to the plugin's
// ProbeVolumePlugins(config) func. Reasonable defaults will be provided by
// the binary hosting the plugins while allowing override of those default
// values. Those config values are then set to an instance of VolumeConfig
// and passed to the plugin.
//
// Values in VolumeConfig are intended to be relevant to several plugins, but not necessarily all plugins. The
// preference is to leverage strong typing in this struct. All config items must have a descriptive but non-specific
// name (i.e, RecyclerMinimumTimeout is OK but RecyclerMinimumTimeoutForNFS is !OK). An instance of config will be
// given directly to the plugin, so config names specific to plugins are unneeded and wrongly expose plugins
// in this VolumeConfig struct.
// Values in VolumeConfig are intended to be relevant to several plugins, but
// not necessarily all plugins. The preference is to leverage strong typing
// in this struct. All config items must have a descriptive but non-specific
// name (i.e, RecyclerMinimumTimeout is OK but RecyclerMinimumTimeoutForNFS is
// !OK). An instance of config will be given directly to the plugin, so
// config names specific to plugins are unneeded and wrongly expose plugins in
// this VolumeConfig struct.
//
// OtherAttributes is a map of string values intended for one-off configuration of a plugin or config that is only
// relevant to a single plugin. All values are passed by string and require interpretation by the plugin.
// Passing config as strings is the least desirable option but can be used for truly one-off configuration.
// The binary should still use strong typing for this value when binding CLI values before they are passed as strings
// in OtherAttributes.
// OtherAttributes is a map of string values intended for one-off
// configuration of a plugin or config that is only relevant to a single
// plugin. All values are passed by string and require interpretation by the
// plugin. Passing config as strings is the least desirable option but can be
// used for truly one-off configuration. The binary should still use strong
// typing for this value when binding CLI values before they are passed as
// strings in OtherAttributes.
type VolumeConfig struct {
// RecyclerPodTemplate is pod template that understands how to scrub clean a persistent volume after its release.
// The template is used by plugins which override specific properties of the pod in accordance with that plugin.
// See NewPersistentVolumeRecyclerPodTemplate for the properties that are expected to be overridden.
// RecyclerPodTemplate is pod template that understands how to scrub clean
// a persistent volume after its release. The template is used by plugins
// which override specific properties of the pod in accordance with that
// plugin. See NewPersistentVolumeRecyclerPodTemplate for the properties
// that are expected to be overridden.
RecyclerPodTemplate *api.Pod

// RecyclerMinimumTimeout is the minimum amount of time in seconds for the recycler pod's ActiveDeadlineSeconds attribute.
// Added to the minimum timeout is the increment per Gi of capacity.
// RecyclerMinimumTimeout is the minimum amount of time in seconds for the
// recycler pod's ActiveDeadlineSeconds attribute. Added to the minimum
// timeout is the increment per Gi of capacity.
RecyclerMinimumTimeout int

// RecyclerTimeoutIncrement is the number of seconds added to the recycler pod's ActiveDeadlineSeconds for each
// Gi of capacity in the persistent volume.
// Example: 5Gi volume x 30s increment = 150s + 30s minimum = 180s ActiveDeadlineSeconds for recycler pod
// RecyclerTimeoutIncrement is the number of seconds added to the recycler
// pod's ActiveDeadlineSeconds for each Gi of capacity in the persistent
// volume. Example: 5Gi volume x 30s increment = 150s + 30s minimum = 180s
// ActiveDeadlineSeconds for recycler pod
RecyclerTimeoutIncrement int

// PVName is name of the PersistentVolume instance that is being recycled. It is used to generate unique recycler pod name.
// PVName is name of the PersistentVolume instance that is being recycled.
// It is used to generate unique recycler pod name.
PVName string

// OtherAttributes stores config as strings. These strings are opaque to the system and only understood by the binary
// hosting the plugin and the plugin itself.
// OtherAttributes stores config as strings. These strings are opaque to
// the system and only understood by the binary hosting the plugin and the
// plugin itself.
OtherAttributes map[string]string
}

Expand Down Expand Up @@ -345,8 +365,9 @@ func (pm *VolumePluginMgr) FindPluginByName(name string) (VolumePlugin, error) {
return pm.plugins[matches[0]], nil
}

// FindPersistentPluginBySpec looks for a persistent volume plugin that can support a given volume
// specification. If no plugin is found, return an error
// FindPersistentPluginBySpec looks for a persistent volume plugin that can
// support a given volume specification. If no plugin is found, return an
// error
func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *Spec) (PersistentVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil {
Expand All @@ -358,8 +379,8 @@ func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *Spec) (PersistentVol
return nil, fmt.Errorf("no persistent volume plugin matched")
}

// FindPersistentPluginByName fetches a persistent volume plugin by name. If no plugin
// is found, returns error.
// FindPersistentPluginByName fetches a persistent volume plugin by name. If
// no plugin is found, returns error.
func (pm *VolumePluginMgr) FindPersistentPluginByName(name string) (PersistentVolumePlugin, error) {
volumePlugin, err := pm.FindPluginByName(name)
if err != nil {
Expand All @@ -371,8 +392,8 @@ func (pm *VolumePluginMgr) FindPersistentPluginByName(name string) (PersistentVo
return nil, fmt.Errorf("no persistent volume plugin matched")
}

// FindRecyclablePluginByName fetches a persistent volume plugin by name. If no plugin
// is found, returns error.
// FindRecyclablePluginByName fetches a persistent volume plugin by name. If
// no plugin is found, returns error.
func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil {
Expand All @@ -384,8 +405,8 @@ func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVol
return nil, fmt.Errorf("no recyclable volume plugin matched")
}

// FindDeletablePluginByName fetches a persistent volume plugin by name. If no plugin
// is found, returns error.
// FindDeletablePluginByName fetches a persistent volume plugin by name. If
// no plugin is found, returns error.
func (pm *VolumePluginMgr) FindDeletablePluginBySpec(spec *Spec) (DeletableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil {
Expand All @@ -397,8 +418,8 @@ func (pm *VolumePluginMgr) FindDeletablePluginBySpec(spec *Spec) (DeletableVolum
return nil, fmt.Errorf("no deletable volume plugin matched")
}

// FindCreatablePluginBySpec fetches a persistent volume plugin by name. If no plugin
// is found, returns error.
// FindCreatablePluginBySpec fetches a persistent volume plugin by name. If
// no plugin is found, returns error.
func (pm *VolumePluginMgr) FindCreatablePluginBySpec(spec *Spec) (ProvisionableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil {
Expand All @@ -410,9 +431,10 @@ func (pm *VolumePluginMgr) FindCreatablePluginBySpec(spec *Spec) (ProvisionableV
return nil, fmt.Errorf("no creatable volume plugin matched")
}

// FindAttachablePluginBySpec fetches a persistent volume plugin by name. Unlike the other "FindPlugin" methods, this
// does not return error if no plugin is found. All volumes require a mounter and unmounter, but not every volume will
// have an attacher/detacher.
// FindAttachablePluginBySpec fetches a persistent volume plugin by name.
// Unlike the other "FindPlugin" methods, this does not return error if no
// plugin is found. All volumes require a mounter and unmounter, but not
// every volume will have an attacher/detacher.
func (pm *VolumePluginMgr) FindAttachablePluginBySpec(spec *Spec) (AttachableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil {
Expand All @@ -424,9 +446,10 @@ func (pm *VolumePluginMgr) FindAttachablePluginBySpec(spec *Spec) (AttachableVol
return nil, nil
}

// FindAttachablePluginByName fetches an attachable volume plugin by name. Unlike the other "FindPlugin" methods, this
// does not return error if no plugin is found. All volumes require a mounter and unmounter, but not every volume will
// have an attacher/detacher.
// FindAttachablePluginByName fetches an attachable volume plugin by name.
// Unlike the other "FindPlugin" methods, this does not return error if no
// plugin is found. All volumes require a mounter and unmounter, but not
// every volume will have an attacher/detacher.
func (pm *VolumePluginMgr) FindAttachablePluginByName(name string) (AttachableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginByName(name)
if err != nil {
Expand All @@ -438,13 +461,18 @@ func (pm *VolumePluginMgr) FindAttachablePluginByName(name string) (AttachableVo
return nil, nil
}

// NewPersistentVolumeRecyclerPodTemplate creates a template for a recycler pod. By default, a recycler pod simply runs
// "rm -rf" on a volume and tests for emptiness. Most attributes of the template will be correct for most
// plugin implementations. The following attributes can be overridden per plugin via configuration:
// NewPersistentVolumeRecyclerPodTemplate creates a template for a recycler
// pod. By default, a recycler pod simply runs "rm -rf" on a volume and tests
// for emptiness. Most attributes of the template will be correct for most
// plugin implementations. The following attributes can be overridden per
// plugin via configuration:
//
// 1. pod.Spec.Volumes[0].VolumeSource must be overridden. Recycler implementations without a valid VolumeSource will fail.
// 2. pod.GenerateName helps distinguish recycler pods by name. Recommended. Default is "pv-recycler-".
// 3. pod.Spec.ActiveDeadlineSeconds gives the recycler pod a maximum timeout before failing. Recommended. Default is 60 seconds.
// 1. pod.Spec.Volumes[0].VolumeSource must be overridden. Recycler
// implementations without a valid VolumeSource will fail.
// 2. pod.GenerateName helps distinguish recycler pods by name. Recommended.
// Default is "pv-recycler-".
// 3. pod.Spec.ActiveDeadlineSeconds gives the recycler pod a maximum timeout
// before failing. Recommended. Default is 60 seconds.
//
// See HostPath and NFS for working recycler examples
func NewPersistentVolumeRecyclerPodTemplate() *api.Pod {
Expand All @@ -460,8 +488,9 @@ func NewPersistentVolumeRecyclerPodTemplate() *api.Pod {
Volumes: []api.Volume{
{
Name: "vol",
// IMPORTANT! All plugins using this template MUST override pod.Spec.Volumes[0].VolumeSource
// Recycler implementations without a valid VolumeSource will fail.
// IMPORTANT! All plugins using this template MUST
// override pod.Spec.Volumes[0].VolumeSource Recycler
// implementations without a valid VolumeSource will fail.
VolumeSource: api.VolumeSource{},
},
},
Expand Down
47 changes: 27 additions & 20 deletions pkg/volume/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,23 @@ import (
"k8s.io/kubernetes/pkg/util/mount"
)

// Volume represents a directory used by pods or hosts on a node.
// All method implementations of methods in the volume interface must be idempotent.
// Volume represents a directory used by pods or hosts on a node. All method
// implementations of methods in the volume interface must be idempotent.
type Volume interface {
// GetPath returns the path to which the volume should be
// mounted for the pod.
// GetPath returns the path to which the volume should be mounted for the
// pod.
GetPath() string

// MetricsProvider embeds methods for exposing metrics (e.g. used,available space).
// MetricsProvider embeds methods for exposing metrics (e.g.
// used, available space).
MetricsProvider
}

// MetricsProvider exposes metrics (e.g. used,available space) related to a Volume.
// MetricsProvider exposes metrics (e.g. used,available space) related to a
// Volume.
type MetricsProvider interface {
// GetMetrics returns the Metrics for the Volume. Maybe expensive for some implementations.
// GetMetrics returns the Metrics for the Volume. Maybe expensive for
// some implementations.
GetMetrics() (*Metrics, error)
}

Expand All @@ -50,14 +53,16 @@ type Metrics struct {
// Note: For block devices this maybe more than the total size of the files.
Used *resource.Quantity

// Capacity represents the total capacity (bytes) of the volume's underlying storage.
// For Volumes that share a filesystem with the host (e.g. emptydir, hostpath) this is the size
// of the underlying storage, and will not equal Used + Available as the fs is shared.
// Capacity represents the total capacity (bytes) of the volume's
// underlying storage. For Volumes that share a filesystem with the host
// (e.g. emptydir, hostpath) this is the size of the underlying storage,
// and will not equal Used + Available as the fs is shared.
Capacity *resource.Quantity

// Available represents the storage space available (bytes) for the Volume.
// For Volumes that share a filesystem with the host (e.g. emptydir, hostpath), this is the available
// space on the underlying storage, and is shared with host processes and other Volumes.
// Available represents the storage space available (bytes) for the
// Volume. For Volumes that share a filesystem with the host (e.g.
// emptydir, hostpath), this is the available space on the underlying
// storage, and is shared with host processes and other Volumes.
Available *resource.Quantity
}

Expand Down Expand Up @@ -103,23 +108,25 @@ type Unmounter interface {
// Recycler provides methods to reclaim the volume resource.
type Recycler interface {
Volume
// Recycle reclaims the resource. Calls to this method should block until the recycling task is complete.
// Any error returned indicates the volume has failed to be reclaimed. A nil return indicates success.
// Recycle reclaims the resource. Calls to this method should block until
// the recycling task is complete. Any error returned indicates the volume
// has failed to be reclaimed. A nil return indicates success.
Recycle() error
}

// Provisioner is an interface that creates templates for PersistentVolumes and can create the volume
// as a new resource in the infrastructure provider.
// Provisioner is an interface that creates templates for PersistentVolumes
// and can create the volume as a new resource in the infrastructure provider.
type Provisioner interface {
// Provision creates the resource by allocating the underlying volume in a
// storage system. This method should block until completion and returns
// PersistentVolume representing the created storage resource.
Provision() (*api.PersistentVolume, error)
}

// Deleter removes the resource from the underlying storage provider. Calls to this method should block until
// the deletion is complete. Any error returned indicates the volume has failed to be reclaimed.
// A nil return indicates success.
// Deleter removes the resource from the underlying storage provider. Calls
// to this method should block until the deletion is complete. Any error
// returned indicates the volume has failed to be reclaimed. A nil return
// indicates success.
type Deleter interface {
Volume
// This method should block until completion.
Expand Down