Documentation ¶
Overview ¶
Package util contains utility code for use by volume plugins.
Index ¶
- Constants
- func AccessModesContainedInAll(indexedModes []v1.PersistentVolumeAccessMode, ...) bool
- func AccessModesContains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool
- func CalculateTimeoutForVolume(minimumTimeout, timeoutIncrement int, pv *v1.PersistentVolume) int64
- func CheckNodeAffinity(pv *v1.PersistentVolume, nodeLabels map[string]string) error
- func CheckPersistentVolumeClaimModeBlock(pvc *v1.PersistentVolumeClaim) bool
- func CheckVolumeModeFilesystem(volumeSpec *volume.Spec) (bool, error)
- func ChooseZoneForVolume(zones sets.String, pvcName string) string
- func ChooseZonesForVolume(zones sets.String, pvcName string, numZones uint32) sets.String
- func ClaimToClaimKey(claim *v1.PersistentVolumeClaim) string
- func GenerateVolumeName(clusterName, pvName string, maxLength int) string
- func GenericResizeFS(host volume.VolumeHost, pluginName, devicePath, deviceMountPath string) (bool, error)
- func GetCSIAttachLimitKey(driverName string) string
- func GetClassForVolume(kubeClient clientset.Interface, pv *v1.PersistentVolume) (*storage.StorageClass, error)
- func GetFullQualifiedPluginNameForVolume(pluginName string, spec *volume.Spec) string
- func GetPath(mounter volume.Mounter) (string, error)
- func GetPersistentVolumeClaimQualifiedName(claim *v1.PersistentVolumeClaim) string
- func GetPersistentVolumeClaimVolumeMode(claim *v1.PersistentVolumeClaim) (v1.PersistentVolumeMode, error)
- func GetSecretForPV(secretNamespace, secretName, volumePluginName string, ...) (map[string]string, error)
- func GetSecretForPod(pod *v1.Pod, secretName string, kubeClient clientset.Interface) (map[string]string, error)
- func GetUniquePodName(pod *v1.Pod) types.UniquePodName
- func GetUniqueVolumeName(pluginName, volumeName string) v1.UniqueVolumeName
- func GetUniqueVolumeNameForNonAttachableVolume(podName types.UniquePodName, volumePlugin volume.VolumePlugin, ...) v1.UniqueVolumeName
- func GetUniqueVolumeNameFromSpec(volumePlugin volume.VolumePlugin, volumeSpec *volume.Spec) (v1.UniqueVolumeName, error)
- func GetVolumeMode(volumeSpec *volume.Spec) (v1.PersistentVolumeMode, error)
- func GetWindowsPath(path string) string
- func IsCorruptedMnt(err error) bool
- func IsPodTerminated(pod *v1.Pod, podStatus v1.PodStatus) bool
- func IsReady(dir string) bool
- func IsWindowsLocalPath(goos, path string) bool
- func IsWindowsUNCPath(goos, path string) bool
- func JoinMountOptions(userOptions []string, systemOptions []string) []string
- func LabelZonesToList(labelZonesValue string) ([]string, error)
- func LabelZonesToSet(labelZonesValue string) (sets.String, error)
- func LoadPodFromFile(filePath string) (*v1.Pod, error)
- func MakeAbsolutePath(goos, path string) string
- func MakeNestedMountpoints(name, baseDir string, pod v1.Pod) error
- func MapBlockVolume(devicePath, globalMapPath, podVolumeMapPath, volumeMapName string, ...) error
- func MarkFSResizeFinished(pvc *v1.PersistentVolumeClaim, capacity v1.ResourceList, ...) error
- func MergeResizeConditionOnPVC(pvc *v1.PersistentVolumeClaim, ...) *v1.PersistentVolumeClaim
- func MountOptionFromSpec(spec *volume.Spec, options ...string) []string
- func NewDanglingError(msg string, node k8stypes.NodeName, devicePath string) error
- func NewSafeFormatAndMountFromHost(pluginName string, host volume.VolumeHost) *mount.SafeFormatAndMount
- func OperationCompleteHook(plugin, operationName string) func(*error)
- func PatchPVCStatus(oldPVC *v1.PersistentVolumeClaim, newPVC *v1.PersistentVolumeClaim, ...) (*v1.PersistentVolumeClaim, error)
- func PathExists(path string) (bool, error)
- func RoundUpSize(volumeSizeBytes int64, allocationUnitBytes int64) int64
- func RoundUpSizeInt(volumeSizeBytes int64, allocationUnitBytes int64) (int, error)
- func RoundUpToGB(size resource.Quantity) int64
- func RoundUpToGBInt(size resource.Quantity) (int, error)
- func RoundUpToGiB(size resource.Quantity) int64
- func RoundUpToGiBInt(size resource.Quantity) (int, error)
- func SelectZoneForVolume(zoneParameterPresent, zonesParameterPresent bool, zoneParameter string, ...) (string, error)
- func SelectZonesForVolume(zoneParameterPresent, zonesParameterPresent bool, zoneParameter string, ...) (sets.String, error)
- func SetReady(dir string)
- func SplitUniqueName(uniqueName v1.UniqueVolumeName) (string, string, error)
- func UnmountMountPoint(mountPath string, mounter mount.Interface, extensiveMountPointCheck bool) error
- func UnmountPath(mountPath string, mounter mount.Interface) error
- func UnmountViaEmptyDir(dir string, host volume.VolumeHost, volName string, volSpec volume.Spec, ...) error
- func ValidateZone(zone string) error
- func ZonesFromAllowedTopologies(allowedTopologies []v1.TopologySelectorTerm) (sets.String, error)
- func ZonesSetToLabelValue(strSet sets.String) string
- func ZonesToSet(zonesString string) (sets.String, error)
- type AtomicWriter
- type DanglingAttachError
- type DeviceUtil
- type FileProjection
- type IoUtil
- type VolumeZoneConfig
Constants ¶
const ( // EBSVolumeLimitKey resource name that will store volume limits for EBS EBSVolumeLimitKey = "attachable-volumes-aws-ebs" // EBSNitroLimitRegex finds nitro instance types with different limit than EBS defaults EBSNitroLimitRegex = "^[cmr]5.*|t3|z1d" // DefaultMaxEBSVolumes is the limit for volumes attached to an instance. // Amazon recommends no more than 40; the system root volume uses at least one. // See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/volume_limits.html#linux-specific-volume-limits DefaultMaxEBSVolumes = 39 // DefaultMaxEBSNitroVolumeLimit is default EBS volume limit on m5 and c5 instances DefaultMaxEBSNitroVolumeLimit = 25 // AzureVolumeLimitKey stores resource name that will store volume limits for Azure AzureVolumeLimitKey = "attachable-volumes-azure-disk" // GCEVolumeLimitKey stores resource name that will store volume limits for GCE node GCEVolumeLimitKey = "attachable-volumes-gce-pd" // CSIAttachLimitPrefix defines prefix used for CSI volumes CSIAttachLimitPrefix = "attachable-volumes-csi-" // ResourceNameLengthLimit stores maximum allowed Length for a ResourceName ResourceNameLengthLimit = 63 )
const ( // PVCProtectionFinalizer is the name of finalizer on PVCs that have a running pod. PVCProtectionFinalizer = "kubernetes.io/pvc-protection" // PVProtectionFinalizer is the name of finalizer on PVs that are bound by PVCs PVProtectionFinalizer = "kubernetes.io/pv-protection" )
const ( // GB - GigaByte size GB = 1000 * 1000 * 1000 // GIB - GibiByte size GIB = 1024 * 1024 * 1024 // ControllerManagedAttachAnnotation is the key of the annotation on Node // objects that indicates attach/detach operations for the node should be // managed by the attach/detach controller ControllerManagedAttachAnnotation string = "volumes.kubernetes.io/controller-managed-attach-detach" // KeepTerminatedPodVolumesAnnotation is the key of the annotation on Node // that decides if pod volumes are unmounted when pod is terminated KeepTerminatedPodVolumesAnnotation string = "volumes.kubernetes.io/keep-terminated-pod-volumes" // VolumeGidAnnotationKey is the of the annotation on the PersistentVolume // object that specifies a supplemental GID. VolumeGidAnnotationKey = "pv.beta.kubernetes.io/gid" // VolumeDynamicallyCreatedByKey is the key of the annotation on PersistentVolume // object created dynamically VolumeDynamicallyCreatedByKey = "kubernetes.io/createdby" )
Variables ¶
This section is empty.
Functions ¶
func AccessModesContainedInAll ¶
func AccessModesContainedInAll(indexedModes []v1.PersistentVolumeAccessMode, requestedModes []v1.PersistentVolumeAccessMode) bool
AccessModesContainedInAll returns whether all of the requested modes are contained by modes
func AccessModesContains ¶
func AccessModesContains(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool
AccessModesContains returns whether the requested mode is contained by modes
func CalculateTimeoutForVolume ¶
func CalculateTimeoutForVolume(minimumTimeout, timeoutIncrement int, pv *v1.PersistentVolume) int64
CalculateTimeoutForVolume calculates time for a Recycler pod to complete a recycle operation. The calculation and return value is either the minimumTimeout or the timeoutIncrement per Gi of storage size, whichever is greater.
func CheckNodeAffinity ¶
func CheckNodeAffinity(pv *v1.PersistentVolume, nodeLabels map[string]string) error
CheckNodeAffinity looks at the PV node affinity, and checks if the node has the same corresponding labels This ensures that we don't mount a volume that doesn't belong to this node
func CheckPersistentVolumeClaimModeBlock ¶
func CheckPersistentVolumeClaimModeBlock(pvc *v1.PersistentVolumeClaim) bool
CheckPersistentVolumeClaimModeBlock checks VolumeMode. If the mode is Block, return true otherwise return false.
func CheckVolumeModeFilesystem ¶
CheckVolumeModeFilesystem checks VolumeMode. If the mode is Filesystem, return true otherwise return false.
func ChooseZoneForVolume ¶
ChooseZoneForVolume implements our heuristics for choosing a zone for volume creation based on the volume name Volumes are generally round-robin-ed across all active zones, using the hash of the PVC Name. However, if the PVCName ends with `-<integer>`, we will hash the prefix, and then add the integer to the hash. This means that a StatefulSet's volumes (`claimname-statefulsetname-id`) will spread across available zones, assuming the id values are consecutive.
func ChooseZonesForVolume ¶
ChooseZonesForVolume is identical to ChooseZoneForVolume, but selects a multiple zones, for multi-zone disks.
func ClaimToClaimKey ¶
func ClaimToClaimKey(claim *v1.PersistentVolumeClaim) string
ClaimToClaimKey return namespace/name string for pvc
func GenerateVolumeName ¶
GenerateVolumeName returns a PV name with clusterName prefix. The function should be used to generate a name of GCE PD or Cinder volume. It basically adds "<clusterName>-dynamic-" before the PV name, making sure the resulting string fits given length and cuts "dynamic" if not.
func GenericResizeFS ¶
func GenericResizeFS(host volume.VolumeHost, pluginName, devicePath, deviceMountPath string) (bool, error)
GenericResizeFS : call generic filesystem resizer for plugins that don't have any special filesystem resize requirements
func GetCSIAttachLimitKey ¶
GetCSIAttachLimitKey returns limit key used for CSI volumes
func GetClassForVolume ¶
func GetClassForVolume(kubeClient clientset.Interface, pv *v1.PersistentVolume) (*storage.StorageClass, error)
GetClassForVolume locates storage class by persistent volume
func GetFullQualifiedPluginNameForVolume ¶
GetFullQualifiedPluginNameForVolume returns full qualified plugin name for given volume. For CSI plugin, it appends plugin driver name at the end of plugin name, e.g. kubernetes.io/csi:csi-hostpath. It helps to distinguish between metrics emitted for CSI volumes which may be handled by different CSI plugin drivers.
func GetPersistentVolumeClaimQualifiedName ¶
func GetPersistentVolumeClaimQualifiedName(claim *v1.PersistentVolumeClaim) string
GetPersistentVolumeClaimQualifiedName returns a qualified name for pvc.
func GetPersistentVolumeClaimVolumeMode ¶
func GetPersistentVolumeClaimVolumeMode(claim *v1.PersistentVolumeClaim) (v1.PersistentVolumeMode, error)
GetPersistentVolumeClaimVolumeMode retrieves VolumeMode from pvc.
func GetSecretForPV ¶
func GetSecretForPV(secretNamespace, secretName, volumePluginName string, kubeClient clientset.Interface) (map[string]string, error)
GetSecretForPV locates secret by name and namespace, verifies the secret type, and returns secret map
func GetSecretForPod ¶
func GetSecretForPod(pod *v1.Pod, secretName string, kubeClient clientset.Interface) (map[string]string, error)
GetSecretForPod locates secret by name in the pod's namespace and returns secret map
func GetUniquePodName ¶
func GetUniquePodName(pod *v1.Pod) types.UniquePodName
GetUniquePodName returns a unique identifier to reference a pod by
func GetUniqueVolumeName ¶
func GetUniqueVolumeName(pluginName, volumeName string) v1.UniqueVolumeName
GetUniqueVolumeName returns a unique name representing the volume/plugin. Caller should ensure that volumeName is a name/ID uniquely identifying the actual backing device, directory, path, etc. for a particular volume. The returned name can be used to uniquely reference the volume, for example, to prevent operations (attach/detach or mount/unmount) from being triggered on the same volume.
func GetUniqueVolumeNameForNonAttachableVolume ¶
func GetUniqueVolumeNameForNonAttachableVolume( podName types.UniquePodName, volumePlugin volume.VolumePlugin, volumeSpec *volume.Spec) v1.UniqueVolumeName
GetUniqueVolumeNameForNonAttachableVolume returns the unique volume name for a non-attachable volume.
func GetUniqueVolumeNameFromSpec ¶
func GetUniqueVolumeNameFromSpec( volumePlugin volume.VolumePlugin, volumeSpec *volume.Spec) (v1.UniqueVolumeName, error)
GetUniqueVolumeNameFromSpec uses the given VolumePlugin to generate a unique name representing the volume defined in the specified volume spec. This returned name can be used to uniquely reference the actual backing device, directory, path, etc. referenced by the given volumeSpec. If the given plugin does not support the volume spec, this returns an error.
func GetVolumeMode ¶
func GetVolumeMode(volumeSpec *volume.Spec) (v1.PersistentVolumeMode, error)
GetVolumeMode retrieves VolumeMode from pv. If the volume doesn't have PersistentVolume, it's an inline volume, should return volumeMode as filesystem to keep existing behavior.
func IsCorruptedMnt ¶
IsCorruptedMnt return true if err is about corrupted mount point
func IsPodTerminated ¶
IsPodTerminated checks if pod is terminated
func IsReady ¶
IsReady checks for the existence of a regular file called 'ready' in the given directory and returns true if that file exists.
func IsWindowsLocalPath ¶
IsWindowsLocalPath checks if path is a local path prefixed with "/" or "\" like "/foo/bar" or "\foo\bar"
func IsWindowsUNCPath ¶
IsWindowsUNCPath checks if path is prefixed with \\ This can be used to skip any processing of paths that point to SMB shares, local named pipes and local UNC path
func JoinMountOptions ¶
JoinMountOptions joins mount options eliminating duplicates
func LabelZonesToList ¶
LabelZonesToList converts a PV label value from string containing a delimited list of zones to list
func LabelZonesToSet ¶
LabelZonesToSet converts a PV label value from string containing a delimited list of zones to set
func LoadPodFromFile ¶
LoadPodFromFile will read, decode, and return a Pod from a file.
func MakeAbsolutePath ¶
MakeAbsolutePath convert path to absolute path according to GOOS
func MakeNestedMountpoints ¶
MakeNestedMountpoints creates mount points in baseDir for volumes mounted beneath name
func MapBlockVolume ¶
func MapBlockVolume( devicePath, globalMapPath, podVolumeMapPath, volumeMapName string, podUID utypes.UID, ) error
MapBlockVolume is a utility function to provide a common way of mounting block device path for a specified volume and pod. This function should be called by volume plugins that implements volume.BlockVolumeMapper.Map() method.
func MarkFSResizeFinished ¶
func MarkFSResizeFinished( pvc *v1.PersistentVolumeClaim, capacity v1.ResourceList, kubeClient clientset.Interface) error
MarkFSResizeFinished marks file system resizing as done
func MergeResizeConditionOnPVC ¶
func MergeResizeConditionOnPVC( pvc *v1.PersistentVolumeClaim, resizeConditions []v1.PersistentVolumeClaimCondition) *v1.PersistentVolumeClaim
MergeResizeConditionOnPVC updates pvc with requested resize conditions leaving other conditions untouched.
func MountOptionFromSpec ¶
MountOptionFromSpec extracts and joins mount options from volume spec with supplied options
func NewDanglingError ¶
NewDanglingError create a new dangling error
func NewSafeFormatAndMountFromHost ¶
func NewSafeFormatAndMountFromHost(pluginName string, host volume.VolumeHost) *mount.SafeFormatAndMount
NewSafeFormatAndMountFromHost creates a new SafeFormatAndMount with Mounter and Exec taken from given VolumeHost.
func OperationCompleteHook ¶
OperationCompleteHook returns a hook to call when an operation is completed
func PatchPVCStatus ¶
func PatchPVCStatus( oldPVC *v1.PersistentVolumeClaim, newPVC *v1.PersistentVolumeClaim, kubeClient clientset.Interface) (*v1.PersistentVolumeClaim, error)
PatchPVCStatus updates PVC status using PATCH verb
func PathExists ¶
PathExists returns true if the specified path exists.
func RoundUpSize ¶
RoundUpSize calculates how many allocation units are needed to accommodate a volume of given size. E.g. when user wants 1500MiB volume, while AWS EBS allocates volumes in gibibyte-sized chunks, RoundUpSize(1500 * 1024*1024, 1024*1024*1024) returns '2' (2 GiB is the smallest allocatable volume that can hold 1500MiB)
func RoundUpSizeInt ¶
RoundUpSizeInt calculates how many allocation units are needed to accommodate a volume of given size. It returns an int instead of an int64 and an error if there's overflow
func RoundUpToGB ¶
RoundUpToGB rounds up given quantity to chunks of GB
func RoundUpToGBInt ¶
RoundUpToGBInt rounds up given quantity to chunks of GB. It returns an int instead of an int64 and an error if there's overflow
func RoundUpToGiB ¶
RoundUpToGiB rounds up given quantity upto chunks of GiB
func RoundUpToGiBInt ¶
RoundUpToGiBInt rounds up given quantity upto chunks of GiB. It returns an int instead of an int64 and an error if there's overflow
func SelectZoneForVolume ¶
func SelectZoneForVolume(zoneParameterPresent, zonesParameterPresent bool, zoneParameter string, zonesParameter, zonesWithNodes sets.String, node *v1.Node, allowedTopologies []v1.TopologySelectorTerm, pvcName string) (string, error)
SelectZoneForVolume is a wrapper around SelectZonesForVolume to select a single zone for a volume based on parameters
func SelectZonesForVolume ¶
func SelectZonesForVolume(zoneParameterPresent, zonesParameterPresent bool, zoneParameter string, zonesParameter, zonesWithNodes sets.String, node *v1.Node, allowedTopologies []v1.TopologySelectorTerm, pvcName string, numReplicas uint32) (sets.String, error)
SelectZonesForVolume selects zones for a volume based on several factors: node.zone, allowedTopologies, zone/zones parameters from storageclass, zones with active nodes from the cluster. The number of zones = replicas.
func SetReady ¶
func SetReady(dir string)
SetReady creates a file called 'ready' in the given directory. It logs an error if the file cannot be created.
func SplitUniqueName ¶
func SplitUniqueName(uniqueName v1.UniqueVolumeName) (string, string, error)
SplitUniqueName splits the unique name to plugin name and volume name strings. It expects the uniqueName to follow the format plugin_name/volume_name and the plugin name must be namespaced as described by the plugin interface, i.e. namespace/plugin containing exactly one '/'. This means the unique name will always be in the form of plugin_namespace/plugin/volume_name, see k8s.io/kubernetes/pkg/volume/plugins.go VolumePlugin interface description and pkg/volume/util/volumehelper/volumehelper.go GetUniqueVolumeNameFromSpec that constructs the unique volume names.
func UnmountMountPoint ¶
func UnmountMountPoint(mountPath string, mounter mount.Interface, extensiveMountPointCheck bool) error
UnmountMountPoint is a common unmount routine that unmounts the given path and deletes the remaining directory if successful. if extensiveMountPointCheck is true IsNotMountPoint will be called instead of IsLikelyNotMountPoint. IsNotMountPoint is more expensive but properly handles bind mounts.
func UnmountPath ¶
UnmountPath is a common unmount routine that unmounts the given path and deletes the remaining directory if successful.
func UnmountViaEmptyDir ¶
func UnmountViaEmptyDir(dir string, host volume.VolumeHost, volName string, volSpec volume.Spec, podUID utypes.UID) error
UnmountViaEmptyDir delegates the tear down operation for secret, configmap, git_repo and downwardapi to empty_dir
func ValidateZone ¶
ValidateZone returns: - an error in case zone is an empty string or contains only any combination of spaces and tab characters - nil otherwise
func ZonesFromAllowedTopologies ¶
func ZonesFromAllowedTopologies(allowedTopologies []v1.TopologySelectorTerm) (sets.String, error)
ZonesFromAllowedTopologies returns a list of zones specified in allowedTopologies
func ZonesSetToLabelValue ¶
ZonesSetToLabelValue converts zones set to label value
Types ¶
type AtomicWriter ¶
type AtomicWriter struct {
// contains filtered or unexported fields
}
AtomicWriter handles atomically projecting content for a set of files into a target directory.
Note:
- AtomicWriter reserves the set of pathnames starting with `..`.
- AtomicWriter offers no concurrency guarantees and must be synchronized by the caller.
The visible files in this volume are symlinks to files in the writer's data directory. Actual files are stored in a hidden timestamped directory which is symlinked to by the data directory. The timestamped directory and data directory symlink are created in the writer's target dir. This scheme allows the files to be atomically updated by changing the target of the data directory symlink.
Consumers of the target directory can monitor the ..data symlink using inotify or fanotify to receive events when the content in the volume is updated.
func NewAtomicWriter ¶
func NewAtomicWriter(targetDir string, logContext string) (*AtomicWriter, error)
NewAtomicWriter creates a new AtomicWriter configured to write to the given target directory, or returns an error if the target directory does not exist.
func (*AtomicWriter) Write ¶
func (w *AtomicWriter) Write(payload map[string]FileProjection) error
Write does an atomic projection of the given payload into the writer's target directory. Input paths must not begin with '..'.
The Write algorithm is:
The payload is validated; if the payload is invalid, the function returns 2. The current timestamped directory is detected by reading the data directory symlink
The old version of the volume is walked to determine whether any portion of the payload was deleted and is still present on disk.
The data in the current timestamped directory is compared to the projected data to determine if an update is required. 5. A new timestamped dir is created
The payload is written to the new timestamped directory 7. Symlinks and directory for new user-visible files are created (if needed).
For example, consider the files: <target-dir>/podName <target-dir>/user/labels <target-dir>/k8s/annotations
The user visible files are symbolic links into the internal data directory: <target-dir>/podName -> ..data/podName <target-dir>/usr -> ..data/usr <target-dir>/k8s -> ..data/k8s
The data directory itself is a link to a timestamped directory with the real data: <target-dir>/..data -> ..2016_02_01_15_04_05.12345678/ 8. A symlink to the new timestamped directory ..data_tmp is created that will become the new data directory 9. The new data directory symlink is renamed to the data directory; rename is atomic
10. Old paths are removed from the user-visible portion of the target directory 11. The previous timestamped directory is removed, if it exists
type DanglingAttachError ¶
type DanglingAttachError struct { CurrentNode k8stypes.NodeName DevicePath string // contains filtered or unexported fields }
DanglingAttachError indicates volume is attached to a different node than we expected.
func (*DanglingAttachError) Error ¶
func (err *DanglingAttachError) Error() string
type DeviceUtil ¶
type DeviceUtil interface { FindMultipathDeviceForDevice(disk string) string FindSlaveDevicesOnMultipath(disk string) []string GetISCSIPortalHostMapForTarget(targetIqn string) (map[string]int, error) FindDevicesForISCSILun(targetIqn string, lun int) ([]string, error) }
DeviceUtil is a util for common device methods
func NewDeviceHandler ¶
func NewDeviceHandler(io IoUtil) DeviceUtil
NewDeviceHandler Create a new IoHandler implementation
type FileProjection ¶
FileProjection contains file Data and access Mode
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package nestedpendingoperations is a modified implementation of pkg/util/goroutinemap.
|
Package nestedpendingoperations is a modified implementation of pkg/util/goroutinemap. |
Package operationexecutor implements interfaces that enable execution of attach, detach, mount, and unmount operations with a nestedpendingoperations so that more than one operation is never triggered on the same volume for the same pod.
|
Package operationexecutor implements interfaces that enable execution of attach, detach, mount, and unmount operations with a nestedpendingoperations so that more than one operation is never triggered on the same volume for the same pod. |
Package types defines types used only by volume components
|
Package types defines types used only by volume components |