mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
Ensure volume mount err checking done inside op
Ensure volume mount error checking is done inside the operation so that failures get handled with exponential backoff, etc.
This commit is contained in:
parent
bf7efc6272
commit
2251bf0c21
@ -725,7 +725,7 @@ func (oe *operationExecutor) MountVolume(
|
|||||||
if fsVolume {
|
if fsVolume {
|
||||||
// Filesystem volume case
|
// Filesystem volume case
|
||||||
// Mount/remount a volume when a volume is attached
|
// Mount/remount a volume when a volume is attached
|
||||||
generatedOperations, err = oe.operationGenerator.GenerateMountVolumeFunc(
|
generatedOperations = oe.operationGenerator.GenerateMountVolumeFunc(
|
||||||
waitForAttachTimeout, volumeToMount, actualStateOfWorld, isRemount)
|
waitForAttachTimeout, volumeToMount, actualStateOfWorld, isRemount)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -389,14 +389,14 @@ func newFakeOperationGenerator(ch chan interface{}, quit chan interface{}) Opera
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fopg *fakeOperationGenerator) GenerateMountVolumeFunc(waitForAttachTimeout time.Duration, volumeToMount VolumeToMount, actualStateOfWorldMounterUpdater ActualStateOfWorldMounterUpdater, isRemount bool) (volumetypes.GeneratedOperations, error) {
|
func (fopg *fakeOperationGenerator) GenerateMountVolumeFunc(waitForAttachTimeout time.Duration, volumeToMount VolumeToMount, actualStateOfWorldMounterUpdater ActualStateOfWorldMounterUpdater, isRemount bool) volumetypes.GeneratedOperations {
|
||||||
opFunc := func() (error, error) {
|
opFunc := func() (error, error) {
|
||||||
startOperationAndBlock(fopg.ch, fopg.quit)
|
startOperationAndBlock(fopg.ch, fopg.quit)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return volumetypes.GeneratedOperations{
|
return volumetypes.GeneratedOperations{
|
||||||
OperationFunc: opFunc,
|
OperationFunc: opFunc,
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
func (fopg *fakeOperationGenerator) GenerateUnmountVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) (volumetypes.GeneratedOperations, error) {
|
func (fopg *fakeOperationGenerator) GenerateUnmountVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) (volumetypes.GeneratedOperations, error) {
|
||||||
opFunc := func() (error, error) {
|
opFunc := func() (error, error) {
|
||||||
|
@ -40,6 +40,10 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
|
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
unknownVolumePlugin string = "UnknownVolumePlugin"
|
||||||
|
)
|
||||||
|
|
||||||
var _ OperationGenerator = &operationGenerator{}
|
var _ OperationGenerator = &operationGenerator{}
|
||||||
|
|
||||||
type operationGenerator struct {
|
type operationGenerator struct {
|
||||||
@ -82,7 +86,7 @@ func NewOperationGenerator(kubeClient clientset.Interface,
|
|||||||
// OperationGenerator interface that extracts out the functions from operation_executor to make it dependency injectable
|
// OperationGenerator interface that extracts out the functions from operation_executor to make it dependency injectable
|
||||||
type OperationGenerator interface {
|
type OperationGenerator interface {
|
||||||
// Generates the MountVolume function needed to perform the mount of a volume plugin
|
// Generates the MountVolume function needed to perform the mount of a volume plugin
|
||||||
GenerateMountVolumeFunc(waitForAttachTimeout time.Duration, volumeToMount VolumeToMount, actualStateOfWorldMounterUpdater ActualStateOfWorldMounterUpdater, isRemount bool) (volumetypes.GeneratedOperations, error)
|
GenerateMountVolumeFunc(waitForAttachTimeout time.Duration, volumeToMount VolumeToMount, actualStateOfWorldMounterUpdater ActualStateOfWorldMounterUpdater, isRemount bool) volumetypes.GeneratedOperations
|
||||||
|
|
||||||
// Generates the UnmountVolume function needed to perform the unmount of a volume plugin
|
// Generates the UnmountVolume function needed to perform the unmount of a volume plugin
|
||||||
GenerateUnmountVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) (volumetypes.GeneratedOperations, error)
|
GenerateUnmountVolumeFunc(volumeToUnmount MountedVolume, actualStateOfWorld ActualStateOfWorldMounterUpdater, podsDir string) (volumetypes.GeneratedOperations, error)
|
||||||
@ -436,61 +440,61 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
|
|||||||
waitForAttachTimeout time.Duration,
|
waitForAttachTimeout time.Duration,
|
||||||
volumeToMount VolumeToMount,
|
volumeToMount VolumeToMount,
|
||||||
actualStateOfWorld ActualStateOfWorldMounterUpdater,
|
actualStateOfWorld ActualStateOfWorldMounterUpdater,
|
||||||
isRemount bool) (volumetypes.GeneratedOperations, error) {
|
isRemount bool) volumetypes.GeneratedOperations {
|
||||||
// Get mounter plugin
|
// Get mounter plugin
|
||||||
|
volumePluginName := unknownVolumePlugin
|
||||||
volumePlugin, err :=
|
volumePlugin, err :=
|
||||||
og.volumePluginMgr.FindPluginBySpec(volumeToMount.VolumeSpec)
|
og.volumePluginMgr.FindPluginBySpec(volumeToMount.VolumeSpec)
|
||||||
if err != nil || volumePlugin == nil {
|
if err == nil && volumePlugin != nil {
|
||||||
return volumetypes.GeneratedOperations{}, volumeToMount.GenerateErrorDetailed("MountVolume.FindPluginBySpec failed", err)
|
volumePluginName = volumePlugin.GetPluginName()
|
||||||
}
|
|
||||||
|
|
||||||
affinityErr := checkNodeAffinity(og, volumeToMount, volumePlugin)
|
|
||||||
if affinityErr != nil {
|
|
||||||
eventErr, detailedErr := volumeToMount.GenerateError("MountVolume.NodeAffinity check failed", affinityErr)
|
|
||||||
og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMountVolume, eventErr.Error())
|
|
||||||
return volumetypes.GeneratedOperations{}, detailedErr
|
|
||||||
}
|
|
||||||
|
|
||||||
volumeMounter, newMounterErr := volumePlugin.NewMounter(
|
|
||||||
volumeToMount.VolumeSpec,
|
|
||||||
volumeToMount.Pod,
|
|
||||||
volume.VolumeOptions{})
|
|
||||||
if newMounterErr != nil {
|
|
||||||
eventErr, detailedErr := volumeToMount.GenerateError("MountVolume.NewMounter initialization failed", newMounterErr)
|
|
||||||
og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.FailedMountVolume, eventErr.Error())
|
|
||||||
return volumetypes.GeneratedOperations{}, detailedErr
|
|
||||||
}
|
|
||||||
|
|
||||||
mountCheckError := checkMountOptionSupport(og, volumeToMount, volumePlugin)
|
|
||||||
|
|
||||||
if mountCheckError != nil {
|
|
||||||
eventErr, detailedErr := volumeToMount.GenerateError("MountVolume.MountOptionSupport check failed", mountCheckError)
|
|
||||||
og.recorder.Eventf(volumeToMount.Pod, v1.EventTypeWarning, kevents.UnsupportedMountOption, eventErr.Error())
|
|
||||||
return volumetypes.GeneratedOperations{}, detailedErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get attacher, if possible
|
|
||||||
attachableVolumePlugin, _ :=
|
|
||||||
og.volumePluginMgr.FindAttachablePluginBySpec(volumeToMount.VolumeSpec)
|
|
||||||
var volumeAttacher volume.Attacher
|
|
||||||
if attachableVolumePlugin != nil {
|
|
||||||
volumeAttacher, _ = attachableVolumePlugin.NewAttacher()
|
|
||||||
}
|
|
||||||
|
|
||||||
// get deviceMounter, if possible
|
|
||||||
deviceMountableVolumePlugin, _ := og.volumePluginMgr.FindDeviceMountablePluginBySpec(volumeToMount.VolumeSpec)
|
|
||||||
var volumeDeviceMounter volume.DeviceMounter
|
|
||||||
if deviceMountableVolumePlugin != nil {
|
|
||||||
volumeDeviceMounter, _ = deviceMountableVolumePlugin.NewDeviceMounter()
|
|
||||||
}
|
|
||||||
|
|
||||||
var fsGroup *int64
|
|
||||||
if volumeToMount.Pod.Spec.SecurityContext != nil &&
|
|
||||||
volumeToMount.Pod.Spec.SecurityContext.FSGroup != nil {
|
|
||||||
fsGroup = volumeToMount.Pod.Spec.SecurityContext.FSGroup
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mountVolumeFunc := func() (error, error) {
|
mountVolumeFunc := func() (error, error) {
|
||||||
|
if err != nil || volumePlugin == nil {
|
||||||
|
return volumeToMount.GenerateError("MountVolume.FindPluginBySpec failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
affinityErr := checkNodeAffinity(og, volumeToMount, volumePlugin)
|
||||||
|
if affinityErr != nil {
|
||||||
|
return volumeToMount.GenerateError("MountVolume.NodeAffinity check failed", affinityErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
volumeMounter, newMounterErr := volumePlugin.NewMounter(
|
||||||
|
volumeToMount.VolumeSpec,
|
||||||
|
volumeToMount.Pod,
|
||||||
|
volume.VolumeOptions{})
|
||||||
|
if newMounterErr != nil {
|
||||||
|
return volumeToMount.GenerateError("MountVolume.NewMounter initialization failed", newMounterErr)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mountCheckError := checkMountOptionSupport(og, volumeToMount, volumePlugin)
|
||||||
|
|
||||||
|
if mountCheckError != nil {
|
||||||
|
return volumeToMount.GenerateError("MountVolume.MountOptionSupport check failed", mountCheckError)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get attacher, if possible
|
||||||
|
attachableVolumePlugin, _ :=
|
||||||
|
og.volumePluginMgr.FindAttachablePluginBySpec(volumeToMount.VolumeSpec)
|
||||||
|
var volumeAttacher volume.Attacher
|
||||||
|
if attachableVolumePlugin != nil {
|
||||||
|
volumeAttacher, _ = attachableVolumePlugin.NewAttacher()
|
||||||
|
}
|
||||||
|
|
||||||
|
// get deviceMounter, if possible
|
||||||
|
deviceMountableVolumePlugin, _ := og.volumePluginMgr.FindDeviceMountablePluginBySpec(volumeToMount.VolumeSpec)
|
||||||
|
var volumeDeviceMounter volume.DeviceMounter
|
||||||
|
if deviceMountableVolumePlugin != nil {
|
||||||
|
volumeDeviceMounter, _ = deviceMountableVolumePlugin.NewDeviceMounter()
|
||||||
|
}
|
||||||
|
|
||||||
|
var fsGroup *int64
|
||||||
|
if volumeToMount.Pod.Spec.SecurityContext != nil &&
|
||||||
|
volumeToMount.Pod.Spec.SecurityContext.FSGroup != nil {
|
||||||
|
fsGroup = volumeToMount.Pod.Spec.SecurityContext.FSGroup
|
||||||
|
}
|
||||||
|
|
||||||
devicePath := volumeToMount.DevicePath
|
devicePath := volumeToMount.DevicePath
|
||||||
if volumeAttacher != nil {
|
if volumeAttacher != nil {
|
||||||
// Wait for attachable volumes to finish attaching
|
// Wait for attachable volumes to finish attaching
|
||||||
@ -536,7 +540,7 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
|
|||||||
|
|
||||||
// resizeFileSystem will resize the file system if user has requested a resize of
|
// resizeFileSystem will resize the file system if user has requested a resize of
|
||||||
// underlying persistent volume and is allowed to do so.
|
// underlying persistent volume and is allowed to do so.
|
||||||
resizeSimpleError, resizeDetailedError := og.resizeFileSystem(volumeToMount, devicePath, deviceMountPath, volumePlugin.GetPluginName())
|
resizeSimpleError, resizeDetailedError := og.resizeFileSystem(volumeToMount, devicePath, deviceMountPath, volumePluginName)
|
||||||
|
|
||||||
if resizeSimpleError != nil || resizeDetailedError != nil {
|
if resizeSimpleError != nil || resizeDetailedError != nil {
|
||||||
return resizeSimpleError, resizeDetailedError
|
return resizeSimpleError, resizeDetailedError
|
||||||
@ -593,8 +597,8 @@ func (og *operationGenerator) GenerateMountVolumeFunc(
|
|||||||
return volumetypes.GeneratedOperations{
|
return volumetypes.GeneratedOperations{
|
||||||
OperationFunc: mountVolumeFunc,
|
OperationFunc: mountVolumeFunc,
|
||||||
EventRecorderFunc: eventRecorderFunc,
|
EventRecorderFunc: eventRecorderFunc,
|
||||||
CompleteFunc: util.OperationCompleteHook(util.GetFullQualifiedPluginNameForVolume(volumePlugin.GetPluginName(), volumeToMount.VolumeSpec), "volume_mount"),
|
CompleteFunc: util.OperationCompleteHook(util.GetFullQualifiedPluginNameForVolume(volumePluginName, volumeToMount.VolumeSpec), "volume_mount"),
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (og *operationGenerator) resizeFileSystem(volumeToMount VolumeToMount, devicePath, deviceMountPath, pluginName string) (simpleErr, detailedErr error) {
|
func (og *operationGenerator) resizeFileSystem(volumeToMount VolumeToMount, devicePath, deviceMountPath, pluginName string) (simpleErr, detailedErr error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user