Wrap comments in pkg/volume

This commit is contained in:
Paul Morie 2016-06-03 16:16:57 -04:00
parent a00dbea133
commit 029b97d5a1
2 changed files with 120 additions and 84 deletions

View File

@ -35,13 +35,15 @@ import (
// VolumeOptions contains option information about a volume. // VolumeOptions contains option information about a volume.
type VolumeOptions struct { type VolumeOptions struct {
// The rootcontext to use when performing mounts for a volume. // The rootcontext to use when performing mounts for a volume. This is a
// This is a temporary measure in order to set the rootContext of tmpfs mounts correctly. // temporary measure in order to set the rootContext of tmpfs mounts
// it will be replaced and expanded on by future SecurityContext work. // correctly. it will be replaced and expanded on by future
// SecurityContext work.
RootContext string RootContext string
// The attributes below are required by volume.Provisioner // 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 is the size of a volume.
Capacity resource.Quantity Capacity resource.Quantity
@ -49,7 +51,8 @@ type VolumeOptions struct {
AccessModes []api.PersistentVolumeAccessMode AccessModes []api.PersistentVolumeAccessMode
// Reclamation policy for a persistent volume // Reclamation policy for a persistent volume
PersistentVolumeReclaimPolicy api.PersistentVolumeReclaimPolicy 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 PVName string
// Unique name of Kubernetes cluster. // Unique name of Kubernetes cluster.
ClusterName string ClusterName string
@ -96,20 +99,23 @@ type PersistentVolumePlugin interface {
} }
// RecyclableVolumePlugin is an extended interface of VolumePlugin and is used // 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 { type RecyclableVolumePlugin interface {
VolumePlugin VolumePlugin
// NewRecycler creates a new volume.Recycler which knows how to reclaim this resource // NewRecycler creates a new volume.Recycler which knows how to reclaim
// after the volume's release from a PersistentVolumeClaim // this resource after the volume's release from a PersistentVolumeClaim
NewRecycler(pvName string, spec *Spec) (Recycler, error) NewRecycler(pvName string, spec *Spec) (Recycler, error)
} }
// DeletableVolumePlugin is an extended interface of VolumePlugin and is used by persistent volumes that want // DeletableVolumePlugin is an extended interface of VolumePlugin and is used
// to be deleted from the cluster after their release from a PersistentVolumeClaim. // by persistent volumes that want to be deleted from the cluster after their
// release from a PersistentVolumeClaim.
type DeletableVolumePlugin interface { type DeletableVolumePlugin interface {
VolumePlugin VolumePlugin
// NewDeleter creates a new volume.Deleter which knows how to delete this resource // NewDeleter creates a new volume.Deleter which knows how to delete this
// in accordance with the underlying storage provider after the volume's release from a claim // resource in accordance with the underlying storage provider after the
// volume's release from a claim
NewDeleter(spec *Spec) (Deleter, error) NewDeleter(spec *Spec) (Deleter, error)
} }
@ -119,11 +125,13 @@ const (
ProvisionedVolumeName = "placeholder-for-provisioning" 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 { type ProvisionableVolumePlugin interface {
VolumePlugin VolumePlugin
// NewProvisioner creates a new volume.Provisioner which knows how to create PersistentVolumes in accordance with // NewProvisioner creates a new volume.Provisioner which knows how to
// the plugin's underlying storage provider // create PersistentVolumes in accordance with the plugin's underlying
// storage provider
NewProvisioner(options VolumeOptions) (Provisioner, error) NewProvisioner(options VolumeOptions) (Provisioner, error)
} }
@ -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 // VolumeConfig is how volume plugins receive configuration. An instance
// the plugin's ProbeVolumePlugins(config) func. Reasonable defaults will be provided by the binary hosting // specific to the plugin will be passed to the plugin's
// the plugins while allowing override of those default values. Those config values are then set to an instance of // ProbeVolumePlugins(config) func. Reasonable defaults will be provided by
// VolumeConfig and passed to the plugin. // 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 // Values in VolumeConfig are intended to be relevant to several plugins, but
// preference is to leverage strong typing in this struct. All config items must have a descriptive but non-specific // not necessarily all plugins. The preference is to leverage strong typing
// name (i.e, RecyclerMinimumTimeout is OK but RecyclerMinimumTimeoutForNFS is !OK). An instance of config will be // in this struct. All config items must have a descriptive but non-specific
// given directly to the plugin, so config names specific to plugins are unneeded and wrongly expose plugins // name (i.e, RecyclerMinimumTimeout is OK but RecyclerMinimumTimeoutForNFS is
// in this VolumeConfig struct. // !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 // OtherAttributes is a map of string values intended for one-off
// relevant to a single plugin. All values are passed by string and require interpretation by the plugin. // configuration of a plugin or config that is only relevant to a single
// Passing config as strings is the least desirable option but can be used for truly one-off configuration. // plugin. All values are passed by string and require interpretation by the
// The binary should still use strong typing for this value when binding CLI values before they are passed as strings // plugin. Passing config as strings is the least desirable option but can be
// in OtherAttributes. // 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 { type VolumeConfig struct {
// RecyclerPodTemplate is pod template that understands how to scrub clean a persistent volume after its release. // RecyclerPodTemplate is pod template that understands how to scrub clean
// The template is used by plugins which override specific properties of the pod in accordance with that plugin. // a persistent volume after its release. The template is used by plugins
// See NewPersistentVolumeRecyclerPodTemplate for the properties that are expected to be overridden. // 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 RecyclerPodTemplate *api.Pod
// RecyclerMinimumTimeout is the minimum amount of time in seconds for the recycler pod's ActiveDeadlineSeconds attribute. // RecyclerMinimumTimeout is the minimum amount of time in seconds for the
// Added to the minimum timeout is the increment per Gi of capacity. // recycler pod's ActiveDeadlineSeconds attribute. Added to the minimum
// timeout is the increment per Gi of capacity.
RecyclerMinimumTimeout int RecyclerMinimumTimeout int
// RecyclerTimeoutIncrement is the number of seconds added to the recycler pod's ActiveDeadlineSeconds for each // RecyclerTimeoutIncrement is the number of seconds added to the recycler
// Gi of capacity in the persistent volume. // pod's ActiveDeadlineSeconds for each Gi of capacity in the persistent
// Example: 5Gi volume x 30s increment = 150s + 30s minimum = 180s ActiveDeadlineSeconds for recycler pod // volume. Example: 5Gi volume x 30s increment = 150s + 30s minimum = 180s
// ActiveDeadlineSeconds for recycler pod
RecyclerTimeoutIncrement int 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 PVName string
// OtherAttributes stores config as strings. These strings are opaque to the system and only understood by the binary // OtherAttributes stores config as strings. These strings are opaque to
// hosting the plugin and the plugin itself. // the system and only understood by the binary hosting the plugin and the
// plugin itself.
OtherAttributes map[string]string OtherAttributes map[string]string
} }
@ -345,8 +365,9 @@ func (pm *VolumePluginMgr) FindPluginByName(name string) (VolumePlugin, error) {
return pm.plugins[matches[0]], nil return pm.plugins[matches[0]], nil
} }
// FindPersistentPluginBySpec looks for a persistent volume plugin that can support a given volume // FindPersistentPluginBySpec looks for a persistent volume plugin that can
// specification. If no plugin is found, return an error // support a given volume specification. If no plugin is found, return an
// error
func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *Spec) (PersistentVolumePlugin, error) { func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *Spec) (PersistentVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec) volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil { if err != nil {
@ -358,8 +379,8 @@ func (pm *VolumePluginMgr) FindPersistentPluginBySpec(spec *Spec) (PersistentVol
return nil, fmt.Errorf("no persistent volume plugin matched") return nil, fmt.Errorf("no persistent volume plugin matched")
} }
// FindPersistentPluginByName fetches a persistent volume plugin by name. If no plugin // FindPersistentPluginByName fetches a persistent volume plugin by name. If
// is found, returns error. // no plugin is found, returns error.
func (pm *VolumePluginMgr) FindPersistentPluginByName(name string) (PersistentVolumePlugin, error) { func (pm *VolumePluginMgr) FindPersistentPluginByName(name string) (PersistentVolumePlugin, error) {
volumePlugin, err := pm.FindPluginByName(name) volumePlugin, err := pm.FindPluginByName(name)
if err != nil { if err != nil {
@ -371,8 +392,8 @@ func (pm *VolumePluginMgr) FindPersistentPluginByName(name string) (PersistentVo
return nil, fmt.Errorf("no persistent volume plugin matched") return nil, fmt.Errorf("no persistent volume plugin matched")
} }
// FindRecyclablePluginByName fetches a persistent volume plugin by name. If no plugin // FindRecyclablePluginByName fetches a persistent volume plugin by name. If
// is found, returns error. // no plugin is found, returns error.
func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVolumePlugin, error) { func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec) volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil { if err != nil {
@ -384,8 +405,8 @@ func (pm *VolumePluginMgr) FindRecyclablePluginBySpec(spec *Spec) (RecyclableVol
return nil, fmt.Errorf("no recyclable volume plugin matched") return nil, fmt.Errorf("no recyclable volume plugin matched")
} }
// FindDeletablePluginByName fetches a persistent volume plugin by name. If no plugin // FindDeletablePluginByName fetches a persistent volume plugin by name. If
// is found, returns error. // no plugin is found, returns error.
func (pm *VolumePluginMgr) FindDeletablePluginBySpec(spec *Spec) (DeletableVolumePlugin, error) { func (pm *VolumePluginMgr) FindDeletablePluginBySpec(spec *Spec) (DeletableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec) volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil { if err != nil {
@ -397,8 +418,8 @@ func (pm *VolumePluginMgr) FindDeletablePluginBySpec(spec *Spec) (DeletableVolum
return nil, fmt.Errorf("no deletable volume plugin matched") return nil, fmt.Errorf("no deletable volume plugin matched")
} }
// FindCreatablePluginBySpec fetches a persistent volume plugin by name. If no plugin // FindCreatablePluginBySpec fetches a persistent volume plugin by name. If
// is found, returns error. // no plugin is found, returns error.
func (pm *VolumePluginMgr) FindCreatablePluginBySpec(spec *Spec) (ProvisionableVolumePlugin, error) { func (pm *VolumePluginMgr) FindCreatablePluginBySpec(spec *Spec) (ProvisionableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec) volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil { if err != nil {
@ -410,9 +431,10 @@ func (pm *VolumePluginMgr) FindCreatablePluginBySpec(spec *Spec) (ProvisionableV
return nil, fmt.Errorf("no creatable volume plugin matched") return nil, fmt.Errorf("no creatable volume plugin matched")
} }
// FindAttachablePluginBySpec fetches a persistent volume plugin by name. Unlike the other "FindPlugin" methods, this // FindAttachablePluginBySpec fetches a persistent volume plugin by name.
// does not return error if no plugin is found. All volumes require a mounter and unmounter, but not every volume will // Unlike the other "FindPlugin" methods, this does not return error if no
// have an attacher/detacher. // 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) { func (pm *VolumePluginMgr) FindAttachablePluginBySpec(spec *Spec) (AttachableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginBySpec(spec) volumePlugin, err := pm.FindPluginBySpec(spec)
if err != nil { if err != nil {
@ -424,9 +446,10 @@ func (pm *VolumePluginMgr) FindAttachablePluginBySpec(spec *Spec) (AttachableVol
return nil, nil return nil, nil
} }
// FindAttachablePluginByName fetches an attachable volume plugin by name. Unlike the other "FindPlugin" methods, this // FindAttachablePluginByName fetches an attachable volume plugin by name.
// does not return error if no plugin is found. All volumes require a mounter and unmounter, but not every volume will // Unlike the other "FindPlugin" methods, this does not return error if no
// have an attacher/detacher. // 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) { func (pm *VolumePluginMgr) FindAttachablePluginByName(name string) (AttachableVolumePlugin, error) {
volumePlugin, err := pm.FindPluginByName(name) volumePlugin, err := pm.FindPluginByName(name)
if err != nil { if err != nil {
@ -438,13 +461,18 @@ func (pm *VolumePluginMgr) FindAttachablePluginByName(name string) (AttachableVo
return nil, nil return nil, nil
} }
// NewPersistentVolumeRecyclerPodTemplate creates a template for a recycler pod. By default, a recycler pod simply runs // NewPersistentVolumeRecyclerPodTemplate creates a template for a recycler
// "rm -rf" on a volume and tests for emptiness. Most attributes of the template will be correct for most // pod. By default, a recycler pod simply runs "rm -rf" on a volume and tests
// plugin implementations. The following attributes can be overridden per plugin via configuration: // 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. // 1. pod.Spec.Volumes[0].VolumeSource must be overridden. Recycler
// 2. pod.GenerateName helps distinguish recycler pods by name. Recommended. Default is "pv-recycler-". // implementations without a valid VolumeSource will fail.
// 3. pod.Spec.ActiveDeadlineSeconds gives the recycler pod a maximum timeout before failing. Recommended. Default is 60 seconds. // 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 // See HostPath and NFS for working recycler examples
func NewPersistentVolumeRecyclerPodTemplate() *api.Pod { func NewPersistentVolumeRecyclerPodTemplate() *api.Pod {
@ -460,8 +488,9 @@ func NewPersistentVolumeRecyclerPodTemplate() *api.Pod {
Volumes: []api.Volume{ Volumes: []api.Volume{
{ {
Name: "vol", Name: "vol",
// IMPORTANT! All plugins using this template MUST override pod.Spec.Volumes[0].VolumeSource // IMPORTANT! All plugins using this template MUST
// Recycler implementations without a valid VolumeSource will fail. // override pod.Spec.Volumes[0].VolumeSource Recycler
// implementations without a valid VolumeSource will fail.
VolumeSource: api.VolumeSource{}, VolumeSource: api.VolumeSource{},
}, },
}, },

View File

@ -27,20 +27,23 @@ import (
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
) )
// Volume represents a directory used by pods or hosts on a node. // Volume represents a directory used by pods or hosts on a node. All method
// All method implementations of methods in the volume interface must be idempotent. // implementations of methods in the volume interface must be idempotent.
type Volume interface { type Volume interface {
// GetPath returns the path to which the volume should be // GetPath returns the path to which the volume should be mounted for the
// mounted for the pod. // pod.
GetPath() string 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
} }
// 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 { 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) GetMetrics() (*Metrics, error)
} }
@ -50,14 +53,16 @@ type Metrics struct {
// Note: For block devices this maybe more than the total size of the files. // Note: For block devices this maybe more than the total size of the files.
Used *resource.Quantity Used *resource.Quantity
// Capacity represents the total capacity (bytes) of the volume's underlying storage. // Capacity represents the total capacity (bytes) of the volume's
// For Volumes that share a filesystem with the host (e.g. emptydir, hostpath) this is the size // underlying storage. For Volumes that share a filesystem with the host
// of the underlying storage, and will not equal Used + Available as the fs is shared. // (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 Capacity *resource.Quantity
// Available represents the storage space available (bytes) for the Volume. // Available represents the storage space available (bytes) for the
// For Volumes that share a filesystem with the host (e.g. emptydir, hostpath), this is the available // Volume. For Volumes that share a filesystem with the host (e.g.
// space on the underlying storage, and is shared with host processes and other Volumes. // emptydir, hostpath), this is the available space on the underlying
// storage, and is shared with host processes and other Volumes.
Available *resource.Quantity Available *resource.Quantity
} }
@ -103,13 +108,14 @@ type Unmounter interface {
// Recycler provides methods to reclaim the volume resource. // Recycler provides methods to reclaim the volume resource.
type Recycler interface { type Recycler interface {
Volume Volume
// Recycle reclaims the resource. Calls to this method should block until the recycling task is complete. // Recycle reclaims the resource. Calls to this method should block until
// Any error returned indicates the volume has failed to be reclaimed. A nil return indicates success. // the recycling task is complete. Any error returned indicates the volume
// has failed to be reclaimed. A nil return indicates success.
Recycle() error Recycle() error
} }
// Provisioner is an interface that creates templates for PersistentVolumes and can create the volume // Provisioner is an interface that creates templates for PersistentVolumes
// as a new resource in the infrastructure provider. // and can create the volume as a new resource in the infrastructure provider.
type Provisioner interface { type Provisioner interface {
// Provision creates the resource by allocating the underlying volume in a // Provision creates the resource by allocating the underlying volume in a
// storage system. This method should block until completion and returns // storage system. This method should block until completion and returns
@ -117,9 +123,10 @@ type Provisioner interface {
Provision() (*api.PersistentVolume, error) Provision() (*api.PersistentVolume, error)
} }
// Deleter removes the resource from the underlying storage provider. Calls to this method should block until // Deleter removes the resource from the underlying storage provider. Calls
// the deletion is complete. Any error returned indicates the volume has failed to be reclaimed. // to this method should block until the deletion is complete. Any error
// A nil return indicates success. // returned indicates the volume has failed to be reclaimed. A nil return
// indicates success.
type Deleter interface { type Deleter interface {
Volume Volume
// This method should block until completion. // This method should block until completion.