From 2c2c446c7b2f28057aab2db7458cb821ba825584 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Mon, 21 Apr 2025 17:11:17 +0200 Subject: [PATCH] pybind/rbd: add ImageMemberOfGroup exception EMLINK is returned by rbd_remove() if the image is a member of a group. Add a dedicated exception similar to ImageBusy or ImageHasSnapshots and a test for it. Signed-off-by: Ilya Dryomov (cherry picked from commit 61075e344c18e57b7416072f66c2e335d4d89d75) Conflicts: src/test/pybind/test_rbd.py [ commits 68eea0eb814e ("src/tools/rbd: add group info command to output group id") and e5ccce14c4b0 ("rbd: add group snap info command") not in squid ] --- src/pybind/rbd/rbd.pyx | 8 ++++++++ src/test/pybind/test_rbd.py | 11 ++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index d7c05ac58b49b..e04e3b6d6aab3 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -267,6 +267,12 @@ class ImageHasSnapshots(OSError): "RBD image has snapshots (%s)" % message, errno) +class ImageMemberOfGroup(OSError): + def __init__(self, message, errno=None): + super(ImageMemberOfGroup, self).__init__( + "RBD image is member of group (%s)" % message, errno) + + class FunctionNotSupported(OSError): def __init__(self, message, errno=None): super(FunctionNotSupported, self).__init__( @@ -316,6 +322,7 @@ cdef errno_to_exception = { errno.EROFS : ReadOnlyImage, errno.EBUSY : ImageBusy, errno.ENOTEMPTY : ImageHasSnapshots, + errno.EMLINK : ImageMemberOfGroup, errno.ENOSYS : FunctionNotSupported, errno.EDOM : ArgumentOutOfRange, errno.ESHUTDOWN : ConnectionShutdown, @@ -335,6 +342,7 @@ cdef group_errno_to_exception = { errno.EROFS : ReadOnlyImage, errno.EBUSY : ImageBusy, errno.ENOTEMPTY : ImageHasSnapshots, + errno.EMLINK : ImageMemberOfGroup, errno.ENOSYS : FunctionNotSupported, errno.EDOM : ArgumentOutOfRange, errno.ESHUTDOWN : ConnectionShutdown, diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index d3fbb4415532f..6d9e5802d952a 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -21,7 +21,7 @@ from rados import (Rados, LIBRADOS_OP_FLAG_FADVISE_RANDOM) from rbd import (RBD, Group, Image, ImageNotFound, InvalidArgument, ImageExists, ImageBusy, ImageHasSnapshots, ReadOnlyImage, - FunctionNotSupported, ArgumentOutOfRange, + FunctionNotSupported, ArgumentOutOfRange, ImageMemberOfGroup, ECANCELED, OperationCanceled, DiskQuotaExceeded, ConnectionShutdown, PermissionError, RBD_FEATURE_LAYERING, RBD_FEATURE_STRIPINGV2, @@ -2979,6 +2979,15 @@ class TestGroups(object): eq([], list(self.group.list_images())) RBD().trash_restore(ioctx, image_id, image_name) + def test_group_image_list_remove(self): + # need a closed image to get ImageMemberOfGroup instead of ImageBusy + self.image_names.append(create_image()) + eq([], list(self.group.list_images())) + self.group.add_image(ioctx, image_name) + eq([image_name], [img['name'] for img in self.group.list_images()]) + assert_raises(ImageMemberOfGroup, RBD().remove, ioctx, image_name) + eq([image_name], [img['name'] for img in self.group.list_images()]) + def test_group_image_many_images(self): eq([], list(self.group.list_images())) self.group.add_image(ioctx, image_name) -- 2.39.5