Ensure that all options are correctly set when calling node-expand-during-mount

This commit is contained in:
Hemant Kumar 2024-07-15 17:36:30 -04:00
parent 785e68a626
commit 099cb71a53
5 changed files with 88 additions and 5 deletions

View File

@ -180,6 +180,7 @@ type FakeVolumePlugin struct {
Host volume.VolumeHost Host volume.VolumeHost
Config volume.VolumeConfig Config volume.VolumeConfig
LastProvisionerOptions volume.VolumeOptions LastProvisionerOptions volume.VolumeOptions
LastResizeOptions volume.NodeResizeOptions
NewAttacherCallCount int NewAttacherCallCount int
NewDetacherCallCount int NewDetacherCallCount int
NodeExpandCallCount int NodeExpandCallCount int
@ -494,6 +495,7 @@ func (plugin *FakeVolumePlugin) RequiresFSResize() bool {
func (plugin *FakeVolumePlugin) NodeExpand(resizeOptions volume.NodeResizeOptions) (bool, error) { func (plugin *FakeVolumePlugin) NodeExpand(resizeOptions volume.NodeResizeOptions) (bool, error) {
plugin.NodeExpandCallCount++ plugin.NodeExpandCallCount++
plugin.LastResizeOptions = resizeOptions
if resizeOptions.VolumeSpec.Name() == FailWithInUseVolumeName { if resizeOptions.VolumeSpec.Name() == FailWithInUseVolumeName {
return false, volumetypes.NewFailedPreconditionError("volume-in-use") return false, volumetypes.NewFailedPreconditionError("volume-in-use")
} }

View File

@ -39,7 +39,7 @@ type NodeExpander struct {
pvCap resource.Quantity pvCap resource.Quantity
resizeStatus v1.ClaimResourceStatus 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 // on the kubelet
markExpansionInfeasible bool markExpansionInfeasible bool

View File

@ -22,7 +22,6 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing" featuregatetesting "k8s.io/component-base/featuregate/testing"
@ -33,9 +32,6 @@ import (
) )
type fakeActualStateOfWorld struct { 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] volumesWithFinalExpansionErrors sets.Set[v1.UniqueVolumeName]
sync.RWMutex sync.RWMutex
} }

View File

@ -2003,6 +2003,7 @@ func (og *operationGenerator) expandVolumeDuringMount(volumeToMount VolumeToMoun
rsOpts.NewSize = pvSpecCap rsOpts.NewSize = pvSpecCap
rsOpts.OldSize = pvcStatusCap rsOpts.OldSize = pvcStatusCap
// rsOpts.VolumeSpec = volumeToMount.VolumeSpec
resizeOp := nodeResizeOperationOpts{ resizeOp := nodeResizeOperationOpts{
vmt: volumeToMount, vmt: volumeToMount,
pvc: pvc, pvc: pvc,

View File

@ -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 { func getTestPod(podName, pvcName string) *v1.Pod {
return &v1.Pod{ return &v1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{