<font size="2" face="'courier new', monospace">Patch 1a of 2 substitute patches to replace an earlier patch with new</font><div><font size="2" face="'courier new', monospace">features:</font></div><div><font face="'courier new', monospace"><br>

</font></div><div><font size="2" face="'courier new', monospace"><div>commit 7389913c708d3f19ca029cf3f150bbfb08a768d3</div><div>Author: Frederick Grose <<a href="mailto:fgrose@sugarlabs.org">fgrose@sugarlabs.org</a>></div>

<div>Date:   Sat Sep 17 17:05:17 2011 -0400</div><div><br></div><div>    Enable mount options, particularly 'read-only', for greater safety.</div><div>    </div><div>    Provide parameters for mounting options, and code to recognize and</div>

<div>    implement various 'read-only' flag possibilities.</div><div><br></div><div>diff --git a/imgcreate/fs.py b/imgcreate/fs.py</div><div>index 69fb5f1..e71032e 100644</div><div>--- a/imgcreate/fs.py</div><div>

+++ b/imgcreate/fs.py</div><div>@@ -122,9 +122,10 @@ def e2fsck(fs):</div><div> </div><div> class BindChrootMount:</div><div>     """Represents a bind mount of a directory into a chroot."""</div>

<div>-    def __init__(self, src, chroot, dest = None):</div><div>+    def __init__(self, src, chroot, dest=None, ops=None):</div><div>         self.src = src</div><div>         self.root = chroot</div><div>+        self.ops = ops</div>

<div> </div><div>         if not dest:</div><div>             dest = src</div><div>@@ -132,17 +133,35 @@ class BindChrootMount:</div><div> </div><div>         self.mounted = False</div><div> </div><div>-    def mount(self):</div>

<div>+    def mount(self, ops=None):</div><div>         if self.mounted:</div><div>             return</div><div> </div><div>         makedirs(self.dest)</div><div>-        rc = call(["/bin/mount", "--bind", self.src, self.dest])</div>

<div>+        args = ['/bin/mount', '--bind', self.src, self.dest]</div><div>+        rc = call(args)</div><div>         if rc != 0:</div><div>             raise MountError("Bind-mounting '%s' to '%s' failed" %</div>

<div>                              (self.src, self.dest))</div><div>+        if ops is None:</div><div>+            ops = self.ops</div><div>+        if ops in (['-o', 'remount,ro'], 'remount,ro,bind', 'remount,ro',</div>

<div>+                   ['-o', 'ro'], ['ro'], ['-r'], 'ro', '-r'):</div><div>+            self.remount('ro')</div><div>+</div><div>         self.mounted = True</div>

<div> </div><div>+    def remount(self, ops):</div><div>+        if not self.mounted:</div><div>+            return</div><div>+</div><div>+        remount_ops = ''.join(('remount,', ops))</div><div>+        args = ['/bin/mount', '-o', remount_ops, self.dest]</div>

<div>+        rc = call(args)</div><div>+        if rc != 0:</div><div>+            raise MountError("%s of '%s' to '%s' failed." %</div><div>+                             (remount_ops, self.src, self.dest))</div>

<div>+</div><div>     def unmount(self):</div><div>         if not self.mounted:</div><div>             return</div><div>@@ -161,9 +180,11 @@ class BindChrootMount:</div><div> </div><div> class LoopbackMount:</div><div>     """LoopbackMount  compatibility layer for old API"""</div>

<div>-    def __init__(self, lofile, mountdir, fstype = None):</div><div>-        self.diskmount = DiskMount(LoopbackDisk(lofile,size = 0),mountdir,fstype,rmmountdir = True)</div><div>+    def __init__(self, lofile, mountdir, fstype=None, ops=None):</div>

<div>+        self.diskmount = DiskMount(LoopbackDisk(lofile, size=0), mountdir,</div><div>+                                   fstype, rmmountdir=True, ops=None)</div><div>         self.losetup = False</div><div>+        self.ops = ops</div>

<div>         </div><div>     def cleanup(self):</div><div>         self.diskmount.cleanup()</div><div>@@ -177,7 +198,7 @@ class LoopbackMount:</div><div>             self.losetup = False</div><div>             self.loopdev = None</div>

<div> </div><div>-    def loopsetup(self):</div><div>+    def loopsetup(self, ops=None):</div><div>         if self.losetup:</div><div>             return</div><div> </div><div>@@ -191,15 +212,22 @@ class LoopbackMount:</div>

