From 7c373bde01651624cfc6cf2bd1a62f0841d7006c Mon Sep 17 00:00:00 2001 From: Andy Piper Date: Mon, 22 Nov 2021 10:17:44 -0500 Subject: Clean up mapped partitions in docker on macOS Docker containers running in Docker Desktop for Mac appear to have a version of `kpartx` that doesn't properly clean up mapped partitions upon execution of `kpartx -dsv`. To work around this behaviour, the kpartx_plugin now unmaps mapped partitions as required using `dmsetup remove `, and frees the loopback device using `losetup -d ` This change requires the list of partition mounpoints to be an ordered list in order to be able to unmap mapped partitions in the correct order, so `Tags.get_tags()` has been updated to return the ordered list `self._tagnames` instead of `self._tags.keys()` which (for Python versions before 3.7) returns an unorderd list. --- vmdb/plugins/kpartx_plugin.py | 17 ++++++++++++++++- vmdb/tags.py | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/vmdb/plugins/kpartx_plugin.py b/vmdb/plugins/kpartx_plugin.py index 6303552..7c31cfc 100644 --- a/vmdb/plugins/kpartx_plugin.py +++ b/vmdb/plugins/kpartx_plugin.py @@ -14,7 +14,8 @@ # along with this program. If not, see . # # =*= License: GPL-3+ =*= - +import os +import re import vmdb @@ -47,3 +48,17 @@ class KpartxStepRunner(vmdb.StepRunnerInterface): def teardown(self, values, settings, state): device = values["kpartx"] vmdb.runcmd(["kpartx", "-dsv", device]) + # docker containers on macOS don't honor the kpartx cleanup command, so + # we have to do the clean up ourselves... :-/ + loop_devs = set() + for tag in state.tags.get_tags(): + dev = state.tags.get_dev(tag) + m = re.match(r"^/dev/mapper/(?P.*)p\d+$", dev) + if m is not None: + if os.path.exists(dev): + vmdb.runcmd(["dmsetup", "-v", "remove", dev]) + loop = m.group("loop") + loop_devs.add("/dev/{}".format(loop)) + + for loop_dev in loop_devs: + vmdb.runcmd(["losetup", "-d", loop_dev]) diff --git a/vmdb/tags.py b/vmdb/tags.py index 818193f..0e59f1a 100644 --- a/vmdb/tags.py +++ b/vmdb/tags.py @@ -25,7 +25,7 @@ class Tags: return repr({"tags": self._tags, "tagnames": self._tagnames}) def get_tags(self): - return list(self._tags.keys()) + return self._tagnames def has_tag(self, tag): return tag in self._tags -- cgit v1.2.1