diff --git a/changelogs/unreleased/9124-blackpiglet b/changelogs/unreleased/9124-blackpiglet new file mode 100644 index 000000000..6f067caa3 --- /dev/null +++ b/changelogs/unreleased/9124-blackpiglet @@ -0,0 +1 @@ +Remove the WaitUntilVSCHandleIsReady from vs BIA. diff --git a/pkg/backup/actions/csi/volumesnapshot_action.go b/pkg/backup/actions/csi/volumesnapshot_action.go index 4f012f8cc..69f881181 100644 --- a/pkg/backup/actions/csi/volumesnapshot_action.go +++ b/pkg/backup/actions/csi/volumesnapshot_action.go @@ -108,12 +108,9 @@ func (p *volumeSnapshotBackupItemAction) Execute( p.log.Infof("Getting VolumesnapshotContent for Volumesnapshot %s/%s", vs.Namespace, vs.Name) - vsc, err := csi.WaitUntilVSCHandleIsReady( - vs, - p.crClient, - p.log, - backup.Spec.CSISnapshotTimeout.Duration, - ) + ctx := context.TODO() + + vsc, err := csi.GetVSCForVS(ctx, vs, p.crClient) if err != nil { csi.CleanupVolumeSnapshot(vs, p.crClient, p.log) return nil, nil, "", nil, errors.WithStack(err) diff --git a/pkg/util/csi/volume_snapshot.go b/pkg/util/csi/volume_snapshot.go index ef70efad0..7d00664cd 100644 --- a/pkg/util/csi/volume_snapshot.go +++ b/pkg/util/csi/volume_snapshot.go @@ -731,3 +731,28 @@ func DiagnoseVSC(vsc *snapshotv1api.VolumeSnapshotContent) string { return diag } + +// GetVSCForVS returns the VolumeSnapshotContent object associated with the VolumeSnapshot. +func GetVSCForVS( + ctx context.Context, + vs *snapshotv1api.VolumeSnapshot, + client crclient.Client, +) (*snapshotv1api.VolumeSnapshotContent, error) { + if vs.Status == nil || vs.Status.BoundVolumeSnapshotContentName == nil { + return nil, errors.Errorf("invalid snapshot info in volume snapshot %s", vs.Name) + } + + vsc := new(snapshotv1api.VolumeSnapshotContent) + + if err := client.Get( + ctx, + crclient.ObjectKey{ + Name: *vs.Status.BoundVolumeSnapshotContentName, + }, + vsc, + ); err != nil { + return nil, errors.Wrap(err, "error getting volume snapshot content from API") + } + + return vsc, nil +} diff --git a/pkg/util/csi/volume_snapshot_test.go b/pkg/util/csi/volume_snapshot_test.go index 72a8e4765..91c9a1ea3 100644 --- a/pkg/util/csi/volume_snapshot_test.go +++ b/pkg/util/csi/volume_snapshot_test.go @@ -21,6 +21,8 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1" snapshotFake "github.com/kubernetes-csi/external-snapshotter/client/v8/clientset/versioned/fake" "github.com/sirupsen/logrus" @@ -36,6 +38,7 @@ import ( velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/builder" + "github.com/vmware-tanzu/velero/pkg/test" velerotest "github.com/vmware-tanzu/velero/pkg/test" "github.com/vmware-tanzu/velero/pkg/util/boolptr" "github.com/vmware-tanzu/velero/pkg/util/logging" @@ -1881,3 +1884,57 @@ func TestDiagnoseVSC(t *testing.T) { }) } } + +func TestGetVSCForVS(t *testing.T) { + testCases := []struct { + name string + vs *snapshotv1api.VolumeSnapshot + vsc *snapshotv1api.VolumeSnapshotContent + expectedErr string + expectedVSC *snapshotv1api.VolumeSnapshotContent + }{ + { + name: "vs has no status", + vs: builder.ForVolumeSnapshot("ns1", "vs1").Result(), + expectedErr: "invalid snapshot info in volume snapshot vs1", + }, + { + name: "vs has no bound vsc", + vs: builder.ForVolumeSnapshot("ns1", "vs1").Status().Result(), + expectedErr: "invalid snapshot info in volume snapshot vs1", + }, + { + name: "vs bound vsc cannot be found", + vs: builder.ForVolumeSnapshot("ns1", "vs1").Status().BoundVolumeSnapshotContentName("vsc1").Result(), + expectedErr: "error getting volume snapshot content from API: volumesnapshotcontents.snapshot.storage.k8s.io \"vsc1\" not found", + }, + { + name: "normal case", + vs: builder.ForVolumeSnapshot("ns1", "vs1").Status().BoundVolumeSnapshotContentName("vsc1").Result(), + vsc: builder.ForVolumeSnapshotContent("vsc1").Result(), + expectedVSC: builder.ForVolumeSnapshotContent("vsc1").Result(), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + objs := []runtime.Object{tc.vs} + if tc.vsc != nil { + objs = append(objs, tc.vsc) + } + + client := test.NewFakeControllerRuntimeClient(t, objs...) + vsc, err := GetVSCForVS(t.Context(), tc.vs, client) + + if tc.expectedErr != "" { + require.EqualError(t, err, tc.expectedErr) + } else { + require.NoError(t, err) + } + + if tc.expectedVSC != nil { + require.True(t, cmp.Equal(tc.expectedVSC, vsc, cmpopts.IgnoreFields(snapshotv1api.VolumeSnapshotContent{}, "ResourceVersion"))) + } + }) + } +}