<div> </div><div>         self.loopdev = losetupOutput.split()[0]</div><div> </div><div>-        rc = call(["/sbin/losetup", self.loopdev, self.lofile])</div><div>+        args = ['/sbin/losetup', self.loopdev, self.lofile]</div>

<div>+        if ops is None:</div><div>+            ops = self.ops</div><div>+        if ops in (['-o', 'ro'], ['ro'], ['-r'], 'ro', '-r'):</div><div>+            ops = ['-r']</div>

<div>+            # This is the only additional option supported, so far.</div><div>+            args += ops</div><div>+        rc = call(args)</div><div>         if rc != 0:</div><div>             raise MountError("Failed to allocate loop device for '%s'" %</div>

<div>                              self.lofile)</div><div> </div><div>         self.losetup = True</div><div> </div><div>-    def mount(self):</div><div>-        self.diskmount.mount()</div><div>+    def mount(self, ops=None):</div>

<div>+        self.diskmount.mount(ops)</div><div> </div><div> class SparseLoopbackMount(LoopbackMount):</div><div>     """SparseLoopbackMount  compatibility layer for old API"""</div><div>@@ -290,9 +318,10 @@ class RawDisk(Disk):</div>

<div> </div><div> class LoopbackDisk(Disk):</div><div>     """A Disk backed by a file via the loop module."""</div><div>-    def __init__(self, lofile, size):</div><div>+    def __init__(self, lofile, size, ops=None):</div>

<div>         Disk.__init__(self, size)</div><div>         self.lofile = lofile</div><div>+        self.ops = ops</div><div> </div><div>     def fixed(self):</div><div>         return False</div><div>@@ -300,7 +329,7 @@ class LoopbackDisk(Disk):</div>

<div>     def exists(self):</div><div>         return os.path.exists(self.lofile)</div><div> </div><div>-    def create(self):</div><div>+    def create(self, ops=None):</div><div>         if self.device is not None:</div>

<div>             return</div><div> </div><div>@@ -313,9 +342,16 @@ class LoopbackDisk(Disk):</div><div>                              self.lofile)</div><div> </div><div>         device = losetupOutput.split()[0]</div><div>

+        args = ['/sbin/losetup', device, self.lofile]</div><div>+        if ops is None:</div><div>+            ops = self.ops</div><div>+        if ops in (['-o', 'ro'], ['ro'], ['-r'], 'ro', '-r'):</div>

<div>+            ops = ['-r']</div><div>+            # This is the only additional option supported, so far.</div><div>+            args += ops</div><div> </div><div>         <a href="http://logging.info">logging.info</a>("Losetup add %s mapping to %s"  % (device, self.lofile))</div>

<div>-        rc = call(["/sbin/losetup", device, self.lofile])</div><div>+        rc = call(args)</div><div>         if rc != 0:</div><div>             raise MountError("Failed to allocate loop device for '%s'" %</div>

<div>                              self.lofile)</div><div>@@ -329,11 +365,10 @@ class LoopbackDisk(Disk):</div><div>         self.device = None</div><div> </div><div> </div><div>-</div><div> class SparseLoopbackDisk(LoopbackDisk):</div>

<div>     """A Disk backed by a sparse file via the loop module."""</div><div>-    def __init__(self, lofile, size):</div><div>-        LoopbackDisk.__init__(self, lofile, size)</div><div>+    def __init__(self, lofile, size, ops=None):</div>

<div>+        LoopbackDisk.__init__(self, lofile, size, ops=None)</div><div> </div><div>     def expand(self, create = False, size = None):</div><div>         flags = os.O_WRONLY</div><div>@@ -362,9 +397,9 @@ class SparseLoopbackDisk(LoopbackDisk):</div>

<div>         os.ftruncate(fd, size)</div><div>         os.close(fd)</div><div> </div><div>-    def create(self):</div><div>+    def create(self, ops=None):</div><div>         self.expand(create = True)</div><div>-        LoopbackDisk.create(self)</div>

<div>+        LoopbackDisk.create(self, ops=None)</div><div> </div><div> class Mount:</div><div>     """A generic base class to deal with mounting things."""</div><div>@@ -382,15 +417,17 @@ class Mount:</div>

<div> </div><div> class DiskMount(Mount):</div><div>     """A Mount object that handles mounting of a Disk."""</div><div>-    def __init__(self, disk, mountdir, fstype = None, rmmountdir = True):</div>

