make loop image type support multiple partitions
authorJF Ding <jian-feng.ding@intel.com>
Mon, 10 Oct 2011 09:20:45 +0000 (17:20 +0800)
committerJF Ding <jian-feng.ding@intel.com>
Mon, 10 Oct 2011 09:20:45 +0000 (17:20 +0800)
which can be specified in kickstart, with the following feilds:
 mountpoint, fstype, size, label

Each particition will be generate as one separate image with the file
name as the one --label specified, else using kickstart name or
partition name.

mic/imager/loop.py
plugins/imager/loop_plugin.py

index 4eb8182..dc5736b 100644 (file)
@@ -33,6 +33,9 @@ class LoopImageCreator(BaseImageCreator):
         LoopImageCreator is a straightforward ImageCreator subclass; the system
         is installed into an ext3 filesystem on a sparse file which can be
         subsequently loopback-mounted.
+
+        When specifying multiple partitions in kickstart file, each partition
+        will be created as a separated loop image.
     """
 
     def __init__(self, creatoropts = None, pkgmgr = None):
@@ -52,11 +55,38 @@ class LoopImageCreator(BaseImageCreator):
         if self.ks:
             self.__fstype = kickstart.get_image_fstype(self.ks, "ext3")
             self.__fsopts = kickstart.get_image_fsopts(self.ks, "defaults,noatime")
+
+            allloops = []
+            for part in sorted(kickstart.get_partitions(self.ks),
+                               key = lambda p: p.mountpoint):
+                label = part.label
+
+                mp = part.mountpoint
+                if mp == '/':
+                    # the base image
+                    if not label:
+                        label =  self.name
+                else:
+                    mp = mp.rstrip('/')
+                    if not label:
+                        msger.warning('no "label" specified for loop img at %s, use the mountpoint as the name' % mp)
+                        label = mp.split('/')[-1]
+
+                imgname = misc.strip_end(label,'.img') + '.img'
+                allloops.append({
+                    'mountpoint': mp,
+                    'label': label,
+                    'name': imgname,
+                    'size': part.size or 4096L * 1024 * 1024,
+                    'fstype': part.fstype or 'ext4',
+                    'loop': None, # to be created in _mount_instroot
+                    })
+            self._instloops = allloops
+
         else:
             self.__fstype = None
             self.__fsopts = None
-
-        self._instloops = [] # list of dict of image_name:loop_device
+            self._instloops = []
 
         self.__imgdir = None
 
@@ -201,27 +231,34 @@ class LoopImageCreator(BaseImageCreator):
     def _mount_instroot(self, base_on = None):
         self._check_imgdir()
         self._base_on(base_on)
+        imgdir = os.path.dirname(self._image)
+
+        for loop in self._instloops:
+            fstype = loop['fstype']
+            mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/'))
+            size = loop['size'] * 1024L * 1024L
+            imgname = loop['name']
+
+            if fstype in ("ext2", "ext3", "ext4"):
+                MyDiskMount = fs.ExtDiskMount
+            elif fstype == "btrfs":
+                MyDiskMount = fs.BtrfsDiskMount
+            elif fstype in ("vfat", "msdos"):
+                MyDiskMount = fs.VfatDiskMount
+            else:
+                msger.error('Cannot support fstype: %s' % fstype)
 
-        if self.__fstype in ("ext2", "ext3", "ext4"):
-            MyDiskMount = fs.ExtDiskMount
-        elif self.__fstype == "btrfs":
-            MyDiskMount = fs.BtrfsDiskMount
-
-        self._instloops.append({
-                'name': self._img_name,
-                'loop': MyDiskMount(fs.SparseLoopbackDisk(self._image, self.__image_size),
-                                    self._instroot,
-                                    self.__fstype,
-                                    self.__blocksize,
-                                    self.fslabel)
-                })
+            loop['loop'] = MyDiskMount(fs.SparseLoopbackDisk(os.path.join(imgdir, imgname), size),
+                                       mp,
+                                       fstype,
+                                       self._blocksize,
+                                       loop['label'])
 
-        for item in self._instloops:
             try:
-                msger.verbose('Mounting image "%s" on "%s"' %(item['name'], item['loop'].mountdir))
-                fs.makedirs(item['loop'].mountdir)
-                item['loop'].mount()
-            except MountError, e:
+                msger.verbose('Mounting image "%s" on "%s"' %(imgname, mp))
+                fs.makedirs(mp)
+                loop['loop'].mount()
+            except errors.MountError, e:
                 raise
 
     def _unmount_instroot(self):
index 8dc7285..50c9c5f 100644 (file)
@@ -76,7 +76,7 @@ class LoopPlugin(ImagerPlugin):
             creator.configure(creatoropts["repomd"])
             creator.unmount()
             creator.package(creatoropts["outdir"])
-            outimage = creator.outimage
+
             if creatoropts['release'] is not None:
                 creator.release_output(ksconf, creatoropts['outdir'], creatoropts['name'], creatoropts['release'])
             creator.print_outimage_info()