summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Piper <andy.piper@arcticwolf.com>2021-11-22 10:17:44 -0500
committerAndy Piper <andy.piper@arcticwolf.com>2021-11-22 10:26:00 -0500
commit7c373bde01651624cfc6cf2bd1a62f0841d7006c (patch)
treed75bdaa32767ca2e56c8f113b57a81bcc53784bd
parent30b787fc5ff6bcd4d5f1fa6ceb2990fedce48fc7 (diff)
downloadvmdb2-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.py17
-rw-r--r--vmdb/tags.py2
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