<div>+    def __init__(self, disk, mountdir, fstype=None, rmmountdir=True, ops=None):</div><div>         Mount.__init__(self, mountdir)</div><div> </div><div>         self.disk = disk</div><div>         self.fstype = fstype</div>

<div>+        self.ops = ops</div><div>         self.rmmountdir = rmmountdir</div><div> </div><div>         self.mounted = False</div><div>         self.rmdir   = False</div><div>+        self.created = False</div><div> </div>

<div>     def cleanup(self):</div><div>         Mount.cleanup(self)</div><div>@@ -420,12 +457,12 @@ class DiskMount(Mount):</div><div>                 pass</div><div>             self.rmdir = False</div><div> </div><div>
-</div>
<div>     def __create(self):</div><div>-        self.disk.create()</div><div>-</div><div>+        if not self.created:</div><div>+            self.disk.create()</div><div>+            self.created = True</div><div> </div>

<div>-    def mount(self):</div><div>+    def mount(self, ops=None):</div><div>         if self.mounted:</div><div>             return</div><div> </div><div>@@ -440,6 +477,10 @@ class DiskMount(Mount):</div><div>         args = [ "/bin/mount", self.disk.device, self.mountdir ]</div>

<div>         if self.fstype:</div><div>             args.extend(["-t", self.fstype])</div><div>+        if ops is None:</div><div>+            ops = self.ops</div><div>+        if ops is not None:</div><div>+            args.extend(['-o', ops])</div>

<div> </div><div>         rc = call(args)</div><div>         if rc != 0:</div><div>@@ -448,6 +489,17 @@ class DiskMount(Mount):</div><div> </div><div>         self.mounted = True</div><div> </div><div>+    def remount(self, ops):</div>

<div>+        if not self.mounted:</div><div>+            return</div><div>+</div><div>+        remount_ops = ''.join(('remount,', ops))</div><div>+        args = ['/bin/mount', '-o', remount_ops, self.mountdir]</div>

<div>+        rc = call(args)</div><div>+        if rc != 0:</div><div>+            raise MountError("%s of '%s' to '%s' failed." %</div><div>+                             (remount_ops, self.disk.device, self.mountdir))</div>

