mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 05:36:12 +00:00
Refactor NodeStage function
Timeout operations should result in Fix unit tests for uncertainDeviceGlobalMounts
This commit is contained in:
@@ -224,6 +224,7 @@ go_test(
|
|||||||
"//pkg/volume/util:go_default_library",
|
"//pkg/volume/util:go_default_library",
|
||||||
"//pkg/volume/util/hostutil:go_default_library",
|
"//pkg/volume/util/hostutil:go_default_library",
|
||||||
"//pkg/volume/util/subpath:go_default_library",
|
"//pkg/volume/util/subpath:go_default_library",
|
||||||
|
"//pkg/volume/util/types:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||||
|
@@ -51,9 +51,10 @@ const (
|
|||||||
reconcilerLoopSleepDuration time.Duration = 1 * time.Nanosecond
|
reconcilerLoopSleepDuration time.Duration = 1 * time.Nanosecond
|
||||||
// waitForAttachTimeout is the maximum amount of time a
|
// waitForAttachTimeout is the maximum amount of time a
|
||||||
// operationexecutor.Mount call will wait for a volume to be attached.
|
// operationexecutor.Mount call will wait for a volume to be attached.
|
||||||
waitForAttachTimeout time.Duration = 1 * time.Second
|
waitForAttachTimeout time.Duration = 1 * time.Second
|
||||||
nodeName k8stypes.NodeName = k8stypes.NodeName("mynodename")
|
nodeName k8stypes.NodeName = k8stypes.NodeName("mynodename")
|
||||||
kubeletPodsDir string = "fake-dir"
|
kubeletPodsDir string = "fake-dir"
|
||||||
|
testOperationBackOffDuration time.Duration = 100 * time.Millisecond
|
||||||
)
|
)
|
||||||
|
|
||||||
func hasAddedPods() bool { return true }
|
func hasAddedPods() bool { return true }
|
||||||
@@ -1134,7 +1135,7 @@ func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) {
|
|||||||
// resize operation and clear the fsResizeRequired flag for volume.
|
// resize operation and clear the fsResizeRequired flag for volume.
|
||||||
go reconciler.Run(wait.NeverStop)
|
go reconciler.Run(wait.NeverStop)
|
||||||
|
|
||||||
waitErr := retryWithExponentialBackOff(500*time.Millisecond, func() (done bool, err error) {
|
waitErr := retryWithExponentialBackOff(testOperationBackOffDuration, func() (done bool, err error) {
|
||||||
mounted, _, err := asw.PodExistsInVolume(podName, volumeName)
|
mounted, _, err := asw.PodExistsInVolume(podName, volumeName)
|
||||||
return mounted && err == nil, nil
|
return mounted && err == nil, nil
|
||||||
})
|
})
|
||||||
@@ -1147,97 +1148,131 @@ func Test_Run_Positive_VolumeFSResizeControllerAttachEnabled(t *testing.T) {
|
|||||||
|
|
||||||
func Test_UncertainDeviceGlobalMounts(t *testing.T) {
|
func Test_UncertainDeviceGlobalMounts(t *testing.T) {
|
||||||
fsMode := v1.PersistentVolumeFilesystem
|
fsMode := v1.PersistentVolumeFilesystem
|
||||||
pv := &v1.PersistentVolume{
|
var tests = []struct {
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
name string
|
||||||
Name: volumetesting.TimeoutOnMountDeviceVolumeName,
|
deviceState operationexecutor.DeviceMountState
|
||||||
UID: "pvuid",
|
unmountDeviceCallCount int
|
||||||
|
volumeName string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "timed out operations should result in device marked as uncertain",
|
||||||
|
deviceState: operationexecutor.DeviceMountUncertain,
|
||||||
|
unmountDeviceCallCount: 1,
|
||||||
|
volumeName: volumetesting.TimeoutOnMountDeviceVolumeName,
|
||||||
},
|
},
|
||||||
Spec: v1.PersistentVolumeSpec{
|
{
|
||||||
ClaimRef: &v1.ObjectReference{Name: "pvc"},
|
name: "failed operation should result in not-mounted device",
|
||||||
VolumeMode: &fsMode,
|
deviceState: operationexecutor.DeviceNotMounted,
|
||||||
|
unmountDeviceCallCount: 0,
|
||||||
|
volumeName: volumetesting.FailMountDeviceVolumeName,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "timeout followed by failed operation should result in non-mounted device",
|
||||||
|
deviceState: operationexecutor.DeviceNotMounted,
|
||||||
|
unmountDeviceCallCount: 0,
|
||||||
|
volumeName: volumetesting.TimeoutAndFailOnMountDeviceVolumeName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pvc := &v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
for _, tc := range tests {
|
||||||
Name: "pvc",
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
UID: "pvcuid",
|
|
||||||
},
|
pv := &v1.PersistentVolume{
|
||||||
Spec: v1.PersistentVolumeClaimSpec{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
VolumeName: volumetesting.TimeoutOnMountDeviceVolumeName,
|
Name: tc.volumeName,
|
||||||
},
|
UID: "pvuid",
|
||||||
}
|
},
|
||||||
pod := &v1.Pod{
|
Spec: v1.PersistentVolumeSpec{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ClaimRef: &v1.ObjectReference{Name: "pvc"},
|
||||||
Name: "pod1",
|
VolumeMode: &fsMode,
|
||||||
UID: "pod1uid",
|
},
|
||||||
},
|
}
|
||||||
Spec: v1.PodSpec{
|
pvc := &v1.PersistentVolumeClaim{
|
||||||
Volumes: []v1.Volume{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
{
|
Name: "pvc",
|
||||||
Name: "volume-name",
|
UID: "pvcuid",
|
||||||
VolumeSource: v1.VolumeSource{
|
},
|
||||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
Spec: v1.PersistentVolumeClaimSpec{
|
||||||
ClaimName: pvc.Name,
|
VolumeName: tc.volumeName,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
pod := &v1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "pod1",
|
||||||
|
UID: "pod1uid",
|
||||||
|
},
|
||||||
|
Spec: v1.PodSpec{
|
||||||
|
Volumes: []v1.Volume{
|
||||||
|
{
|
||||||
|
Name: "volume-name",
|
||||||
|
VolumeSource: v1.VolumeSource{
|
||||||
|
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
||||||
|
ClaimName: pvc.Name,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
},
|
|
||||||
|
volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t)
|
||||||
|
dsw := cache.NewDesiredStateOfWorld(volumePluginMgr)
|
||||||
|
asw := cache.NewActualStateOfWorld(nodeName, volumePluginMgr)
|
||||||
|
kubeClient := createtestClientWithPVPVC(pv, pvc, v1.AttachedVolume{
|
||||||
|
Name: v1.UniqueVolumeName(fmt.Sprintf("fake-plugin/%s", tc.volumeName)),
|
||||||
|
DevicePath: "fake/path",
|
||||||
|
})
|
||||||
|
fakeRecorder := &record.FakeRecorder{}
|
||||||
|
fakeHandler := volumetesting.NewBlockVolumePathHandler()
|
||||||
|
oex := operationexecutor.NewOperationExecutor(operationexecutor.NewOperationGenerator(
|
||||||
|
kubeClient,
|
||||||
|
volumePluginMgr,
|
||||||
|
fakeRecorder,
|
||||||
|
false, /* checkNodeCapabilitiesBeforeMount */
|
||||||
|
fakeHandler))
|
||||||
|
|
||||||
|
reconciler := NewReconciler(
|
||||||
|
kubeClient,
|
||||||
|
true, /* controllerAttachDetachEnabled */
|
||||||
|
reconcilerLoopSleepDuration,
|
||||||
|
waitForAttachTimeout,
|
||||||
|
nodeName,
|
||||||
|
dsw,
|
||||||
|
asw,
|
||||||
|
hasAddedPods,
|
||||||
|
oex,
|
||||||
|
&mount.FakeMounter{},
|
||||||
|
hostutil.NewFakeHostUtil(nil),
|
||||||
|
volumePluginMgr,
|
||||||
|
kubeletPodsDir)
|
||||||
|
volumeSpec := &volume.Spec{PersistentVolume: pv}
|
||||||
|
podName := util.GetUniquePodName(pod)
|
||||||
|
volumeName, err := dsw.AddPodToVolume(
|
||||||
|
podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */)
|
||||||
|
// Assert
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AddPodToVolume failed. Expected: <no error> Actual: <%v>", err)
|
||||||
|
}
|
||||||
|
dsw.MarkVolumesReportedInUse([]v1.UniqueVolumeName{volumeName})
|
||||||
|
|
||||||
|
// Start the reconciler to fill ASW.
|
||||||
|
stopChan, stoppedChan := make(chan struct{}), make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
reconciler.Run(stopChan)
|
||||||
|
close(stoppedChan)
|
||||||
|
}()
|
||||||
|
waitForVolumeToExistInASW(t, volumeName, asw)
|
||||||
|
if tc.deviceState == operationexecutor.DeviceMountUncertain {
|
||||||
|
waitForUncertainGlobalMount(t, volumeName, asw)
|
||||||
|
}
|
||||||
|
|
||||||
|
dsw.DeletePodFromVolume(podName, volumeName)
|
||||||
|
waitForDetach(t, volumeName, asw)
|
||||||
|
|
||||||
|
volumetesting.VerifyUnmountDeviceCallCount(1, fakePlugin)
|
||||||
|
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t)
|
|
||||||
dsw := cache.NewDesiredStateOfWorld(volumePluginMgr)
|
|
||||||
asw := cache.NewActualStateOfWorld(nodeName, volumePluginMgr)
|
|
||||||
kubeClient := createtestClientWithPVPVC(pv, pvc, v1.AttachedVolume{
|
|
||||||
Name: v1.UniqueVolumeName(fmt.Sprintf("fake-plugin/%s", volumetesting.TimeoutOnMountDeviceVolumeName)),
|
|
||||||
DevicePath: "fake/path",
|
|
||||||
})
|
|
||||||
fakeRecorder := &record.FakeRecorder{}
|
|
||||||
fakeHandler := volumetesting.NewBlockVolumePathHandler()
|
|
||||||
oex := operationexecutor.NewOperationExecutor(operationexecutor.NewOperationGenerator(
|
|
||||||
kubeClient,
|
|
||||||
volumePluginMgr,
|
|
||||||
fakeRecorder,
|
|
||||||
false, /* checkNodeCapabilitiesBeforeMount */
|
|
||||||
fakeHandler))
|
|
||||||
|
|
||||||
reconciler := NewReconciler(
|
|
||||||
kubeClient,
|
|
||||||
true, /* controllerAttachDetachEnabled */
|
|
||||||
reconcilerLoopSleepDuration,
|
|
||||||
waitForAttachTimeout,
|
|
||||||
nodeName,
|
|
||||||
dsw,
|
|
||||||
asw,
|
|
||||||
hasAddedPods,
|
|
||||||
oex,
|
|
||||||
&mount.FakeMounter{},
|
|
||||||
hostutil.NewFakeHostUtil(nil),
|
|
||||||
volumePluginMgr,
|
|
||||||
kubeletPodsDir)
|
|
||||||
volumeSpec := &volume.Spec{PersistentVolume: pv}
|
|
||||||
podName := util.GetUniquePodName(pod)
|
|
||||||
volumeName, err := dsw.AddPodToVolume(
|
|
||||||
podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */)
|
|
||||||
// Assert
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("AddPodToVolume failed. Expected: <no error> Actual: <%v>", err)
|
|
||||||
}
|
|
||||||
dsw.MarkVolumesReportedInUse([]v1.UniqueVolumeName{volumeName})
|
|
||||||
|
|
||||||
// Start the reconciler to fill ASW.
|
|
||||||
stopChan, stoppedChan := make(chan struct{}), make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
reconciler.Run(stopChan)
|
|
||||||
close(stoppedChan)
|
|
||||||
}()
|
|
||||||
waitForVolumeToExistInASW(t, volumeName, asw)
|
|
||||||
waitForUncertainGlobalMount(t, volumeName, asw)
|
|
||||||
|
|
||||||
dsw.DeletePodFromVolume(podName, volumeName)
|
|
||||||
waitForDetach(t, volumeName, asw)
|
|
||||||
|
|
||||||
volumetesting.VerifyUnmountDeviceCallCount(1, fakePlugin)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_UncertainVolumeMountState(t *testing.T) {
|
func Test_UncertainVolumeMountState(t *testing.T) {
|
||||||
@@ -1339,7 +1374,7 @@ func Test_UncertainVolumeMountState(t *testing.T) {
|
|||||||
func waitForUncertainGlobalMount(t *testing.T, volumeName v1.UniqueVolumeName, asw cache.ActualStateOfWorld) {
|
func waitForUncertainGlobalMount(t *testing.T, volumeName v1.UniqueVolumeName, asw cache.ActualStateOfWorld) {
|
||||||
// check if volume is globally mounted in uncertain state
|
// check if volume is globally mounted in uncertain state
|
||||||
err := retryWithExponentialBackOff(
|
err := retryWithExponentialBackOff(
|
||||||
time.Duration(500*time.Millisecond),
|
testOperationBackOffDuration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
unmountedVolumes := asw.GetUnmountedVolumes()
|
unmountedVolumes := asw.GetUnmountedVolumes()
|
||||||
for _, v := range unmountedVolumes {
|
for _, v := range unmountedVolumes {
|
||||||
@@ -1359,7 +1394,7 @@ func waitForUncertainGlobalMount(t *testing.T, volumeName v1.UniqueVolumeName, a
|
|||||||
func waitForUncertainPodMount(t *testing.T, volumeName v1.UniqueVolumeName, asw cache.ActualStateOfWorld) {
|
func waitForUncertainPodMount(t *testing.T, volumeName v1.UniqueVolumeName, asw cache.ActualStateOfWorld) {
|
||||||
// check if volume is locally pod mounted in uncertain state
|
// check if volume is locally pod mounted in uncertain state
|
||||||
err := retryWithExponentialBackOff(
|
err := retryWithExponentialBackOff(
|
||||||
time.Duration(500*time.Millisecond),
|
testOperationBackOffDuration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
allMountedVolumes := asw.GetAllMountedVolumes()
|
allMountedVolumes := asw.GetAllMountedVolumes()
|
||||||
for _, v := range allMountedVolumes {
|
for _, v := range allMountedVolumes {
|
||||||
@@ -1382,7 +1417,7 @@ func waitForMount(
|
|||||||
volumeName v1.UniqueVolumeName,
|
volumeName v1.UniqueVolumeName,
|
||||||
asw cache.ActualStateOfWorld) {
|
asw cache.ActualStateOfWorld) {
|
||||||
err := retryWithExponentialBackOff(
|
err := retryWithExponentialBackOff(
|
||||||
time.Duration(500*time.Millisecond),
|
testOperationBackOffDuration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
mountedVolumes := asw.GetMountedVolumes()
|
mountedVolumes := asw.GetMountedVolumes()
|
||||||
for _, mountedVolume := range mountedVolumes {
|
for _, mountedVolume := range mountedVolumes {
|
||||||
@@ -1402,7 +1437,7 @@ func waitForMount(
|
|||||||
|
|
||||||
func waitForVolumeToExistInASW(t *testing.T, volumeName v1.UniqueVolumeName, asw cache.ActualStateOfWorld) {
|
func waitForVolumeToExistInASW(t *testing.T, volumeName v1.UniqueVolumeName, asw cache.ActualStateOfWorld) {
|
||||||
err := retryWithExponentialBackOff(
|
err := retryWithExponentialBackOff(
|
||||||
time.Duration(500*time.Millisecond),
|
testOperationBackOffDuration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
if asw.VolumeExists(volumeName) {
|
if asw.VolumeExists(volumeName) {
|
||||||
return true, nil
|
return true, nil
|
||||||
@@ -1420,7 +1455,7 @@ func waitForDetach(
|
|||||||
volumeName v1.UniqueVolumeName,
|
volumeName v1.UniqueVolumeName,
|
||||||
asw cache.ActualStateOfWorld) {
|
asw cache.ActualStateOfWorld) {
|
||||||
err := retryWithExponentialBackOff(
|
err := retryWithExponentialBackOff(
|
||||||
time.Duration(500*time.Millisecond),
|
testOperationBackOffDuration,
|
||||||
func() (bool, error) {
|
func() (bool, error) {
|
||||||
if asw.VolumeExists(volumeName) {
|
if asw.VolumeExists(volumeName) {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@@ -66,6 +66,7 @@ go_test(
|
|||||||
"//pkg/volume/csi/fake:go_default_library",
|
"//pkg/volume/csi/fake:go_default_library",
|
||||||
"//pkg/volume/testing:go_default_library",
|
"//pkg/volume/testing:go_default_library",
|
||||||
"//pkg/volume/util:go_default_library",
|
"//pkg/volume/util:go_default_library",
|
||||||
|
"//pkg/volume/util/types:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/storage/v1beta1:go_default_library",
|
||||||
|
@@ -499,7 +499,7 @@ func TestMounterSetupWithStatusTracking(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !tc.shouldFail && err != nil {
|
if !tc.shouldFail && err != nil {
|
||||||
t.Fatalf("expected successs got mounter.Setup failed with: %v", err)
|
t.Fatalf("expected success got mounter.Setup failed with: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,8 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library",
|
"//vendor/github.com/container-storage-interface/spec/lib/go/csi:go_default_library",
|
||||||
"//vendor/google.golang.org/grpc:go_default_library",
|
"//vendor/google.golang.org/grpc:go_default_library",
|
||||||
|
"//vendor/google.golang.org/grpc/codes:go_default_library",
|
||||||
|
"//vendor/google.golang.org/grpc/status:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -98,8 +98,8 @@ func (a *flexVolumeAttacher) MountDevice(spec *volume.Spec, devicePath string, d
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (attacher *flexVolumeAttacher) MountDeviceWithStatusTracking(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) {
|
func (a *flexVolumeAttacher) MountDeviceWithStatusTracking(spec *volume.Spec, devicePath string, deviceMountPath string) (volumetypes.OperationStatus, error) {
|
||||||
err := attacher.MountDevice(spec, devicePath, deviceMountPath)
|
err := a.MountDevice(spec, devicePath, deviceMountPath)
|
||||||
return volumetypes.OperationFinished, err
|
return volumetypes.OperationFinished, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,6 +71,10 @@ const (
|
|||||||
TimeoutOnSetupVolumeName = "timeout-setup-volume"
|
TimeoutOnSetupVolumeName = "timeout-setup-volume"
|
||||||
// TimeoutOnMountDeviceVolumeName will cause MountDevice call to timeout but Setup will finish.
|
// TimeoutOnMountDeviceVolumeName will cause MountDevice call to timeout but Setup will finish.
|
||||||
TimeoutOnMountDeviceVolumeName = "timeout-mount-device-volume"
|
TimeoutOnMountDeviceVolumeName = "timeout-mount-device-volume"
|
||||||
|
// TimeoutAndFailOnMountDeviceVolumeName will cause first MountDevice call to timeout but second call will fail
|
||||||
|
TimeoutAndFailOnMountDeviceVolumeName = "timeout-and-fail-mount-device-name"
|
||||||
|
// FailMountDeviceVolumeName will cause MountDevice operation on volume to fail
|
||||||
|
FailMountDeviceVolumeName = "fail-mount-device-volume-name"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fakeVolumeHost is useful for testing volume plugins.
|
// fakeVolumeHost is useful for testing volume plugins.
|
||||||
@@ -388,6 +392,7 @@ func (plugin *FakeVolumePlugin) getFakeVolume(list *[]*FakeVolume) *FakeVolume {
|
|||||||
UnmountDeviceHook: plugin.UnmountDeviceHook,
|
UnmountDeviceHook: plugin.UnmountDeviceHook,
|
||||||
}
|
}
|
||||||
volume.VolumesAttached = make(map[string]types.NodeName)
|
volume.VolumesAttached = make(map[string]types.NodeName)
|
||||||
|
volume.DeviceMountState = make(map[string]volumetypes.OperationStatus)
|
||||||
*list = append(*list, volume)
|
*list = append(*list, volume)
|
||||||
return volume
|
return volume
|
||||||
}
|
}
|
||||||
@@ -789,7 +794,8 @@ type FakeVolume struct {
|
|||||||
VolName string
|
VolName string
|
||||||
Plugin *FakeVolumePlugin
|
Plugin *FakeVolumePlugin
|
||||||
MetricsNil
|
MetricsNil
|
||||||
VolumesAttached map[string]types.NodeName
|
VolumesAttached map[string]types.NodeName
|
||||||
|
DeviceMountState map[string]volumetypes.OperationStatus
|
||||||
|
|
||||||
// Add callbacks as needed
|
// Add callbacks as needed
|
||||||
WaitForAttachHook func(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error)
|
WaitForAttachHook func(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error)
|
||||||
@@ -1056,8 +1062,26 @@ func (fv *FakeVolume) MountDevice(spec *Spec, devicePath string, deviceMountPath
|
|||||||
fv.Lock()
|
fv.Lock()
|
||||||
defer fv.Unlock()
|
defer fv.Unlock()
|
||||||
if spec.Name() == TimeoutOnMountDeviceVolumeName {
|
if spec.Name() == TimeoutOnMountDeviceVolumeName {
|
||||||
|
fv.DeviceMountState[spec.Name()] = volumetypes.OperationInProgress
|
||||||
return volumetypes.NewOperationTimedOutError("error mounting device")
|
return volumetypes.NewOperationTimedOutError("error mounting device")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if spec.Name() == FailMountDeviceVolumeName {
|
||||||
|
fv.DeviceMountState[spec.Name()] = volumetypes.OperationFinished
|
||||||
|
return fmt.Errorf("error mounting disk: %s", devicePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if spec.Name() == TimeoutAndFailOnMountDeviceVolumeName {
|
||||||
|
oldState, ok := fv.DeviceMountState[spec.Name()]
|
||||||
|
if !ok {
|
||||||
|
fv.DeviceMountState[spec.Name()] = volumetypes.OperationInProgress
|
||||||
|
return volumetypes.NewOperationTimedOutError("error mounting state")
|
||||||
|
}
|
||||||
|
if oldState == volumetypes.OperationInProgress {
|
||||||
|
fv.DeviceMountState[spec.Name()] = volumetypes.OperationFinished
|
||||||
|
return fmt.Errorf("error mounting disk: %s", devicePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
fv.MountDeviceCallCount++
|
fv.MountDeviceCallCount++
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,7 @@ func (o *GeneratedOperations) Run() (eventErr, detailedErr error) {
|
|||||||
return o.OperationFunc()
|
return o.OperationFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OperationStatus is used to store status of a volume operation
|
||||||
type OperationStatus string
|
type OperationStatus string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
Reference in New Issue
Block a user