From a40638e9477b19517c34d415606054e0d830012e Mon Sep 17 00:00:00 2001 From: John Mulligan Date: Fri, 8 Jan 2021 13:21:22 -0500 Subject: [PATCH] rbd: add GroupList implementing rbd_group_list Signed-off-by: John Mulligan --- rbd/group.go | 33 +++++++++++++++++++++++++++++++++ rbd/group_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/rbd/group.go b/rbd/group.go index 531c954..7838458 100644 --- a/rbd/group.go +++ b/rbd/group.go @@ -10,6 +10,8 @@ import "C" import ( "unsafe" + "github.com/ceph/go-ceph/internal/cutil" + "github.com/ceph/go-ceph/internal/retry" "github.com/ceph/go-ceph/rados" ) @@ -51,3 +53,34 @@ func GroupRename(ioctx *rados.IOContext, src, dest string) error { ret := C.rbd_group_rename(cephIoctx(ioctx), cSrc, cDest) return getError(ret) } + +// GroupList returns a slice of image group names. +// +// Implements: +// int rbd_group_list(rados_ioctx_t p, char *names, size_t *size); +func GroupList(ioctx *rados.IOContext) ([]string, error) { + var ( + buf []byte + err error + ret C.int + ) + retry.WithSizes(1024, 262144, func(size int) retry.Hint { + cSize := C.size_t(size) + buf = make([]byte, cSize) + ret = C.rbd_group_list( + cephIoctx(ioctx), + (*C.char)(unsafe.Pointer(&buf[0])), + &cSize) + err = getErrorIfNegative(ret) + return retry.Size(int(cSize)).If(err == errRange) + }) + + if err != nil { + return nil, err + } + + // cSize is not set to the expected size when it is sufficiently large + // but ret will be set to the size in a non-error condition. + groups := cutil.SplitBuffer(buf[:ret]) + return groups, nil +} diff --git a/rbd/group_test.go b/rbd/group_test.go index 1fc287e..c4c9f9e 100644 --- a/rbd/group_test.go +++ b/rbd/group_test.go @@ -67,3 +67,49 @@ func TestGroupRename(t *testing.T) { err = GroupRename(ioctx, "club1", "nowhere") assert.Error(t, err) } + +func TestGroupList(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() + + err = GroupCreate(ioctx, "uno") + assert.NoError(t, err) + err = GroupCreate(ioctx, "dos") + assert.NoError(t, err) + err = GroupCreate(ioctx, "tres") + assert.NoError(t, err) + + l, err := GroupList(ioctx) + assert.NoError(t, err) + if assert.Len(t, l, 3) { + assert.Contains(t, l, "uno") + assert.Contains(t, l, "dos") + assert.Contains(t, l, "tres") + } + + err = GroupRemove(ioctx, "uno") + assert.NoError(t, err) + err = GroupRemove(ioctx, "dos") + assert.NoError(t, err) + err = GroupRemove(ioctx, "tres") + assert.NoError(t, err) + + l, err = GroupList(ioctx) + assert.NoError(t, err) + assert.Len(t, l, 0) + + // test that GroupList panics if passed a nil ioctx + assert.Panics(t, func() { + GroupList(nil) + }) +}