diff --git a/internal/rbd/group/group_snapshot.go b/internal/rbd/group/group_snapshot.go index 7abb237addd..f565a600ac0 100644 --- a/internal/rbd/group/group_snapshot.go +++ b/internal/rbd/group/group_snapshot.go @@ -155,6 +155,12 @@ func NewVolumeGroupSnapshot( } volumeMap[handle] = name + + // store the CSI ID of the group in the snapshot attributes + snapErr = snapshot.SetVolumeGroup(ctx, creds, vgs.id) + if snapErr != nil { + return nil, fmt.Errorf("failed to set volume group ID %q for snapshot %q: %w", vgs.id, name, snapErr) + } } j, err := vgs.getJournal(ctx) diff --git a/internal/rbd/manager.go b/internal/rbd/manager.go index 73f783fb027..8b0d6a06448 100644 --- a/internal/rbd/manager.go +++ b/internal/rbd/manager.go @@ -212,11 +212,6 @@ func (mgr *rbdManager) GetSnapshotByID(ctx context.Context, id string) (types.Sn } } - // FIXME: The snapshot will have RbdImageName set to the image that was - // used as source. This is not correct for group snapshots images, and - // need to be fixed. See rbdVolume.NewSnapshotByID() for more details. - snapshot.RbdImageName = snapshot.RbdSnapName - return snapshot, nil } diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index b76187aa0f1..fbae7f4181d 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -191,6 +191,9 @@ type rbdSnapshot struct { // RbdSnapName is the name of the RBD snapshot backing this rbdSnapshot SourceVolumeID string RbdSnapName string + + // groupID is the CSI volume group ID where this snapshot belongs to + groupID string } // imageFeature represents required image features and value. @@ -1054,6 +1057,15 @@ func genSnapFromSnapID( } } + if imageAttributes.GroupID != "" { + rbdSnap.groupID = imageAttributes.GroupID + // FIXME: The snapshot will have RbdImageName set to the image + // that was used as source. This is not correct for group + // snapshots images, and need to be fixed. See + // rbdVolume.NewSnapshotByID() for more details. + rbdSnap.RbdImageName = rbdSnap.RbdSnapName + } + err = rbdSnap.Connect(cr) if err != nil { return rbdSnap, fmt.Errorf("failed to connect to %q: %w", diff --git a/internal/rbd/snapshot.go b/internal/rbd/snapshot.go index 209299e5c50..6a06cefc288 100644 --- a/internal/rbd/snapshot.go +++ b/internal/rbd/snapshot.go @@ -153,11 +153,12 @@ func (rbdSnap *rbdSnapshot) ToCSI(ctx context.Context) (*csi.Snapshot, error) { } return &csi.Snapshot{ - SizeBytes: rbdSnap.VolSize, - SnapshotId: rbdSnap.VolID, - SourceVolumeId: rbdSnap.SourceVolumeID, - CreationTime: timestamppb.New(*created), - ReadyToUse: true, + SizeBytes: rbdSnap.VolSize, + SnapshotId: rbdSnap.VolID, + SourceVolumeId: rbdSnap.SourceVolumeID, + CreationTime: timestamppb.New(*created), + ReadyToUse: true, + GroupSnapshotId: rbdSnap.groupID, }, nil } @@ -315,3 +316,26 @@ func (rv *rbdVolume) NewSnapshotByID( return snap, nil } + +func (rbdSnap *rbdSnapshot) SetVolumeGroup(ctx context.Context, cr *util.Credentials, groupID string) error { + vi := util.CSIIdentifier{} + err := vi.DecomposeCSIID(rbdSnap.VolID) + if err != nil { + return err + } + + j, err := snapJournal.Connect(rbdSnap.Monitors, rbdSnap.RadosNamespace, cr) + if err != nil { + return fmt.Errorf("snapshot %q failed to connect to journal: %w", rbdSnap, err) + } + defer j.Destroy() + + err = j.StoreGroupID(ctx, rbdSnap.Pool, vi.ObjectUUID, groupID) + if err != nil { + return fmt.Errorf("failed to set volume group ID for snapshot %q: %w", rbdSnap, err) + } + + rbdSnap.groupID = groupID + + return nil +} diff --git a/internal/rbd/types/snapshot.go b/internal/rbd/types/snapshot.go index 90e4ef13e79..95487821618 100644 --- a/internal/rbd/types/snapshot.go +++ b/internal/rbd/types/snapshot.go @@ -21,6 +21,8 @@ import ( "time" "github.com/container-storage-interface/spec/lib/go/csi" + + "github.com/ceph/ceph-csi/internal/util" ) type Snapshot interface { @@ -35,4 +37,7 @@ type Snapshot interface { ToCSI(ctx context.Context) (*csi.Snapshot, error) GetCreationTime(ctx context.Context) (*time.Time, error) + + // SetVolumeGroup sets the CSI volume group ID in the snapshot. + SetVolumeGroup(ctx context.Context, creds *util.Credentials, vgID string) error }