Merge pull request #74653 from cofyc/fix74650-CheckVolumeExistenceOperation

Distinguish between volume path and mount path
pull/564/head
Kubernetes Prow Robot 2019-03-06 20:35:40 -08:00 committed by GitHub
commit 8dd60281ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 24 deletions

View File

@ -341,7 +341,7 @@ func (rc *reconciler) StatesHasBeenSynced() bool {
type podVolume struct { type podVolume struct {
podName volumetypes.UniquePodName podName volumetypes.UniquePodName
volumeSpecName string volumeSpecName string
mountPath string volumePath string
pluginName string pluginName string
volumeMode v1.PersistentVolumeMode volumeMode v1.PersistentVolumeMode
} }
@ -477,7 +477,7 @@ func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume,
pod.UID, pod.UID,
volume.podName, volume.podName,
volume.volumeSpecName, volume.volumeSpecName,
volume.mountPath, volume.volumePath,
volume.pluginName) volume.pluginName)
if err != nil { if err != nil {
return nil, err return nil, err
@ -492,15 +492,6 @@ func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume,
} else { } else {
uniqueVolumeName = util.GetUniqueVolumeNameFromSpecWithPod(volume.podName, plugin, volumeSpec) uniqueVolumeName = util.GetUniqueVolumeNameFromSpecWithPod(volume.podName, plugin, volumeSpec)
} }
// Check existence of mount point for filesystem volume or symbolic link for block volume
isExist, checkErr := rc.operationExecutor.CheckVolumeExistenceOperation(volumeSpec, volume.mountPath, volumeSpec.Name(), rc.mounter, uniqueVolumeName, volume.podName, pod.UID, attachablePlugin)
if checkErr != nil {
return nil, checkErr
}
// If mount or symlink doesn't exist, volume reconstruction should be failed
if !isExist {
return nil, fmt.Errorf("Volume: %q is not mounted", uniqueVolumeName)
}
volumeMounter, newMounterErr := plugin.NewMounter( volumeMounter, newMounterErr := plugin.NewMounter(
volumeSpec, volumeSpec,
@ -516,6 +507,16 @@ func (rc *reconciler) reconstructVolume(volume podVolume) (*reconstructedVolume,
newMounterErr) newMounterErr)
} }
// Check existence of mount point for filesystem volume or symbolic link for block volume
isExist, checkErr := rc.operationExecutor.CheckVolumeExistenceOperation(volumeSpec, volumeMounter.GetPath(), volumeSpec.Name(), rc.mounter, uniqueVolumeName, volume.podName, pod.UID, attachablePlugin)
if checkErr != nil {
return nil, checkErr
}
// If mount or symlink doesn't exist, volume reconstruction should be failed
if !isExist {
return nil, fmt.Errorf("Volume: %q is not mounted", uniqueVolumeName)
}
// TODO: remove feature gate check after no longer needed // TODO: remove feature gate check after no longer needed
var volumeMapper volumepkg.BlockVolumeMapper var volumeMapper volumepkg.BlockVolumeMapper
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && volume.volumeMode == v1.PersistentVolumeBlock { if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) && volume.volumeMode == v1.PersistentVolumeBlock {
@ -680,12 +681,12 @@ func getVolumesFromPodDir(podDir string) ([]podVolume, error) {
} }
unescapePluginName := utilstrings.UnescapeQualifiedName(pluginName) unescapePluginName := utilstrings.UnescapeQualifiedName(pluginName)
for _, volumeName := range volumePluginDirs { for _, volumeName := range volumePluginDirs {
mountPath := path.Join(volumePluginPath, volumeName) volumePath := path.Join(volumePluginPath, volumeName)
klog.V(5).Infof("podName: %v, mount path from volume plugin directory: %v, ", podName, mountPath) klog.V(5).Infof("podName: %v, volume path from volume plugin directory: %v, ", podName, volumePath)
volumes = append(volumes, podVolume{ volumes = append(volumes, podVolume{
podName: volumetypes.UniquePodName(podName), podName: volumetypes.UniquePodName(podName),
volumeSpecName: volumeName, volumeSpecName: volumeName,
mountPath: mountPath, volumePath: volumePath,
pluginName: unescapePluginName, pluginName: unescapePluginName,
volumeMode: volumeMode, volumeMode: volumeMode,
}) })

View File

@ -139,10 +139,10 @@ type VolumePlugin interface {
NewUnmounter(name string, podUID types.UID) (Unmounter, error) NewUnmounter(name string, podUID types.UID) (Unmounter, error)
// ConstructVolumeSpec constructs a volume spec based on the given volume name // ConstructVolumeSpec constructs a volume spec based on the given volume name
// and mountPath. The spec may have incomplete information due to limited // and volumePath. The spec may have incomplete information due to limited
// information from input. This function is used by volume manager to reconstruct // information from input. This function is used by volume manager to reconstruct
// volume spec by reading the volume directories from disk // volume spec by reading the volume directories from disk
ConstructVolumeSpec(volumeName, mountPath string) (*Spec, error) ConstructVolumeSpec(volumeName, volumePath string) (*Spec, error)
// SupportsMountOption returns true if volume plugins supports Mount options // SupportsMountOption returns true if volume plugins supports Mount options
// Specifying mount options in a volume plugin that doesn't support // Specifying mount options in a volume plugin that doesn't support
@ -275,7 +275,7 @@ type BlockVolumePlugin interface {
// The spec may have incomplete information due to limited information // The spec may have incomplete information due to limited information
// from input. This function is used by volume manager to reconstruct // from input. This function is used by volume manager to reconstruct
// volume spec by reading the volume directories from disk. // volume spec by reading the volume directories from disk.
ConstructBlockVolumeSpec(podUID types.UID, volumeName, mountPath string) (*Spec, error) ConstructBlockVolumeSpec(podUID types.UID, volumeName, volumePath string) (*Spec, error)
} }
// VolumeHost is an interface that plugins can use to access the kubelet. // VolumeHost is an interface that plugins can use to access the kubelet.

View File

@ -145,7 +145,7 @@ type OperationExecutor interface {
// ExpandVolumeFSWithoutUnmounting will resize volume's file system to expected size without unmounting the volume. // ExpandVolumeFSWithoutUnmounting will resize volume's file system to expected size without unmounting the volume.
ExpandVolumeFSWithoutUnmounting(volumeToMount VolumeToMount, actualStateOfWorld ActualStateOfWorldMounterUpdater) error ExpandVolumeFSWithoutUnmounting(volumeToMount VolumeToMount, actualStateOfWorld ActualStateOfWorldMounterUpdater) error
// ReconstructVolumeOperation construct a new volumeSpec and returns it created by plugin // ReconstructVolumeOperation construct a new volumeSpec and returns it created by plugin
ReconstructVolumeOperation(volumeMode v1.PersistentVolumeMode, plugin volume.VolumePlugin, mapperPlugin volume.BlockVolumePlugin, uid types.UID, podName volumetypes.UniquePodName, volumeSpecName string, mountPath string, pluginName string) (*volume.Spec, error) ReconstructVolumeOperation(volumeMode v1.PersistentVolumeMode, plugin volume.VolumePlugin, mapperPlugin volume.BlockVolumePlugin, uid types.UID, podName volumetypes.UniquePodName, volumeSpecName string, volumePath string, pluginName string) (*volume.Spec, error)
// CheckVolumeExistenceOperation checks volume existence // CheckVolumeExistenceOperation checks volume existence
CheckVolumeExistenceOperation(volumeSpec *volume.Spec, mountPath, volumeName string, mounter mount.Interface, uniqueVolumeName v1.UniqueVolumeName, podName volumetypes.UniquePodName, podUID types.UID, attachable volume.AttachableVolumePlugin) (bool, error) CheckVolumeExistenceOperation(volumeSpec *volume.Spec, mountPath, volumeName string, mounter mount.Interface, uniqueVolumeName v1.UniqueVolumeName, podName volumetypes.UniquePodName, podUID types.UID, attachable volume.AttachableVolumePlugin) (bool, error)
} }
@ -862,14 +862,14 @@ func (oe *operationExecutor) ReconstructVolumeOperation(
uid types.UID, uid types.UID,
podName volumetypes.UniquePodName, podName volumetypes.UniquePodName,
volumeSpecName string, volumeSpecName string,
mountPath string, volumePath string,
pluginName string) (*volume.Spec, error) { pluginName string) (*volume.Spec, error) {
// Filesystem Volume case // Filesystem Volume case
if volumeMode == v1.PersistentVolumeFilesystem { if volumeMode == v1.PersistentVolumeFilesystem {
// Create volumeSpec from mount path // Create volumeSpec from mount path
klog.V(5).Infof("Starting operationExecutor.ReconstructVolumepodName") klog.V(5).Infof("Starting operationExecutor.ReconstructVolumepodName")
volumeSpec, err := plugin.ConstructVolumeSpec(volumeSpecName, mountPath) volumeSpec, err := plugin.ConstructVolumeSpec(volumeSpecName, volumePath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -886,17 +886,17 @@ func (oe *operationExecutor) ReconstructVolumeOperation(
podName, podName,
uid) uid)
} }
// mountPath contains volumeName on the path. In the case of block volume, {volumeName} is symbolic link // volumePath contains volumeName on the path. In the case of block volume, {volumeName} is symbolic link
// corresponding to raw block device. // corresponding to raw block device.
// ex. mountPath: pods/{podUid}}/{DefaultKubeletVolumeDevicesDirName}/{escapeQualifiedPluginName}/{volumeName} // ex. volumePath: pods/{podUid}}/{DefaultKubeletVolumeDevicesDirName}/{escapeQualifiedPluginName}/{volumeName}
volumeSpec, err := mapperPlugin.ConstructBlockVolumeSpec(uid, volumeSpecName, mountPath) volumeSpec, err := mapperPlugin.ConstructBlockVolumeSpec(uid, volumeSpecName, volumePath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return volumeSpec, nil return volumeSpec, nil
} }
// CheckVolumeExistenceOperation return a func() to check mount path directory if volume still exists // CheckVolumeExistenceOperation checks mount path directory if volume still exists
func (oe *operationExecutor) CheckVolumeExistenceOperation( func (oe *operationExecutor) CheckVolumeExistenceOperation(
volumeSpec *volume.Spec, volumeSpec *volume.Spec,
mountPath, volumeName string, mountPath, volumeName string,