From 6202f61c95d83dacae28b5f2083cabe154a67303 Mon Sep 17 00:00:00 2001 From: Niclas Schad Date: Wed, 29 Apr 2026 09:40:05 +0200 Subject: [PATCH] WIP: Check actual volume size after volume expand to verify if expand was successful Signed-off-by: Niclas Schad --- pkg/csi/blockstorage/controllerserver.go | 4 ++-- pkg/stackit/client.go | 2 +- pkg/stackit/iaas_mock.go | 2 +- pkg/stackit/volumes.go | 17 +++++++++++++++-- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/pkg/csi/blockstorage/controllerserver.go b/pkg/csi/blockstorage/controllerserver.go index 8de6237e..dac096db 100644 --- a/pkg/csi/blockstorage/controllerserver.go +++ b/pkg/csi/blockstorage/controllerserver.go @@ -947,10 +947,10 @@ func (cs *controllerServer) ControllerExpandVolume(ctx context.Context, req *csi // we need wait for the volume to be available or InUse, it might be error_extending in some scenario targetStatus := []string{stackit.VolumeAvailableStatus, stackit.VolumeAttachedStatus} - err = cloud.WaitVolumeTargetStatus(ctx, volumeID, targetStatus) + err = cloud.WaitVolumeTargetStatus(ctx, volumeID, targetStatus, volSizeGB) if err != nil { klog.Errorf("Failed to WaitVolumeTargetStatus of volume %s: %v", volumeID, err) - return nil, status.Errorf(codes.Internal, "[ControllerExpandVolume] Volume %s not in target state after resize operation: %v", volumeID, err) + return nil, status.Errorf(codes.Internal, "[ControllerExpandVolume] Volume %s not in target state or size after resize operation: %v", volumeID, err) } klog.V(4).Infof("ControllerExpandVolume resized volume %v to size %v", volumeID, volSizeGB) diff --git a/pkg/stackit/client.go b/pkg/stackit/client.go index 12960832..ef919f05 100644 --- a/pkg/stackit/client.go +++ b/pkg/stackit/client.go @@ -58,7 +58,7 @@ type IaasClient interface { WaitDiskAttached(ctx context.Context, instanceID string, volumeID string) error DetachVolume(ctx context.Context, instanceID, volumeID string) error WaitDiskDetached(ctx context.Context, instanceID string, volumeID string) error - WaitVolumeTargetStatus(ctx context.Context, volumeID string, tStatus []string) error + WaitVolumeTargetStatus(ctx context.Context, volumeID string, tStatus []string, tSize int64) error GetVolume(ctx context.Context, volumeID string) (*iaas.Volume, error) GetVolumesByName(ctx context.Context, name string) ([]iaas.Volume, error) GetVolumeByName(ctx context.Context, name string) (*iaas.Volume, error) diff --git a/pkg/stackit/iaas_mock.go b/pkg/stackit/iaas_mock.go index 397d3cf3..d11eeb30 100644 --- a/pkg/stackit/iaas_mock.go +++ b/pkg/stackit/iaas_mock.go @@ -383,7 +383,7 @@ func (mr *MockIaasClientMockRecorder) WaitSnapshotReady(ctx, snapshotID any) *go } // WaitVolumeTargetStatus mocks base method. -func (m *MockIaasClient) WaitVolumeTargetStatus(ctx context.Context, volumeID string, tStatus []string) error { +func (m *MockIaasClient) WaitVolumeTargetStatus(ctx context.Context, volumeID string, tStatus []string, tSize int64) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "WaitVolumeTargetStatus", ctx, volumeID, tStatus) ret0, _ := ret[0].(error) diff --git a/pkg/stackit/volumes.go b/pkg/stackit/volumes.go index 5813e54a..e04bd18e 100644 --- a/pkg/stackit/volumes.go +++ b/pkg/stackit/volumes.go @@ -292,19 +292,32 @@ func (os *iaasClient) GetVolumeByName(ctx context.Context, name string) (*iaas.V return &vols[0], nil } -func (os *iaasClient) WaitVolumeTargetStatus(ctx context.Context, volumeID string, tStatus []string) error { +func (os *iaasClient) WaitVolumeTargetStatus(ctx context.Context, volumeID string, tStatus []string, tSize int64) error { backoff := wait.Backoff{ Duration: operationFinishInitDelay, Factor: operationFinishFactor, Steps: operationFinishSteps, } + // volResizeSuccess checks if the volume is an "GOOD" State and the target Size has + // been met. + volResizeSuccess := func(vol *iaas.Volume, tSize int64, tStatus []string) bool { + if slices.Contains(tStatus, *vol.Status) { + if tSize == vol.GetSize() { + return true + } + return false + } + return false + } + waitErr := wait.ExponentialBackoff(backoff, func() (bool, error) { vol, err := os.GetVolume(ctx, volumeID) if err != nil { return false, err } - if slices.Contains(tStatus, *vol.Status) { + // Check status + if volResizeSuccess(vol, tSize, tStatus) { return true, nil } for _, eState := range volumeErrorStates {