Skip to content

Commit

Permalink
rbd: include details for parent image in the trash
Browse files Browse the repository at this point in the history
When a parent image has been removed, it will linger in the trash until
all siblings are gone. The image is not accessible through it's name
anymore, only through its ID.

The ImageSpec that is returned by Image.GetParent() now contains the
Trash boolean and the ImageID to identify if the image is in the trash,
and use OpenImageById() to access the removed parent image.

Related-to: ceph/ceph-csi#4013
Signed-off-by: Niels de Vos <ndevos@ibm.com>
  • Loading branch information
nixpanic authored and mergify[bot] committed Aug 2, 2023
1 parent 85524f6 commit 1257d81
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
50 changes: 50 additions & 0 deletions rbd/rbd_nautilus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package rbd

import (
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -185,6 +186,55 @@ func TestGetParent(t *testing.T) {
assert.Equal(t, parentInfo.Image.ImageName, imgName)
assert.Equal(t, parentInfo.Snap.SnapName, snapName)
assert.Equal(t, parentInfo.Image.PoolName, poolName)
assert.False(t, parentInfo.Image.Trash)
// TODO: add a comaprison for snap ID
})

t.Run("ParentInTrash", func(t *testing.T) {
trashName := "trashed"
_, err := Create(ioctx, trashName, testImageSize, testImageOrder, 1)
assert.NoError(t, err)

imgTrash, err := OpenImage(ioctx, trashName, NoSnapshot)
assert.NoError(t, err)
defer func() { assert.NoError(t, imgTrash.Close()) }()
imgTrashID, err := imgTrash.GetId()
assert.NoError(t, err)

snapNameTrash := "snapTrash"
snapTrash, err := imgTrash.CreateSnapshot(snapNameTrash)
assert.NoError(t, err)
defer func() {
assert.NoError(t, snapTrash.Remove())
}()

cloneName := "childWithTrash"
optionsClone := NewRbdImageOptions()
defer optionsClone.Destroy()
err = optionsClone.SetUint64(ImageOptionCloneFormat, 2)
assert.NoError(t, err)

// Create a clone of the image.
err = CloneImage(ioctx, trashName, snapNameTrash, ioctx, cloneName, optionsClone)
assert.NoError(t, err)
defer func() { assert.NoError(t, RemoveImage(ioctx, cloneName)) }()

// Move the parent image to the trash, won't be deleted until the clone is removed.
assert.NoError(t, imgTrash.Trash(15*time.Second))

imgNew, err := OpenImage(ioctx, cloneName, NoSnapshot)
assert.NoError(t, err)
defer func() {
assert.NoError(t, imgNew.Close())
}()

parentInfo, err := imgNew.GetParent()
assert.NoError(t, err)
assert.Equal(t, parentInfo.Image.ImageName, trashName)
assert.Equal(t, parentInfo.Image.ImageID, imgTrashID)
assert.Equal(t, parentInfo.Image.PoolName, poolName)
assert.True(t, parentInfo.Image.Trash)
assert.Equal(t, parentInfo.Snap.SnapName, snapNameTrash)
// TODO: add a comaprison for snap ID
})

Expand Down
16 changes: 12 additions & 4 deletions rbd/snapshot_nautilus.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,12 @@ func (image *Image) GetParentInfo(pool, name, snapname []byte) error {

// ImageSpec represents the image information.
type ImageSpec struct {
ImageName string
PoolName string
ImageName string
ImageID string
PoolName string
PoolNamespace string
PoolID uint64
Trash bool
}

// SnapSpec represents the snapshot infomation.
Expand Down Expand Up @@ -104,8 +108,12 @@ func (image *Image) GetParent() (*ParentInfo, error) {
defer C.rbd_snap_spec_cleanup(&parentSnap)

imageSpec := ImageSpec{
ImageName: C.GoString(parentImage.image_name),
PoolName: C.GoString(parentImage.pool_name),
ImageName: C.GoString(parentImage.image_name),
ImageID: C.GoString(parentImage.image_id),
PoolName: C.GoString(parentImage.pool_name),
PoolNamespace: C.GoString(parentImage.pool_namespace),
PoolID: uint64(parentImage.pool_id),
Trash: bool(parentImage.trash),
}

snapSpec := SnapSpec{
Expand Down

0 comments on commit 1257d81

Please sign in to comment.