diff options
author | Andy Piper <andy.piper@arcticwolf.com> | 2021-11-22 10:17:44 -0500 |
---|---|---|
committer | Andy Piper <andy.piper@arcticwolf.com> | 2021-11-22 10:26:00 -0500 |
commit | 7c373bde01651624cfc6cf2bd1a62f0841d7006c (patch) | |
tree | d75bdaa32767ca2e56c8f113b57a81bcc53784bd | |
parent | 30b787fc5ff6bcd4d5f1fa6ceb2990fedce48fc7 (diff) | |
download | vmdb2-7c373bde01651624cfc6cf2bd1a62f0841d7006c.tar.gz |
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 <part>`, and frees the
loopback device using `losetup -d <device>`
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.
-rw-r--r-- | vmdb/plugins/kpartx_plugin.py | 17 | ||||
-rw-r--r-- | 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 <http://www.gnu.org/licenses/>. # # =*= 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<loop>.*)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 |