From fdccba1f3386066463a300246acf5cc301d26c62 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Thu, 17 Oct 2024 17:34:24 +0200 Subject: [PATCH] rbd: add Manager.GetVolumeGroupSnapshotByName The Group Controller Server may need to fetch a VolumeGroupSnapshot that was statically provisioned. In that case, only the name of the VolumeGroupSnapshot is known and should be resolved to an object. Signed-off-by: Niels de Vos --- internal/rbd/manager.go | 62 +++++++++++++++++++++++++++++++++++ internal/rbd/types/manager.go | 4 +++ 2 files changed, 66 insertions(+) diff --git a/internal/rbd/manager.go b/internal/rbd/manager.go index d637c89a7..8b0d6a064 100644 --- a/internal/rbd/manager.go +++ b/internal/rbd/manager.go @@ -337,6 +337,68 @@ func (mgr *rbdManager) GetVolumeGroupSnapshotByID( return vgs, nil } +func (mgr *rbdManager) GetVolumeGroupSnapshotByName( + ctx context.Context, + name string, +) (types.VolumeGroupSnapshot, error) { + pool, ok := mgr.parameters["pool"] + if !ok || pool == "" { + return nil, errors.New("required 'pool' option missing in volume group parameters") + } + + // groupNamePrefix is an optional parameter, can be an empty string + prefix := mgr.parameters["groupNamePrefix"] + + clusterID, err := util.GetClusterID(mgr.parameters) + if err != nil { + return nil, fmt.Errorf("failed to get cluster-id: %w", err) + } + + uuid, freeUUID, err := mgr.getGroupUUID(ctx, clusterID, pool, name, prefix) + if err != nil { + return nil, fmt.Errorf("failed to get a UUID for volume group snapshot %q: %w", name, err) + } + defer func() { + // no error, no need to undo the reservation + if err == nil { + return + } + + freeUUID() + }() + + monitors, err := util.Mons(util.CsiConfigFile, clusterID) + if err != nil { + return nil, fmt.Errorf("failed to find MONs for cluster %q: %w", clusterID, err) + } + + _ /*journalPoolID*/, poolID, err := util.GetPoolIDs(ctx, monitors, pool, pool, mgr.creds) + if err != nil { + return nil, fmt.Errorf("failed to get the pool for volume group snapshot with uuid for %q: %w", uuid, err) + } + + csiID, err := util.GenerateVolID(ctx, monitors, mgr.creds, poolID, pool, clusterID, uuid) + if err != nil { + return nil, fmt.Errorf("failed to generate a unique CSI volume group with uuid %q: %w", uuid, err) + } + + vgs, err := rbd_group.GetVolumeGroupSnapshot(ctx, csiID, mgr.csiID, mgr.creds, mgr) + if err != nil { + return nil, fmt.Errorf("failed to get existing volume group snapshot with uuid %q: %w", uuid, err) + } + + snapshots, err := vgs.ListSnapshots(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get snapshots for volume group snapshot %q: %w", vgs, err) + } + + if len(snapshots) == 0 { + return nil, fmt.Errorf("volume group snapshot %q is incomplete, it has no snapshots", vgs) + } + + return vgs, nil +} + func (mgr *rbdManager) CreateVolumeGroupSnapshot( ctx context.Context, vg types.VolumeGroup, diff --git a/internal/rbd/types/manager.go b/internal/rbd/types/manager.go index 105e28374..273bd5810 100644 --- a/internal/rbd/types/manager.go +++ b/internal/rbd/types/manager.go @@ -57,6 +57,10 @@ type Manager interface { // CSI id/handle. GetVolumeGroupSnapshotByID(ctx context.Context, id string) (VolumeGroupSnapshot, error) + // GetVolumeGroupSnapshotByName resolves the VolumeGroupSnapshot by the + // name (like the request-id). + GetVolumeGroupSnapshotByName(ctx context.Context, name string) (VolumeGroupSnapshot, error) + // CreateVolumeGroupSnapshot instructs the Manager to create a // VolumeGroupSnapshot from the VolumeGroup. All snapshots in the // returned VolumeGroupSnapshot have been taken while I/O on the