From 099cb71a53b8b123da7758b96b8357cecd8d826a Mon Sep 17 00:00:00 2001 From: Hemant Kumar Date: Mon, 15 Jul 2024 17:36:30 -0400 Subject: [PATCH] Ensure that all options are correctly set when calling node-expand-during-mount --- pkg/volume/testing/testing.go | 2 + .../util/operationexecutor/node_expander.go | 2 +- .../operationexecutor/node_expander_test.go | 4 - .../operationexecutor/operation_generator.go | 1 + .../operation_generator_test.go | 84 +++++++++++++++++++ 5 files changed, 88 insertions(+), 5 deletions(-) diff --git a/pkg/volume/testing/testing.go b/pkg/volume/testing/testing.go index cd7c654610d..f0ebe444811 100644 --- a/pkg/volume/testing/testing.go +++ b/pkg/volume/testing/testing.go @@ -180,6 +180,7 @@ type FakeVolumePlugin struct { Host volume.VolumeHost Config volume.VolumeConfig LastProvisionerOptions volume.VolumeOptions + LastResizeOptions volume.NodeResizeOptions NewAttacherCallCount int NewDetacherCallCount int NodeExpandCallCount int @@ -494,6 +495,7 @@ func (plugin *FakeVolumePlugin) RequiresFSResize() bool { func (plugin *FakeVolumePlugin) NodeExpand(resizeOptions volume.NodeResizeOptions) (bool, error) { plugin.NodeExpandCallCount++ + plugin.LastResizeOptions = resizeOptions if resizeOptions.VolumeSpec.Name() == FailWithInUseVolumeName { return false, volumetypes.NewFailedPreconditionError("volume-in-use") } diff --git a/pkg/volume/util/operationexecutor/node_expander.go b/pkg/volume/util/operationexecutor/node_expander.go index 8e55d0b771c..743b5837497 100644 --- a/pkg/volume/util/operationexecutor/node_expander.go +++ b/pkg/volume/util/operationexecutor/node_expander.go @@ -39,7 +39,7 @@ type NodeExpander struct { pvCap resource.Quantity resizeStatus v1.ClaimResourceStatus - // indicates that pvc spec size has actually changed since last we observerd size + // indicates that pvc spec size has actually changed since last we observed size // on the kubelet markExpansionInfeasible bool diff --git a/pkg/volume/util/operationexecutor/node_expander_test.go b/pkg/volume/util/operationexecutor/node_expander_test.go index 87d029004bc..40d09e15c26 100644 --- a/pkg/volume/util/operationexecutor/node_expander_test.go +++ b/pkg/volume/util/operationexecutor/node_expander_test.go @@ -22,7 +22,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" @@ -33,9 +32,6 @@ import ( ) type fakeActualStateOfWorld struct { - // nodeName is the name of this node. This value is passed to Attach/Detach - nodeName types.NodeName - volumesWithFinalExpansionErrors sets.Set[v1.UniqueVolumeName] sync.RWMutex } diff --git a/pkg/volume/util/operationexecutor/operation_generator.go b/pkg/volume/util/operationexecutor/operation_generator.go index 6accbb53fd1..2e92b30fd20 100644 --- a/pkg/volume/util/operationexecutor/operation_generator.go +++ b/pkg/volume/util/operationexecutor/operation_generator.go @@ -2003,6 +2003,7 @@ func (og *operationGenerator) expandVolumeDuringMount(volumeToMount VolumeToMoun rsOpts.NewSize = pvSpecCap rsOpts.OldSize = pvcStatusCap + // rsOpts.VolumeSpec = volumeToMount.VolumeSpec resizeOp := nodeResizeOperationOpts{ vmt: volumeToMount, pvc: pvc, diff --git a/pkg/volume/util/operationexecutor/operation_generator_test.go b/pkg/volume/util/operationexecutor/operation_generator_test.go index 2835941cb30..b9ca558be0c 100644 --- a/pkg/volume/util/operationexecutor/operation_generator_test.go +++ b/pkg/volume/util/operationexecutor/operation_generator_test.go @@ -320,6 +320,90 @@ func TestOperationGenerator_nodeExpandVolume(t *testing.T) { } } +func TestExpandDuringMount(t *testing.T) { + nodeResizePending := v1.PersistentVolumeClaimNodeResizePending + var tests = []struct { + name string + pvc *v1.PersistentVolumeClaim + pv *v1.PersistentVolume + + // desired size, defaults to pv.Spec.Capacity + desiredSize *resource.Quantity + // actualSize, defaults to pvc.Status.Capacity + actualSize *resource.Quantity + + // expectations of test + expectedResizeStatus v1.ClaimResourceStatus + expectedStatusSize resource.Quantity + resizeCallCount int + expectError bool + }{ + { + name: "pv.spec.cap > pvc.status.cap, resizeStatus=node_expansion_pending", + pvc: getTestPVC("test-vol0", "2G", "1G", "2G", &nodeResizePending), + pv: getTestPV("test-vol0", "2G"), + expectedResizeStatus: "", + resizeCallCount: 1, + expectedStatusSize: resource.MustParse("2G"), + }, + } + for i := range tests { + test := tests[i] + t.Run(test.name, func(t *testing.T) { + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.RecoverVolumeExpansionFailure, true) + volumePluginMgr, fakePlugin := volumetesting.GetTestKubeletVolumePluginMgr(t) + test.pv.Spec.ClaimRef = &v1.ObjectReference{ + Namespace: test.pvc.Namespace, + Name: test.pvc.Name, + } + + pvc := test.pvc + pv := test.pv + pod := getTestPod("test-pod", pvc.Name) + og := getTestOperatorGeneratorWithPVPVC(volumePluginMgr, pvc, pv) + vmt := VolumeToMount{ + Pod: pod, + VolumeName: v1.UniqueVolumeName(pv.Name), + VolumeSpec: volume.NewSpecFromPersistentVolume(pv, false), + } + desiredSize := test.desiredSize + if desiredSize == nil { + desiredSize = pv.Spec.Capacity.Storage() + } + actualSize := test.actualSize + if actualSize == nil { + actualSize = pvc.Status.Capacity.Storage() + } + pluginResizeOpts := volume.NodeResizeOptions{ + VolumeSpec: vmt.VolumeSpec, + NewSize: *desiredSize, + OldSize: *actualSize, + } + asow := newFakeActualStateOfWorld() + + ogInstance, _ := og.(*operationGenerator) + _, err := ogInstance.expandVolumeDuringMount(vmt, asow, pluginResizeOpts) + + if !test.expectError && err != nil { + t.Errorf("For test %s, expected no error got: %v", test.name, err) + } + if test.expectError && err == nil { + t.Errorf("For test %s, expected error but got none", test.name) + } + if test.resizeCallCount != fakePlugin.NodeExpandCallCount { + t.Errorf("for test %s, expected node-expand call count to be %d, got %d", test.name, test.resizeCallCount, fakePlugin.NodeExpandCallCount) + } + + if test.resizeCallCount > 0 { + resizeOptions := fakePlugin.LastResizeOptions + if resizeOptions.VolumeSpec == nil { + t.Errorf("for test %s, expected volume spec to be set", test.name) + } + } + }) + } +} + func getTestPod(podName, pvcName string) *v1.Pod { return &v1.Pod{ ObjectMeta: metav1.ObjectMeta{