rbd: add GroupImageList implementing rbd_group_image_list

This function can be used to list the images in a group.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
This commit is contained in:
John Mulligan 2021-01-20 14:35:25 -05:00 committed by mergify[bot]
parent cd0a5bfe01
commit cbf2a51698
2 changed files with 139 additions and 0 deletions

View File

@ -156,3 +156,70 @@ func GroupImageRemoveByID(groupIoctx *rados.IOContext, groupName string,
cid) cid)
return getError(ret) return getError(ret)
} }
// GroupImageState indicates an image's state in a group.
type GroupImageState int
const (
// GroupImageStateAttached is equivalent to RBD_GROUP_IMAGE_STATE_ATTACHED
GroupImageStateAttached = GroupImageState(C.RBD_GROUP_IMAGE_STATE_ATTACHED)
// GroupImageStateIncomplete is equivalent to RBD_GROUP_IMAGE_STATE_INCOMPLETE
GroupImageStateIncomplete = GroupImageState(C.RBD_GROUP_IMAGE_STATE_INCOMPLETE)
)
// GroupImageInfo reports on images within a group.
type GroupImageInfo struct {
Name string
PoolID int64
State GroupImageState
}
// GroupImageList returns a slice of GroupImageInfo types based on the
// images that are part of the named group.
//
// Implements:
// int rbd_group_image_list(rados_ioctx_t group_p,
// const char *group_name,
// rbd_group_image_info_t *images,
// size_t group_image_info_size,
// size_t *num_entries);
func GroupImageList(ioctx *rados.IOContext, name string) ([]GroupImageInfo, error) {
cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))
var (
cImages []C.rbd_group_image_info_t
cSize C.size_t
err error
)
retry.WithSizes(1024, 262144, func(size int) retry.Hint {
cSize = C.size_t(size)
cImages = make([]C.rbd_group_image_info_t, cSize)
ret := C.rbd_group_image_list(
cephIoctx(ioctx),
cName,
(*C.rbd_group_image_info_t)(unsafe.Pointer(&cImages[0])),
C.sizeof_rbd_group_image_info_t,
&cSize)
err = getErrorIfNegative(ret)
return retry.Size(int(cSize)).If(err == errRange)
})
if err != nil {
return nil, err
}
images := make([]GroupImageInfo, cSize)
for i := range images {
images[i].Name = C.GoString(cImages[i].name)
images[i].PoolID = int64(cImages[i].pool)
images[i].State = GroupImageState(cImages[i].state)
}
// free C memory allocated by C.rbd_group_image_list call
ret := C.rbd_group_image_list_cleanup(
(*C.rbd_group_image_info_t)(unsafe.Pointer(&cImages[0])),
C.sizeof_rbd_group_image_info_t,
cSize)
return images, getError(ret)
}

View File

@ -240,3 +240,75 @@ func TestGroupImageRemoveByID(t *testing.T) {
GroupImageRemoveByID(ioctx, "invalid", nil, "foobar") GroupImageRemoveByID(ioctx, "invalid", nil, "foobar")
}) })
} }
func TestGroupImageList(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()
options := NewRbdImageOptions()
assert.NoError(t,
options.SetUint64(ImageOptionOrder, uint64(testImageOrder)))
name1 := GetUUID()
err = CreateImage(ioctx, name1, testImageSize, options)
require.NoError(t, err)
name2 := GetUUID()
err = CreateImage(ioctx, name2, testImageSize, options)
require.NoError(t, err)
err = GroupCreate(ioctx, "grone")
assert.NoError(t, err)
err = GroupImageAdd(ioctx, "grone", ioctx, name1)
assert.NoError(t, err)
gimgs, err := GroupImageList(ioctx, "grone")
assert.NoError(t, err)
assert.NotNil(t, gimgs)
if assert.Len(t, gimgs, 1) {
assert.Equal(t, name1, gimgs[0].Name)
assert.Equal(t, GroupImageStateAttached, gimgs[0].State)
}
err = GroupImageAdd(ioctx, "grone", ioctx, name2)
assert.NoError(t, err)
gimgs, err = GroupImageList(ioctx, "grone")
assert.NoError(t, err)
assert.NotNil(t, gimgs)
if assert.Len(t, gimgs, 2) {
// order is not assured!
names := []string{}
for _, gimg := range gimgs {
names = append(names, gimg.Name)
}
assert.Contains(t, names, name1)
assert.Contains(t, names, name2)
}
err = GroupImageRemove(ioctx, "grone", ioctx, name1)
assert.NoError(t, err)
gimgs, err = GroupImageList(ioctx, "grone")
assert.NoError(t, err)
assert.NotNil(t, gimgs)
if assert.Len(t, gimgs, 1) {
assert.Equal(t, name2, gimgs[0].Name)
assert.Equal(t, GroupImageStateAttached, gimgs[0].State)
}
assert.Panics(t, func() {
GroupImageList(nil, "foo")
})
}