<div>+</div><div> class ExtDiskMount(DiskMount):</div><div>     """A DiskMount object that is able to format/resize ext[23] filesystems."""</div><div>     def __init__(self, disk, mountdir, fstype, blocksize, fslabel,</div>

<div>@@ -456,6 +508,7 @@ class ExtDiskMount(DiskMount):</div><div>         self.blocksize = blocksize</div><div>         self.fslabel = "_" + fslabel</div><div>         self.tmpdir = tmpdir</div><div>+        self.created = False</div>

<div> </div><div>     def __format_filesystem(self):</div><div>         <a href="http://logging.info">logging.info</a>("Formating %s filesystem on %s" % (self.fstype, self.disk.device))</div><div>@@ -487,6 +540,8 @@ class ExtDiskMount(DiskMount):</div>

<div>         return size</div><div> </div><div>     def __create(self):</div><div>+        if self.created:</div><div>+            return</div><div>         resize = False</div><div>         if not self.disk.fixed() and self.disk.exists():</div>

<div>             resize = True</div><div>@@ -498,6 +553,8 @@ class ExtDiskMount(DiskMount):</div><div>         else:</div><div>             self.__format_filesystem()</div><div> </div><div>+        self.created = True</div>

<div>+</div><div>     def mount(self):</div><div>         self.__create()</div><div>         DiskMount.mount(self)</div><div>@@ -535,10 +592,12 @@ class ExtDiskMount(DiskMount):</div><div>         self.__resize_filesystem(size)</div>

<div>         return minsize</div><div> </div><div>+</div><div> class DeviceMapperSnapshot(object):</div><div>-    def __init__(self, imgloop, cowloop):</div><div>+    def __init__(self, imgloop, cowloop, ops=None):</div>

<div>         self.imgloop = imgloop</div><div>         self.cowloop = cowloop</div><div>+        self.ops = ops</div><div> </div><div>         self.__created = False</div><div>         self.__name = None</div><div>@@ -546,15 +605,16 @@ class DeviceMapperSnapshot(object):</div>

<div>     def get_path(self):</div><div>         if self.__name is None:</div><div>             return None</div><div>+        return self.device</div><div>         return os.path.join("/dev/mapper", self.__name)</div>

<div>     path = property(get_path)</div><div> </div><div>-    def create(self):</div><div>+    def create(self, ops=None):</div><div>         if self.__created:</div><div>             return</div><div> </div><div>-        self.imgloop.create()</div>

<div>-        self.cowloop.create()</div><div>+        self.imgloop.create(self.ops)</div><div>+        self.cowloop.create(self.ops)</div><div> </div><div>         self.__name = "imgcreate-%d-%d" % (os.getpid(),</div>

<div>                                            random.randint(0, 2**16))</div><div>@@ -567,13 +627,22 @@ class DeviceMapperSnapshot(object):</div><div> </div><div>         args = ["/sbin/dmsetup", "create", self.__name,</div>

<div>                 "--uuid", "LIVECD-%s" % self.__name, "--table", table]</div><div>+        if ops is None:</div><div>+            ops = self.ops</div><div>+        if ops in (['-o', 'ro'], ['ro'], ['-r'], 'ro', '-r',</div>

<div>+                   ['--readonly'], '--readonly'):</div><div>+            ops = ['--readonly']</div><div>+            # This is the only additional option supported, so far.</div><div>+            args += ops</div>

<div>         if call(args) != 0:</div><div>+            time.sleep(1)</div><div>             self.cowloop.cleanup()</div><div>             self.imgloop.cleanup()</div><div>             raise SnapshotError("Could not create snapshot device using: " +</div>

<div>                                 string.join(args, " "))</div><div> </div><div>         self.__created = True</div><div>+        self.device = os.path.join('/dev/mapper', self.__name)</div><div> </div>

<div>     def remove(self, ignore_errors = False):</div><div>         if not self.__created:</div></font><div><br></div><div><br></div><div><br></div><br><div class="gmail_quote">On Thu, Apr 14, 2011 at 12:02 PM, Frederick Grose <span dir="ltr"><<a href="mailto:fgrose@gmail.com">fgrose@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><font face="courier new,monospace">[Patch 1/5]</font><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">Author: Frederick Grose <<a href="mailto:fgrose@sugarlabs.org" target="_blank">fgrose@sugarlabs.org</a>></span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">Date:   Thu Apr 14 09:29:14 2011 -0400</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    Support Live image mounting.</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">    </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">    Provide DiskMount with mount options, DeviceMapperSnapshot with a</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">    device attribute, and a new LiveImageMount class.</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">diff --git a/imgcreate/fs.py b/imgcreate/fs.py</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">index d5307a2..0871182 100644</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">--- a/imgcreate/fs.py</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+++ b/imgcreate/fs.py</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">@@ -324,7 +324,6 @@ class LoopbackDisk(Disk):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">         self.device = None</span><br style="font-family:courier new,monospace"> <br style="font-family:courier new,monospace"> <br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">-</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> class SparseLoopbackDisk(LoopbackDisk):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">     """A Disk backed by a sparse file via the loop module."""</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">     def __init__(self, lofile, size):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">@@ -377,11 +376,12 @@ class Mount:</span><br style="font-family:courier new,monospace"> <br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> class DiskMount(Mount):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">     """A Mount object that handles mounting of a Disk."""</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">-    def __init__(self, disk, mountdir, fstype = None, rmmountdir = True):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+    def __init__(self, disk, mountdir, fstype=None, rmmountdir=True, ops=None):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         Mount.__init__(self, mountdir)</span><br style="font-family:courier new,monospace">


 <br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         self.disk = disk</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         self.fstype = fstype</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.ops = ops</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         self.rmmountdir = rmmountdir</span><br style="font-family:courier new,monospace">


 <br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         self.mounted = False</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">@@ -435,6 +435,8 @@ class DiskMount(Mount):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">         args = [ "/bin/mount", self.disk.device, self.mountdir ]</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         if self.fstype:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">             args.extend(["-t", self.fstype])</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        if self.ops:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            args.extend(['-o', self.ops])</span><br style="font-family:courier new,monospace"> <br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         rc = call(args)</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">         if rc != 0:</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">@@ -530,6 +532,7 @@ class ExtDiskMount(DiskMount):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">         self.__resize_filesystem(size)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         return minsize</span><br style="font-family:courier new,monospace">


 <br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> class DeviceMapperSnapshot(object):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">     def __init__(self, imgloop, cowloop):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         self.imgloop = imgloop</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">@@ -541,6 +544,7 @@ class DeviceMapperSnapshot(object):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">     def get_path(self):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">         if self.__name is None:</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">             return None</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        return self.device</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         return os.path.join("/dev/mapper", self.__name)</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">     path = property(get_path)</span><br style="font-family:courier new,monospace"> <br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">@@ -569,6 +573,7 @@ class DeviceMapperSnapshot(object):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">                                 string.join(args, " "))</span><br style="font-family:courier new,monospace"> <br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         self.__created = True</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.device = os.path.join('/dev/mapper', self.__name)</span><br style="font-family:courier new,monospace"> <br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">     def remove(self, ignore_errors = False):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         if not self.__created:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">@@ -610,6 +615,89 @@ class DeviceMapperSnapshot(object):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">         except ValueError:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">             raise SnapshotError("Failed to parse dmsetup status: " + out)</span><br style="font-family:courier new,monospace"> <br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+class LiveImageMount(object):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+    """A class for mounting a LiveOS image installed with an active overlay."""</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+    def __init__(self, disk, mountdir, overlay, tmpdir='/tmp'):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.disk = disk</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.mountdir = mountdir</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.overlay = overlay</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.tmpdir = tmpdir</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.__created = False</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.squashmnt = None</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.homemnt = None</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.mntlive = None</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+    def __create(self):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        if self.__created:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            return</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.liveosdevmnt = DiskMount(self.disk,</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+                                   os.path.join(self.tmpdir, 'device'))</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.liveosdevmnt.mount()</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        liveosdir = os.path.join(self.liveosdevmnt.mountdir, 'LiveOS')</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        sqfs_img = os.path.join(liveosdir, 'squashfs.img')</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        if os.path.exists(sqfs_img):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            self.squashloop = LoopbackDisk(sqfs_img, None)</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            self.squashmnt = DiskMount(self.squashloop,</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+                                       os.path.join(self.tmpdir, 'squash'))</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            self.squashmnt.mount()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            rootfs_img = os.path.join(self.squashmnt.mountdir,</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+                                      'LiveOS', 'ext3fs.img')</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        else:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            rootfs_img = os.path.join(liveosdir, 'ext3fs.img')</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            if not os.path.exists(rootfs_img):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+                raise SnapshotError("Failed to find a LiveOS root image.")</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.imgloop = LoopbackDisk(rootfs_img, None)</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.overlay = os.path.join(liveosdir, self.overlay)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.cowloop = LoopbackDisk(self.overlay, None)</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        home_img = os.path.join(liveosdir, 'home.img')</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.dm_liveimage = DeviceMapperSnapshot(self.imgloop, self.cowloop)</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.dm_livemount = DiskMount(self.dm_liveimage, self.mountdir)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        if os.path.exists(home_img):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            homedir = os.path.join(self.mountdir, 'home')</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            self.homemnt = LoopbackMount(home_img, homedir)</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.__created = True</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+    def mount(self):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        try:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            self.__create()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            if not self.liveosdevmnt.mounted:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+                self.liveosdevmnt.mount()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            if not self.squashmnt.mounted:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+                self.squashmnt.mount()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            self.dm_livemount.mount()</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            if self.homemnt:</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+                self.homemnt.mount()</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            mntlivedir = os.path.join(self.mountdir, 'mnt', 'live')</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            if not os.path.exists(mntlivedir):</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+                os.makedirs(mntlivedir)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            self.mntlive = BindChrootMount(self.liveosdevmnt.mountdir,</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+                                           '', mntlivedir)</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            self.mntlive.mount()</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        except MountError, e:</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            raise SnapshotError("Failed to mount %s : %s" % (self.disk, e))</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            self.cleanup()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+    def unmount(self):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        if self.mntlive:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            self.mntlive.unmount()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        if self.homemnt:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            self.homemnt.unmount()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.dm_livemount.unmount()</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.liveosdevmnt.unmount()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+    def cleanup(self):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.unmount()</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        if self.homemnt:</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+            self.homemnt.cleanup()</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.dm_liveimage.remove()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        if self.squashmnt:</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+            self.squashmnt.cleanup()</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+        self.liveosdevmnt.cleanup()</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+        self.__created = False</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">+</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> def create_image_minimizer(path, image, compress_type, target_size = None,</span><br style="font-family:courier new,monospace">


<span style="font-family:courier new,monospace">                            tmpdir = "/tmp"):</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">     """</span>
</blockquote></div><br></div>