Skip to content

Commit 29d377a

Browse files
committed
Trash RBD image on namespace deletion.
Fixes #953 Signed-off-by: Gil Bregman <gbregman@il.ibm.com>
1 parent 5bc26c0 commit 29d377a

File tree

7 files changed

+354
-32
lines changed

7 files changed

+354
-32
lines changed

.github/workflows/build-container.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ jobs:
139139
strategy:
140140
fail-fast: false
141141
matrix:
142-
test: ["cli", "cli_change_lb", "cli_change_keys", "cli_change_ns_visibility", "state", "multi_gateway", "server", "grpc", "omap_lock", "log_files", "nsid", "psk", "dhchap", "subsys_grp_name_append"]
142+
test: ["cli", "cli_change_lb", "cli_change_keys", "cli_change_ns_visibility", "cli_trash_rbd", "state", "multi_gateway", "server", "grpc", "omap_lock", "log_files", "nsid", "psk", "dhchap", "subsys_grp_name_append"]
143143
runs-on: ubuntu-latest
144144
env:
145145
HUGEPAGES: 512 # for multi gateway test, approx 256 per gateway instance

control/cephutils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,28 @@ def create_image(self, pool_name, image_name, size) -> bool:
185185

186186
return True
187187

188+
def delete_image(self, pool_name, image_name) -> bool:
189+
if not pool_name and not image_name:
190+
return True
191+
192+
if not self.pool_exists(pool_name):
193+
self.logger.warning(f"Pool {pool_name} doesn't exist, can't delete RBD image")
194+
return True
195+
196+
with rados.Rados(conffile=self.ceph_conf, rados_id=self.rados_id) as cluster:
197+
with cluster.open_ioctx(pool_name) as ioctx:
198+
rbd_inst = rbd.RBD()
199+
try:
200+
rbd_inst.remove(ioctx, image_name)
201+
except rbd.ImageNotFound:
202+
self.logger.warning(f"Image {pool_name}/{image_name} is not found")
203+
return True
204+
except (rbd.ImageBusy, rbd.ImageHasSnapshots):
205+
self.logger.exception(f"Can't delete image {pool_name}/{image_name}")
206+
return False
207+
208+
return True
209+
188210
def get_image_size(self, pool_name, image_name) -> int:
189211
image_size = 0
190212
if not self.pool_exists(pool_name):

control/cli.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,10 @@ def ns_add(self, args):
17261726
self.cli.parser.error("--size argument is not allowed for add command when "
17271727
"RBD image creation is disabled")
17281728

1729+
if args.rbd_trash_image_on_delete and not args.rbd_create_image:
1730+
self.cli.parser.error("Can't trash associated RBD image on delete if it wasn't "
1731+
"created automatically by the gateway")
1732+
17291733
req = pb2.namespace_add_req(rbd_pool_name=args.rbd_pool,
17301734
rbd_image_name=args.rbd_image,
17311735
subsystem_nqn=args.subsystem,
@@ -1736,7 +1740,8 @@ def ns_add(self, args):
17361740
create_image=args.rbd_create_image,
17371741
size=img_size,
17381742
force=args.force,
1739-
no_auto_visible=args.no_auto_visible)
1743+
no_auto_visible=args.no_auto_visible,
1744+
trash_image=args.rbd_trash_image_on_delete)
17401745
try:
17411746
ret = self.stub.namespace_add(req)
17421747
except Exception as ex:
@@ -1776,7 +1781,7 @@ def ns_del(self, args):
17761781

17771782
try:
17781783
ret = self.stub.namespace_delete(pb2.namespace_delete_req(
1779-
subsystem_nqn=args.subsystem, nsid=args.nsid))
1784+
subsystem_nqn=args.subsystem, nsid=args.nsid, are_you_sure=args.are_you_sure))
17801785
except Exception as ex:
17811786
ret = pb2.req_status(status=errno.EINVAL,
17821787
error_message=f"Failure deleting namespace:\n{ex}")
@@ -1925,15 +1930,15 @@ def ns_list(self, args):
19251930
namespaces_list = []
19261931
for ns in namespaces_info.namespaces:
19271932
if args.subsystem == GatewayUtils.ALL_SUBSYSTEMS:
1928-
if not ns.subsystem_nqn:
1933+
if not ns.ns_subsystem_nqn:
19291934
err_func(f"Got namespace with ID {ns.nsid} on an unknown subsystem")
19301935
subsys_nqn = "<n/a>"
19311936
else:
1932-
subsys_nqn = ns.subsystem_nqn
1937+
subsys_nqn = ns.ns_subsystem_nqn
19331938
else:
1934-
if ns.subsystem_nqn and ns.subsystem_nqn != args.subsystem:
1939+
if ns.ns_subsystem_nqn and ns.ns_subsystem_nqn != args.subsystem:
19351940
err_func(f"Got a namespace with ID {ns.nsid} in subsystem "
1936-
f"{ns.subsystem_nqn} which is different than the "
1941+
f"{ns.ns_subsystem_nqn} which is different than the "
19371942
f"requested one {args.subsystem}")
19381943
return errno.ENODEV
19391944
subsys_nqn = namespaces_info.subsystem_nqn
@@ -1960,10 +1965,11 @@ def ns_list(self, args):
19601965
else:
19611966
visibility = "Restrictive"
19621967

1968+
trash_msg = "\n(trash on deletion)" if ns.trash_image else ""
19631969
namespaces_list.append([subsys_nqn,
19641970
ns.nsid,
19651971
break_string(ns.bdev_name, "-", 2),
1966-
f"{ns.rbd_pool_name}/{ns.rbd_image_name}",
1972+
f"{ns.rbd_pool_name}/{ns.rbd_image_name}{trash_msg}",
19671973
self.format_size(ns.rbd_image_size),
19681974
self.format_size(ns.block_size),
19691975
break_string(ns.uuid, "-", 3),
@@ -2454,12 +2460,20 @@ def ns_change_visibility(self, args):
24542460
help="Make the namespace visible only to specific hosts",
24552461
action='store_true',
24562462
required=False),
2463+
argument("--rbd-trash-image-on-delete",
2464+
help="When deleting the namespace, trash associated RBD image. "
2465+
"Only applies to images created automatically by the gateway",
2466+
action='store_true',
2467+
required=False),
24572468
]
24582469
ns_del_args_list = ns_common_args + [
24592470
argument("--nsid",
24602471
help="Namespace ID",
24612472
type=int,
24622473
required=True),
2474+
argument("--are-you-sure",
2475+
help="If you choose to delete the associated RBD image, set this to \"yes\"",
2476+
required=False),
24632477
]
24642478
ns_resize_args_list = ns_common_args + [
24652479
argument("--nsid",

0 commit comments

Comments
 (0)