mirror of
https://github.com/ceph/go-ceph
synced 2024-12-23 22:53:47 +00:00
a9ce294dbb
Some versions of librbd provide the rbd_clone4 function, and others do not. Squid will have the function backported in the 1st update, the initial release of Squid does not have it. This makes checking for the function based on the named Ceph version impractical. With the new dlsym.LookupSymbol() function, it is now possible to check the availability of rbd_clone4 during runtime. If the symbol is not found ErrNotImplemented is returned, which can be used to detect the unavailability of the function. Signed-off-by: Niels de Vos <ndevos@ibm.com>
162 lines
4.3 KiB
Go
162 lines
4.3 KiB
Go
//go:build ceph_preview
|
|
|
|
package rbd
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestCloneImageByID(t *testing.T) {
|
|
// tests are done as subtests to avoid creating pools, images, etc
|
|
// over and over again.
|
|
conn := radosConnect(t)
|
|
require.NotNil(t, conn)
|
|
defer conn.Shutdown()
|
|
|
|
poolname := GetUUID()
|
|
err := conn.MakePool(poolname)
|
|
require.NoError(t, err)
|
|
defer conn.DeletePool(poolname)
|
|
|
|
ioctx, err := conn.OpenIOContext(poolname)
|
|
require.NoError(t, err)
|
|
defer ioctx.Destroy()
|
|
|
|
// create a group, some images, and add images to the group
|
|
gname := "snapme"
|
|
err = GroupCreate(ioctx, gname)
|
|
assert.NoError(t, err)
|
|
defer func() {
|
|
assert.NoError(t, GroupRemove(ioctx, gname))
|
|
}()
|
|
|
|
options := NewRbdImageOptions()
|
|
assert.NoError(t,
|
|
options.SetUint64(ImageOptionOrder, uint64(testImageOrder)))
|
|
defer options.Destroy()
|
|
|
|
name1 := GetUUID()
|
|
err = CreateImage(ioctx, name1, testImageSize, options)
|
|
require.NoError(t, err)
|
|
defer func() {
|
|
assert.NoError(t, RemoveImage(ioctx, name1))
|
|
}()
|
|
|
|
name2 := GetUUID()
|
|
err = CreateImage(ioctx, name2, testImageSize, options)
|
|
require.NoError(t, err)
|
|
defer func() {
|
|
assert.NoError(t, RemoveImage(ioctx, name2))
|
|
}()
|
|
|
|
err = GroupImageAdd(ioctx, gname, ioctx, name1)
|
|
assert.NoError(t, err)
|
|
defer func() {
|
|
assert.NoError(t, GroupImageRemove(ioctx, gname, ioctx, name1))
|
|
}()
|
|
|
|
err = GroupImageAdd(ioctx, gname, ioctx, name2)
|
|
assert.NoError(t, err)
|
|
defer func() {
|
|
assert.NoError(t, GroupImageRemove(ioctx, gname, ioctx, name2))
|
|
}()
|
|
|
|
t.Run("CloneFromSnapshot", func(t *testing.T) {
|
|
cloneName := "child"
|
|
optionsClone := NewRbdImageOptions()
|
|
defer optionsClone.Destroy()
|
|
err := optionsClone.SetUint64(ImageOptionCloneFormat, 2)
|
|
assert.NoError(t, err)
|
|
|
|
// Get the snapID
|
|
img, err := OpenImage(ioctx, name1, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
defer img.Close()
|
|
|
|
snapName := "mysnap"
|
|
snapshot, err := img.CreateSnapshot(snapName)
|
|
assert.NoError(t, err)
|
|
defer func() {
|
|
assert.NoError(t, snapshot.Remove())
|
|
}()
|
|
|
|
snapInfos, err := img.GetSnapshotNames()
|
|
assert.NoError(t, err)
|
|
require.Equal(t, 1, len(snapInfos))
|
|
|
|
snapID := snapInfos[0].Id
|
|
|
|
// Create a clone of the image using the snapshot.
|
|
err = CloneImageByID(ioctx, name1, snapID, ioctx, cloneName, optionsClone)
|
|
if errors.Is(err, ErrNotImplemented) {
|
|
t.Skipf("CloneImageByID is not supported: %v", err)
|
|
}
|
|
assert.NoError(t, err)
|
|
defer func() { assert.NoError(t, RemoveImage(ioctx, cloneName)) }()
|
|
|
|
imgNew, err := OpenImage(ioctx, cloneName, NoSnapshot)
|
|
defer func() {
|
|
assert.NoError(t, imgNew.Close())
|
|
}()
|
|
assert.NoError(t, err)
|
|
|
|
parentInfo, err := imgNew.GetParent()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, parentInfo.Image.ImageName, name1)
|
|
assert.Equal(t, parentInfo.Image.PoolName, poolname)
|
|
assert.False(t, parentInfo.Image.Trash)
|
|
assert.Equal(t, parentInfo.Snap.SnapName, snapName)
|
|
assert.Equal(t, parentInfo.Snap.ID, snapID)
|
|
})
|
|
|
|
t.Run("CloneFromGroupSnap", func(t *testing.T) {
|
|
err := GroupSnapCreate(ioctx, gname, "groupsnap")
|
|
assert.NoError(t, err)
|
|
defer func() {
|
|
assert.NoError(t, GroupSnapRemove(ioctx, gname, "groupsnap"))
|
|
}()
|
|
|
|
cloneName := "img-clone"
|
|
optionsClone := NewRbdImageOptions()
|
|
defer optionsClone.Destroy()
|
|
err = optionsClone.SetUint64(ImageOptionCloneFormat, 2)
|
|
assert.NoError(t, err)
|
|
|
|
// Get the snapID of the image
|
|
img, err := OpenImageReadOnly(ioctx, name1, NoSnapshot)
|
|
assert.NoError(t, err)
|
|
defer img.Close()
|
|
|
|
snapInfos, err := img.GetSnapshotNames()
|
|
assert.NoError(t, err)
|
|
require.Equal(t, 1, len(snapInfos))
|
|
|
|
snapID := snapInfos[0].Id
|
|
|
|
// Create a clone of the image using the snapshot.
|
|
err = CloneImageByID(ioctx, name1, snapID, ioctx, cloneName, optionsClone)
|
|
if errors.Is(err, ErrNotImplemented) {
|
|
t.Skipf("CloneImageByID is not supported: %v", err)
|
|
}
|
|
assert.NoError(t, err)
|
|
defer func() { assert.NoError(t, RemoveImage(ioctx, cloneName)) }()
|
|
|
|
imgNew, err := OpenImage(ioctx, cloneName, NoSnapshot)
|
|
defer func() {
|
|
assert.NoError(t, imgNew.Close())
|
|
}()
|
|
assert.NoError(t, err)
|
|
|
|
parentInfo, err := imgNew.GetParent()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, parentInfo.Image.ImageName, name1)
|
|
assert.Equal(t, parentInfo.Snap.ID, snapID)
|
|
assert.Equal(t, parentInfo.Image.PoolName, poolname)
|
|
assert.False(t, parentInfo.Image.Trash)
|
|
})
|
|
}
|