mirror of https://github.com/k3s-io/k3s
Merge pull request #74653 from cofyc/fix74650-CheckVolumeExistenceOperation
Distinguish between volume path and mount pathpull/564/head
commit
8dd60281ff
|
@ -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,
|
||||||
})
|
})
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue