pvl/backup/mount.py
changeset 5 23371d26fdd0
child 10 724a90bd77b5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pvl/backup/mount.py	Tue Feb 14 18:57:21 2012 +0200
@@ -0,0 +1,106 @@
+"""
+    Mount filesystems.
+"""
+
+from pvl.backup.invoke import command
+
+import contextlib
+import os.path
+import logging
+
+log = logging.getLogger('pvl.backup.mount')
+
+
+class MountError (Exception) :
+    pass
+
+class Mount (object) :
+    """
+        Trivial filesystem mounting
+    """
+
+    MOUNT   = '/bin/mount'
+    UMOUNT  = '/bin/umount'
+
+
+    def __init__ (self, dev, mnt, readonly=False) :
+        """
+            dev         - device path
+            mnt         - mount path
+            readonly    - mount readonly
+        """
+
+        self.dev = dev
+        self.mnt = mnt
+        self.readonly = readonly
+
+    @property
+    def path (self) :
+        return self.mnt
+
+    def options (self) :
+        """
+            Mount options as a comma-separated string.
+        """
+
+        options = [
+                ('ro' if self.readonly else None),
+        ]
+
+        return ','.join(option for option in options if option)
+
+    def open (self) :
+        """
+            Mount
+        """
+
+        # check
+        if not os.path.isdir(self.mnt) :
+            raise MountError("Mountpoint is not a directory: {mnt}".format(mnt=self.mnt))
+
+        if os.path.ismount(self.mnt) :
+            raise MountError("Mountpoint is already mounted: {mnt}".format(mnt=self.mnt))
+
+        if not os.path.exists(self.dev) :
+            raise MountError("Device does not exist: {dev}".format(dev=self.dev))
+
+        # mount
+        command(self.MOUNT, self.dev, self.mnt, options=self.options())
+
+    def close (self) :
+        """
+            Un-mount
+        """
+
+        # check
+        if not os.path.ismount(self.mnt):
+            raise MountError("Mountpoint is not mounted: {mnt}".format(mnt=self.mnt))
+
+        # umount
+        command(self.UMOUNT, self.mnt)
+
+@contextlib.contextmanager
+def mount (dev, mnt, **kwargs) :
+    """
+        Use a temporary mount:
+
+        with mount('/dev/...', '/mnt', readonly=True) as mount:
+            ...
+    """
+
+    mount = Mount(dev, mnt, **kwargs)
+
+    # open
+    log.debug("open: %s", mount)
+    mount.open()
+
+    try :
+        log.debug("got: %s", mount)
+        yield mount
+
+    finally:
+        # cleanup
+        log.debug("cleanup: %s", mount)
+        mount.close()
+
+