mirror of
https://github.com/ceph/go-ceph
synced 2025-01-24 15:13:34 +00:00
rbd: add functions and constants related to snapshot namespace.
Added few constants used for determining snapshot namespace. Added wrapper for function rbd_snap_get_namespace_type() which returns namespace type for a given snapshot. Signed-off-by: Mudit Agarwal <muagarwa@redhat.com>
This commit is contained in:
parent
7dea1f728f
commit
a5da5e308b
42
rbd/snapshot_namespace.go
Normal file
42
rbd/snapshot_namespace.go
Normal file
@ -0,0 +1,42 @@
|
||||
// +build !luminous
|
||||
//
|
||||
// Ceph Mimic introduced rbd_snap_get_namespace_type().
|
||||
|
||||
package rbd
|
||||
|
||||
// #cgo LDFLAGS: -lrbd
|
||||
// #include <rbd/librbd.h>
|
||||
import "C"
|
||||
|
||||
// SnapNamespaceType indicates the namespace to which the snapshot belongs to.
|
||||
type SnapNamespaceType C.rbd_snap_namespace_type_t
|
||||
|
||||
const (
|
||||
// SnapNamespaceTypeUser indicates that the snapshot belongs to user namespace.
|
||||
SnapNamespaceTypeUser = SnapNamespaceType(C.RBD_SNAP_NAMESPACE_TYPE_USER)
|
||||
|
||||
// SnapNamespaceTypeGroup indicates that the snapshot belongs to group namespace.
|
||||
// Such snapshots will have associated group information.
|
||||
SnapNamespaceTypeGroup = SnapNamespaceType(C.RBD_SNAP_NAMESPACE_TYPE_GROUP)
|
||||
|
||||
// SnapNamespaceTypeTrash indicates that the snapshot belongs to trash namespace.
|
||||
SnapNamespaceTypeTrash = SnapNamespaceType(C.RBD_SNAP_NAMESPACE_TYPE_TRASH)
|
||||
)
|
||||
|
||||
// GetSnapNamespaceType gets the type of namespace to which the snapshot belongs to,
|
||||
// returns error on failure.
|
||||
//
|
||||
// Implements:
|
||||
// int rbd_snap_get_namespace_type(rbd_image_t image, uint64_t snap_id, rbd_snap_namespace_type_t *namespace_type)
|
||||
func (image *Image) GetSnapNamespaceType(snapID uint64) (SnapNamespaceType, error) {
|
||||
var nsType SnapNamespaceType
|
||||
|
||||
if err := image.validate(imageIsOpen); err != nil {
|
||||
return nsType, err
|
||||
}
|
||||
|
||||
ret := C.rbd_snap_get_namespace_type(image.image,
|
||||
C.uint64_t(snapID),
|
||||
(*C.rbd_snap_namespace_type_t)(&nsType))
|
||||
return nsType, getError(ret)
|
||||
}
|
111
rbd/snapshot_namespace_test.go
Normal file
111
rbd/snapshot_namespace_test.go
Normal file
@ -0,0 +1,111 @@
|
||||
// +build !luminous
|
||||
|
||||
package rbd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetSnapNamespaceType(t *testing.T) {
|
||||
conn := radosConnect(t)
|
||||
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()
|
||||
|
||||
imageName := "parent"
|
||||
snapName := "mySnap"
|
||||
options := NewRbdImageOptions()
|
||||
defer options.Destroy()
|
||||
err = options.SetUint64(ImageOptionOrder, uint64(testImageOrder))
|
||||
assert.NoError(t, err)
|
||||
err = options.SetUint64(ImageOptionFeatures, 1)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = CreateImage(ioctx, imageName, testImageSize, options)
|
||||
assert.NoError(t, err)
|
||||
|
||||
img, err := OpenImage(ioctx, imageName, NoSnapshot)
|
||||
assert.NoError(t, err)
|
||||
|
||||
defer func() {
|
||||
assert.NoError(t, img.Close())
|
||||
assert.NoError(t, img.Remove())
|
||||
}()
|
||||
|
||||
snapshot, err := img.CreateSnapshot(snapName)
|
||||
assert.NoError(t, err)
|
||||
|
||||
snapInfoList, err := img.GetSnapshotNames()
|
||||
assert.NoError(t, err)
|
||||
|
||||
snapInfo := snapInfoList[0]
|
||||
assert.Equal(t, snapInfo.Name, snapName)
|
||||
|
||||
t.Run("SnapNamespaceTypeInvalidArgs", func(t *testing.T) {
|
||||
validImageName := GetUUID()
|
||||
validImg, err := Create(ioctx, validImageName, testImageSize, testImageOrder, 1)
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
assert.NoError(t, validImg.Remove())
|
||||
}()
|
||||
|
||||
validImg = GetImage(ioctx, validImageName)
|
||||
// Closed image and a snapshot ID which doesn't belong to this image.
|
||||
_, err = validImg.GetSnapNamespaceType(snapInfo.Id)
|
||||
assert.Error(t, err)
|
||||
|
||||
// Open image but invalid snap ID.
|
||||
validImg, err = OpenImage(ioctx, validImageName, NoSnapshot)
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
assert.NoError(t, validImg.Close())
|
||||
}()
|
||||
|
||||
_, err = validImg.GetSnapNamespaceType(uint64(22))
|
||||
assert.Error(t, err)
|
||||
|
||||
// With non-existing image.
|
||||
invalidImageName := GetUUID()
|
||||
invalidImg := GetImage(ioctx, invalidImageName)
|
||||
_, err = invalidImg.GetSnapNamespaceType(snapInfo.Id)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("SnapNamespaceTypeUser", func(t *testing.T) {
|
||||
nsType, err := img.GetSnapNamespaceType(snapInfo.Id)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, nsType, SnapNamespaceTypeUser)
|
||||
})
|
||||
|
||||
t.Run("SnapNamespaceTypeTrash", func(t *testing.T) {
|
||||
cloneName := "myClone"
|
||||
optionsClone := NewRbdImageOptions()
|
||||
defer optionsClone.Destroy()
|
||||
err := optionsClone.SetUint64(ImageOptionCloneFormat, 2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create a clone of the image using the same snapshot.
|
||||
err = CloneImage(ioctx, imageName, snapName, ioctx, cloneName, optionsClone)
|
||||
assert.NoError(t, err)
|
||||
defer func() { assert.NoError(t, RemoveImage(ioctx, cloneName)) }()
|
||||
|
||||
// Once clone is created, remove the snapshot.
|
||||
err = snapshot.Remove()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Snapshot would move to the trash because linked clone is still there.
|
||||
nsType, err := img.GetSnapNamespaceType(snapInfo.Id)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, nsType, SnapNamespaceTypeTrash)
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user