diff options
Diffstat (limited to 'tools/nbdfuse.py')
-rw-r--r-- | tools/nbdfuse.py | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/tools/nbdfuse.py b/tools/nbdfuse.py new file mode 100644 index 0000000..b7a4997 --- /dev/null +++ b/tools/nbdfuse.py @@ -0,0 +1,63 @@ +import logging +import os +import tempfile + +from subprocess import Popen, PIPE +from time import sleep +from . import log, rmdir + +__all__ = ["mount"] + +L = logging.getLogger(__name__) + + +@log +def mount(path): + """Mount a VMware Virtual Machine Disk (VMDK) file as a RAW image file in + the local filesystem with read-only support using `qemu-nbd` + `nbdfuse`. + + See also: + https://manpages.debian.org/bullseye/qemu-utils/qemu-nbd.8.en.html + https://manpages.debian.org/bullseye/libnbd-bin/nbdfuse.1.en.html + + Make sure you have the following packages installed: + $ sudo apt install qemu-utils nbdfuse + + Args: + path (str): Path to the VMDK file. + + Returns: + Path to the directory containing a single virtual file named `nbd`. + """ + mp = tempfile.mkdtemp() + cmd = [ + "nbdfuse", + "--readonly", + mp, + "--socket-activation", + "qemu-nbd", + "--read-only", + "--format=vmdk", + path + ] + + try: + p = Popen(cmd, stdout=PIPE, stderr=PIPE, text=True) + except Exception as e: + L.error("failed to execute command %s: %r", cmd, e) + rmdir(mp) + return "" + + while p.poll() is None: + if os.path.ismount(mp): + return mp + sleep(1) + + ret = p.poll() + out, err = p.communicate() + out, err = out.strip(), err.strip() + L.error("retcode: %d, stdout: %s, stderr: %s", ret, out, err) + + rmdir(mp) + + return "" |