diff --git a/rbd/group.go b/rbd/group.go index 7838458..ba45527 100644 --- a/rbd/group.go +++ b/rbd/group.go @@ -84,3 +84,75 @@ func GroupList(ioctx *rados.IOContext) ([]string, error) { groups := cutil.SplitBuffer(buf[:ret]) return groups, nil } + +// GroupImageAdd will add the specified image to the named group. +// An io context must be supplied for both the group and image. +// +// Implements: +// int rbd_group_image_add(rados_ioctx_t group_p, +// const char *group_name, +// rados_ioctx_t image_p, +// const char *image_name); +func GroupImageAdd(groupIoctx *rados.IOContext, groupName string, + imageIoctx *rados.IOContext, imageName string) error { + + cGroupName := C.CString(groupName) + defer C.free(unsafe.Pointer(cGroupName)) + cImageName := C.CString(imageName) + defer C.free(unsafe.Pointer(cImageName)) + + ret := C.rbd_group_image_add( + cephIoctx(groupIoctx), + cGroupName, + cephIoctx(imageIoctx), + cImageName) + return getError(ret) +} + +// GroupImageRemove will remove the specified image from the named group. +// An io context must be supplied for both the group and image. +// +// Implements: +// int rbd_group_image_remove(rados_ioctx_t group_p, +// const char *group_name, +// rados_ioctx_t image_p, +// const char *image_name); +func GroupImageRemove(groupIoctx *rados.IOContext, groupName string, + imageIoctx *rados.IOContext, imageName string) error { + + cGroupName := C.CString(groupName) + defer C.free(unsafe.Pointer(cGroupName)) + cImageName := C.CString(imageName) + defer C.free(unsafe.Pointer(cImageName)) + + ret := C.rbd_group_image_remove( + cephIoctx(groupIoctx), + cGroupName, + cephIoctx(imageIoctx), + cImageName) + return getError(ret) +} + +// GroupImageRemoveByID will remove the specified image from the named group. +// An io context must be supplied for both the group and image. +// +// Implements: +// CEPH_RBD_API int rbd_group_image_remove_by_id(rados_ioctx_t group_p, +// const char *group_name, +// rados_ioctx_t image_p, +// const char *image_id); +func GroupImageRemoveByID(groupIoctx *rados.IOContext, groupName string, + imageIoctx *rados.IOContext, imageID string) error { + + cGroupName := C.CString(groupName) + defer C.free(unsafe.Pointer(cGroupName)) + cid := C.CString(imageID) + defer C.free(unsafe.Pointer(cid)) + + ret := C.rbd_group_image_remove_by_id( + cephIoctx(groupIoctx), + cGroupName, + cephIoctx(imageIoctx), + cid) + return getError(ret) +} diff --git a/rbd/group_test.go b/rbd/group_test.go index c4c9f9e..bc2c8ab 100644 --- a/rbd/group_test.go +++ b/rbd/group_test.go @@ -113,3 +113,130 @@ func TestGroupList(t *testing.T) { GroupList(nil) }) } + +func TestGroupImageAdd(t *testing.T) { + 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() + + name := GetUUID() + options := NewRbdImageOptions() + assert.NoError(t, + options.SetUint64(ImageOptionOrder, uint64(testImageOrder))) + err = CreateImage(ioctx, name, testImageSize, options) + require.NoError(t, err) + + err = GroupCreate(ioctx, "grone") + assert.NoError(t, err) + + err = GroupImageAdd(ioctx, "grone", ioctx, name) + assert.NoError(t, err) + + err = GroupImageAdd(ioctx, "badGroup", ioctx, name) + assert.Error(t, err) + + assert.Panics(t, func() { + GroupImageAdd(nil, "invalid", ioctx, "foobar") + }) + assert.Panics(t, func() { + GroupImageAdd(ioctx, "invalid", nil, "foobar") + }) +} + +func TestGroupImageRemove(t *testing.T) { + 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() + + name := GetUUID() + options := NewRbdImageOptions() + assert.NoError(t, + options.SetUint64(ImageOptionOrder, uint64(testImageOrder))) + err = CreateImage(ioctx, name, testImageSize, options) + require.NoError(t, err) + + err = GroupCreate(ioctx, "grone") + assert.NoError(t, err) + + err = GroupImageAdd(ioctx, "grone", ioctx, name) + assert.NoError(t, err) + + err = GroupImageRemove(ioctx, "grone", ioctx, name) + assert.NoError(t, err) + + err = GroupImageRemove(ioctx, "badGroup", ioctx, name) + assert.Error(t, err) + + assert.Panics(t, func() { + GroupImageRemove(nil, "invalid", ioctx, "foobar") + }) + assert.Panics(t, func() { + GroupImageRemove(ioctx, "invalid", nil, "foobar") + }) +} + +func TestGroupImageRemoveByID(t *testing.T) { + 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() + + name := GetUUID() + options := NewRbdImageOptions() + assert.NoError(t, + options.SetUint64(ImageOptionOrder, uint64(testImageOrder))) + err = CreateImage(ioctx, name, testImageSize, options) + require.NoError(t, err) + + err = GroupCreate(ioctx, "grone") + assert.NoError(t, err) + + err = GroupImageAdd(ioctx, "grone", ioctx, name) + assert.NoError(t, err) + + img, err := OpenImage(ioctx, name, NoSnapshot) + assert.NoError(t, err) + imageID, err := img.GetId() + assert.NoError(t, err) + err = img.Close() + assert.NoError(t, err) + + err = GroupImageRemoveByID(ioctx, "grone", ioctx, imageID) + assert.NoError(t, err) + + err = GroupImageRemoveByID(ioctx, "badGroup", ioctx, imageID) + assert.Error(t, err) + + assert.Panics(t, func() { + GroupImageRemoveByID(nil, "invalid", ioctx, "foobar") + }) + assert.Panics(t, func() { + GroupImageRemoveByID(ioctx, "invalid", nil, "foobar") + }) +}