[OE-core] [PATCH 04/18] wic: moved content of direct.py to direct_plugin

Ed Bartosh ed.bartosh at linux.intel.com
Wed Feb 1 13:48:11 UTC 2017


This move simplifies directory structure and makes
further refactoring easier. The code from direct.py was used
only in direct_plugin, so it's safe to move it there.

[YOCTO #10619]

Signed-off-by: Ed Bartosh <ed.bartosh at linux.intel.com>
---
 scripts/lib/wic/imager/__init__.py              |   0
 scripts/lib/wic/imager/direct.py                | 402 ------------------------
 scripts/lib/wic/plugins/imager/direct_plugin.py | 396 ++++++++++++++++++++++-
 3 files changed, 380 insertions(+), 418 deletions(-)
 delete mode 100644 scripts/lib/wic/imager/__init__.py
 delete mode 100644 scripts/lib/wic/imager/direct.py

diff --git a/scripts/lib/wic/imager/__init__.py b/scripts/lib/wic/imager/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/scripts/lib/wic/imager/direct.py b/scripts/lib/wic/imager/direct.py
deleted file mode 100644
index ff06b50..0000000
--- a/scripts/lib/wic/imager/direct.py
+++ /dev/null
@@ -1,402 +0,0 @@
-# ex:ts=4:sw=4:sts=4:et
-# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-#
-# Copyright (c) 2013, Intel Corporation.
-# All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# DESCRIPTION
-# This implements the 'direct' image creator class for 'wic'
-#
-# AUTHORS
-# Tom Zanussi <tom.zanussi (at] linux.intel.com>
-#
-
-import os
-import shutil
-import uuid
-import tempfile
-
-from wic import msger
-from wic.utils.oe.misc import get_bitbake_var
-from wic.utils.partitionedfs import Image
-from wic.utils.errors import CreatorError, ImageError
-from wic.plugin import pluginmgr
-from wic.utils.oe.misc import exec_cmd, exec_native_cmd
-
-disk_methods = {
-    "do_install_disk":None,
-}
-
-class DiskImage():
-    """
-    A Disk backed by a file.
-    """
-    def __init__(self, device, size):
-        self.size = size
-        self.device = device
-        self.created = False
-
-    def exists(self):
-        return os.path.exists(self.device)
-
-    def create(self):
-        if self.created:
-            return
-        # create sparse disk image
-        with open(self.device, 'w') as sparse:
-            os.ftruncate(sparse.fileno(), self.size)
-
-        self.created = True
-
-class DirectImageCreator:
-    """
-    Installs a system into a file containing a partitioned disk image.
-
-    DirectImageCreator is an advanced ImageCreator subclass; an image
-    file is formatted with a partition table, each partition created
-    from a rootfs or other OpenEmbedded build artifact and dd'ed into
-    the virtual disk. The disk image can subsequently be dd'ed onto
-    media and used on actual hardware.
-    """
-
-    def __init__(self, image_name, ksobj, oe_builddir, image_output_dir,
-                 rootfs_dir, bootimg_dir, kernel_dir, native_sysroot,
-                 compressor, bmap=False):
-        """
-        Initialize a DirectImageCreator instance.
-
-        This method takes the same arguments as ImageCreator.__init__()
-        """
-        self.name = image_name
-        self.outdir = image_output_dir
-        self.workdir = tempfile.mktemp(prefix='wic')
-        self.ks = ksobj
-
-        self.__image = None
-        self.__disks = {}
-        self.__disk_format = "direct"
-        self._disk_names = []
-        self.ptable_format = self.ks.bootloader.ptable
-
-        self.oe_builddir = oe_builddir
-        self.rootfs_dir = rootfs_dir
-        self.bootimg_dir = bootimg_dir
-        self.kernel_dir = kernel_dir
-        self.native_sysroot = native_sysroot
-        self.compressor = compressor
-        self.bmap = bmap
-
-    def _get_part_num(self, num, parts):
-        """calculate the real partition number, accounting for partitions not
-        in the partition table and logical partitions
-        """
-        realnum = 0
-        for pnum, part in enumerate(parts, 1):
-            if not part.no_table:
-                realnum += 1
-            if pnum == num:
-                if  part.no_table:
-                    return 0
-                if self.ptable_format == 'msdos' and realnum > 3:
-                    # account for logical partition numbering, ex. sda5..
-                    return realnum + 1
-                return realnum
-
-    def _write_fstab(self, image_rootfs):
-        """overriden to generate fstab (temporarily) in rootfs. This is called
-        from _create, make sure it doesn't get called from
-        BaseImage.create()
-        """
-        if not image_rootfs:
-            return
-
-        fstab_path = image_rootfs + "/etc/fstab"
-        if not os.path.isfile(fstab_path):
-            return
-
-        with open(fstab_path) as fstab:
-            fstab_lines = fstab.readlines()
-
-        if self._update_fstab(fstab_lines, self._get_parts()):
-            shutil.copyfile(fstab_path, fstab_path + ".orig")
-
-            with open(fstab_path, "w") as fstab:
-                fstab.writelines(fstab_lines)
-
-            return fstab_path
-
-    def _update_fstab(self, fstab_lines, parts):
-        """Assume partition order same as in wks"""
-        updated = False
-        for num, part in enumerate(parts, 1):
-            pnum = self._get_part_num(num, parts)
-            if not pnum or not part.mountpoint \
-               or part.mountpoint in ("/", "/boot"):
-                continue
-
-            # mmc device partitions are named mmcblk0p1, mmcblk0p2..
-            prefix = 'p' if  part.disk.startswith('mmcblk') else ''
-            device_name = "/dev/%s%s%d" % (part.disk, prefix, pnum)
-
-            opts = part.fsopts if part.fsopts else "defaults"
-            line = "\t".join([device_name, part.mountpoint, part.fstype,
-                              opts, "0", "0"]) + "\n"
-
-            fstab_lines.append(line)
-            updated = True
-
-        return updated
-
-    def set_bootimg_dir(self, bootimg_dir):
-        """
-        Accessor for bootimg_dir, the actual location used for the source
-        of the bootimg.  Should be set by source plugins (only if they
-        change the default bootimg source) so the correct info gets
-        displayed for print_outimage_info().
-        """
-        self.bootimg_dir = bootimg_dir
-
-    def _get_parts(self):
-        if not self.ks:
-            raise CreatorError("Failed to get partition info, "
-                               "please check your kickstart setting.")
-
-        # Set a default partition if no partition is given out
-        if not self.ks.partitions:
-            partstr = "part / --size 1900 --ondisk sda --fstype=ext3"
-            args = partstr.split()
-            part = self.ks.parse(args[1:])
-            if part not in self.ks.partitions:
-                self.ks.partitions.append(part)
-
-        # partitions list from kickstart file
-        return self.ks.partitions
-
-    def _full_name(self, name, extention):
-        """ Construct full file name for a file we generate. """
-        return "%s-%s.%s" % (self.name, name, extention)
-
-    def _full_path(self, path, name, extention):
-        """ Construct full file path to a file we generate. """
-        return os.path.join(path, self._full_name(name, extention))
-
-    def get_default_source_plugin(self):
-        """
-        The default source plugin i.e. the plugin that's consulted for
-        overall image generation tasks outside of any particular
-        partition.  For convenience, we just hang it off the
-        bootloader handler since it's the one non-partition object in
-        any setup.  By default the default plugin is set to the same
-        plugin as the /boot partition; since we hang it off the
-        bootloader object, the default can be explicitly set using the
-        --source bootloader param.
-        """
-        return self.ks.bootloader.source
-
-    #
-    # Actual implemention
-    #
-    def create(self):
-        """
-        For 'wic', we already have our build artifacts - we just create
-        filesystems from the artifacts directly and combine them into
-        a partitioned image.
-        """
-        parts = self._get_parts()
-
-        self._image = Image(self.native_sysroot)
-
-        disk_ids = {}
-        for num, part in enumerate(parts, 1):
-            # as a convenience, set source to the boot partition source
-            # instead of forcing it to be set via bootloader --source
-            if not self.ks.bootloader.source and part.mountpoint == "/boot":
-                self.ks.bootloader.source = part.source
-
-            # generate parition UUIDs
-            if not part.uuid and part.use_uuid:
-                if self.ptable_format == 'gpt':
-                    part.uuid = str(uuid.uuid4())
-                else: # msdos partition table
-                    if part.disk not in disk_ids:
-                        disk_ids[part.disk] = int.from_bytes(os.urandom(4), 'little')
-                    disk_id = disk_ids[part.disk]
-                    part.uuid = '%0x-%02d' % (disk_id, self._get_part_num(num, parts))
-
-        fstab_path = self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
-
-        for part in parts:
-            # get rootfs size from bitbake variable if it's not set in .ks file
-            if not part.size:
-                # and if rootfs name is specified for the partition
-                image_name = self.rootfs_dir.get(part.rootfs_dir)
-                if image_name and os.path.sep not in image_name:
-                    # Bitbake variable ROOTFS_SIZE is calculated in
-                    # Image._get_rootfs_size method from meta/lib/oe/image.py
-                    # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT,
-                    # IMAGE_OVERHEAD_FACTOR and IMAGE_ROOTFS_EXTRA_SPACE
-                    rsize_bb = get_bitbake_var('ROOTFS_SIZE', image_name)
-                    if rsize_bb:
-                        part.size = int(round(float(rsize_bb)))
-            # need to create the filesystems in order to get their
-            # sizes before we can add them and do the layout.
-            # Image.create() actually calls __format_disks() to create
-            # the disk images and carve out the partitions, then
-            # self.assemble() calls Image.assemble() which calls
-            # __write_partitition() for each partition to dd the fs
-            # into the partitions.
-            part.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir,
-                         self.bootimg_dir, self.kernel_dir, self.native_sysroot)
-
-
-            self._image.add_partition(part.disk_size,
-                                       part.disk,
-                                       part.mountpoint,
-                                       part.source_file,
-                                       part.fstype,
-                                       part.label,
-                                       fsopts=part.fsopts,
-                                       boot=part.active,
-                                       align=part.align,
-                                       no_table=part.no_table,
-                                       part_type=part.part_type,
-                                       uuid=part.uuid,
-                                       system_id=part.system_id)
-
-        if fstab_path:
-            shutil.move(fstab_path + ".orig", fstab_path)
-
-        self._image.layout_partitions(self.ptable_format)
-
-        for disk_name, disk in self._image.disks.items():
-            full_path = self._full_path(self.workdir, disk_name, "direct")
-            msger.debug("Adding disk %s as %s with size %s bytes" \
-                        % (disk_name, full_path, disk['min_size']))
-            disk_obj = DiskImage(full_path, disk['min_size'])
-            #self._disks[disk_name] = disk_obj
-            self._image.add_disk(disk_name, disk_obj, disk_ids.get(disk_name))
-
-        self._image.create()
-
-    def assemble(self):
-        """
-        Assemble partitions into disk image(s)
-        """
-        for disk_name, disk in self._image.disks.items():
-            full_path = self._full_path(self.workdir, disk_name, "direct")
-            msger.debug("Assembling disk %s as %s with size %s bytes" \
-                        % (disk_name, full_path, disk['min_size']))
-            self._image.assemble(full_path)
-
-    def finalize(self):
-        """
-        Finalize the disk image.
-
-        For example, prepare the image to be bootable by e.g.
-        creating and installing a bootloader configuration.
-        """
-        source_plugin = self.get_default_source_plugin()
-        if source_plugin:
-            self._source_methods = pluginmgr.get_source_plugin_methods(source_plugin, disk_methods)
-            for disk_name, disk in self._image.disks.items():
-                self._source_methods["do_install_disk"](disk, disk_name, self,
-                                                        self.workdir,
-                                                        self.oe_builddir,
-                                                        self.bootimg_dir,
-                                                        self.kernel_dir,
-                                                        self.native_sysroot)
-
-        for disk_name, disk in self._image.disks.items():
-            full_path = self._full_path(self.workdir, disk_name, "direct")
-            # Generate .bmap
-            if self.bmap:
-                msger.debug("Generating bmap file for %s" % disk_name)
-                exec_native_cmd("bmaptool create %s -o %s.bmap" % (full_path, full_path),
-                                self.native_sysroot)
-            # Compress the image
-            if self.compressor:
-                msger.debug("Compressing disk %s with %s" % (disk_name, self.compressor))
-                exec_cmd("%s %s" % (self.compressor, full_path))
-
-    def print_outimage_info(self):
-        """
-        Print the image(s) and artifacts used, for the user.
-        """
-        msg = "The new image(s) can be found here:\n"
-
-        parts = self._get_parts()
-
-        for disk_name in self._image.disks:
-            extension = "direct" + {"gzip": ".gz",
-                                    "bzip2": ".bz2",
-                                    "xz": ".xz",
-                                    "": ""}.get(self.compressor)
-            full_path = self._full_path(self.outdir, disk_name, extension)
-            msg += '  %s\n\n' % full_path
-
-        msg += 'The following build artifacts were used to create the image(s):\n'
-        for part in parts:
-            if part.rootfs_dir is None:
-                continue
-            if part.mountpoint == '/':
-                suffix = ':'
-            else:
-                suffix = '["%s"]:' % (part.mountpoint or part.label)
-            msg += '  ROOTFS_DIR%s%s\n' % (suffix.ljust(20), part.rootfs_dir)
-
-        msg += '  BOOTIMG_DIR:                  %s\n' % self.bootimg_dir
-        msg += '  KERNEL_DIR:                   %s\n' % self.kernel_dir
-        msg += '  NATIVE_SYSROOT:               %s\n' % self.native_sysroot
-
-        msger.info(msg)
-
-    @property
-    def rootdev(self):
-        """
-        Get root device name to use as a 'root' parameter
-        in kernel command line.
-
-        Assume partition order same as in wks
-        """
-        parts = self._get_parts()
-        for num, part in enumerate(parts, 1):
-            if part.mountpoint == "/":
-                if part.uuid:
-                    return "PARTUUID=%s" % part.uuid
-                else:
-                    suffix = 'p' if part.disk.startswith('mmcblk') else ''
-                    pnum = self._get_part_num(num, parts)
-                    return "/dev/%s%s%-d" % (part.disk, suffix, pnum)
-
-    def cleanup(self):
-        if self._image:
-            try:
-                self._image.cleanup()
-            except ImageError as err:
-                msger.warning("%s" % err)
-
-        # Move results to the output dir
-        if not os.path.exists(self.outdir):
-            os.makedirs(self.outdir)
-
-        for fname in os.listdir(self.workdir):
-            path = os.path.join(self.workdir, fname)
-            if os.path.isfile(path):
-                shutil.move(path, os.path.join(self.outdir, fname))
-
-        # remove work directory
-        shutil.rmtree(self.workdir, ignore_errors=True)
-
diff --git a/scripts/lib/wic/plugins/imager/direct_plugin.py b/scripts/lib/wic/plugins/imager/direct_plugin.py
index e839d2f..91a9792 100644
--- a/scripts/lib/wic/plugins/imager/direct_plugin.py
+++ b/scripts/lib/wic/plugins/imager/direct_plugin.py
@@ -23,16 +23,23 @@
 # AUTHORS
 # Tom Zanussi <tom.zanussi (at] linux.intel.com>
 #
+import os
+import shutil
+import uuid
+import tempfile
+import time
 
 from time import strftime
-
 from os.path import basename, splitext
-from wic.utils import errors
-from wic.ksparser import KickStart, KickStartError
-from wic import msger
 
-import wic.imager.direct as direct
+from wic import msger
+from wic.ksparser import KickStart, KickStartError
+from wic.plugin import pluginmgr
 from wic.pluginbase import ImagerPlugin
+from wic.utils import errors
+from wic.utils.errors import CreatorError, ImageError
+from wic.utils.oe.misc import get_bitbake_var, exec_cmd, exec_native_cmd
+from wic.utils.partitionedfs import Image
 
 class DirectPlugin(ImagerPlugin):
     """
@@ -87,16 +94,10 @@ class DirectPlugin(ImagerPlugin):
                           strftime("%Y%m%d%H%M"))
         krootfs_dir = cls.__rootfs_dir_to_dict(rootfs_dir)
 
-        creator = direct.DirectImageCreator(image_name,
-                                            ksobj,
-                                            oe_builddir,
-                                            image_output_dir,
-                                            krootfs_dir,
-                                            bootimg_dir,
-                                            kernel_dir,
-                                            native_sysroot,
-                                            compressor,
-                                            opts.bmap)
+        creator = DirectImageCreator(image_name, ksobj, oe_builddir,
+                                     image_output_dir, krootfs_dir,
+                                     bootimg_dir, kernel_dir, native_sysroot,
+                                     compressor, opts.bmap)
         try:
             creator.create()
             creator.assemble()
@@ -108,4 +109,367 @@ class DirectPlugin(ImagerPlugin):
         finally:
             creator.cleanup()
 
-        return 0
+disk_methods = {
+    "do_install_disk":None,
+}
+
+class DiskImage():
+    """
+    A Disk backed by a file.
+    """
+    def __init__(self, device, size):
+        self.size = size
+        self.device = device
+        self.created = False
+
+    def exists(self):
+        return os.path.exists(self.device)
+
+    def create(self):
+        if self.created:
+            return
+        # create sparse disk image
+        with open(self.device, 'w') as sparse:
+            os.ftruncate(sparse.fileno(), self.size)
+
+        self.created = True
+
+class DirectImageCreator:
+    """
+    Installs a system into a file containing a partitioned disk image.
+
+    DirectImageCreator is an advanced ImageCreator subclass; an image
+    file is formatted with a partition table, each partition created
+    from a rootfs or other OpenEmbedded build artifact and dd'ed into
+    the virtual disk. The disk image can subsequently be dd'ed onto
+    media and used on actual hardware.
+    """
+
+    def __init__(self, image_name, ksobj, oe_builddir, image_output_dir,
+                 rootfs_dir, bootimg_dir, kernel_dir, native_sysroot,
+                 compressor, bmap=False):
+        """
+        Initialize a DirectImageCreator instance.
+
+        This method takes the same arguments as ImageCreator.__init__()
+        """
+        self.name = image_name
+        self.outdir = image_output_dir
+        self.workdir = tempfile.mktemp(prefix='wic')
+        self.ks = ksobj
+
+        self.__image = None
+        self.__disks = {}
+        self.__disk_format = "direct"
+        self._disk_names = []
+        self.ptable_format = self.ks.bootloader.ptable
+
+        self.oe_builddir = oe_builddir
+        self.rootfs_dir = rootfs_dir
+        self.bootimg_dir = bootimg_dir
+        self.kernel_dir = kernel_dir
+        self.native_sysroot = native_sysroot
+        self.compressor = compressor
+        self.bmap = bmap
+
+    def _get_part_num(self, num, parts):
+        """calculate the real partition number, accounting for partitions not
+        in the partition table and logical partitions
+        """
+        realnum = 0
+        for pnum, part in enumerate(parts, 1):
+            if not part.no_table:
+                realnum += 1
+            if pnum == num:
+                if  part.no_table:
+                    return 0
+                if self.ptable_format == 'msdos' and realnum > 3:
+                    # account for logical partition numbering, ex. sda5..
+                    return realnum + 1
+                return realnum
+
+    def _write_fstab(self, image_rootfs):
+        """overriden to generate fstab (temporarily) in rootfs. This is called
+        from _create, make sure it doesn't get called from
+        BaseImage.create()
+        """
+        if not image_rootfs:
+            return
+
+        fstab_path = image_rootfs + "/etc/fstab"
+        if not os.path.isfile(fstab_path):
+            return
+
+        with open(fstab_path) as fstab:
+            fstab_lines = fstab.readlines()
+
+        if self._update_fstab(fstab_lines, self._get_parts()):
+            shutil.copyfile(fstab_path, fstab_path + ".orig")
+
+            with open(fstab_path, "w") as fstab:
+                fstab.writelines(fstab_lines)
+
+            return fstab_path
+
+    def _update_fstab(self, fstab_lines, parts):
+        """Assume partition order same as in wks"""
+        updated = False
+        for num, part in enumerate(parts, 1):
+            pnum = self._get_part_num(num, parts)
+            if not pnum or not part.mountpoint \
+               or part.mountpoint in ("/", "/boot"):
+                continue
+
+            # mmc device partitions are named mmcblk0p1, mmcblk0p2..
+            prefix = 'p' if  part.disk.startswith('mmcblk') else ''
+            device_name = "/dev/%s%s%d" % (part.disk, prefix, pnum)
+
+            opts = part.fsopts if part.fsopts else "defaults"
+            line = "\t".join([device_name, part.mountpoint, part.fstype,
+                              opts, "0", "0"]) + "\n"
+
+            fstab_lines.append(line)
+            updated = True
+
+        return updated
+
+    def set_bootimg_dir(self, bootimg_dir):
+        """
+        Accessor for bootimg_dir, the actual location used for the source
+        of the bootimg.  Should be set by source plugins (only if they
+        change the default bootimg source) so the correct info gets
+        displayed for print_outimage_info().
+        """
+        self.bootimg_dir = bootimg_dir
+
+    def _get_parts(self):
+        if not self.ks:
+            raise CreatorError("Failed to get partition info, "
+                               "please check your kickstart setting.")
+
+        # Set a default partition if no partition is given out
+        if not self.ks.partitions:
+            partstr = "part / --size 1900 --ondisk sda --fstype=ext3"
+            args = partstr.split()
+            part = self.ks.parse(args[1:])
+            if part not in self.ks.partitions:
+                self.ks.partitions.append(part)
+
+        # partitions list from kickstart file
+        return self.ks.partitions
+
+    def _full_name(self, name, extention):
+        """ Construct full file name for a file we generate. """
+        return "%s-%s.%s" % (self.name, name, extention)
+
+    def _full_path(self, path, name, extention):
+        """ Construct full file path to a file we generate. """
+        return os.path.join(path, self._full_name(name, extention))
+
+    def get_default_source_plugin(self):
+        """
+        The default source plugin i.e. the plugin that's consulted for
+        overall image generation tasks outside of any particular
+        partition.  For convenience, we just hang it off the
+        bootloader handler since it's the one non-partition object in
+        any setup.  By default the default plugin is set to the same
+        plugin as the /boot partition; since we hang it off the
+        bootloader object, the default can be explicitly set using the
+        --source bootloader param.
+        """
+        return self.ks.bootloader.source
+
+    #
+    # Actual implemention
+    #
+    def create(self):
+        """
+        For 'wic', we already have our build artifacts - we just create
+        filesystems from the artifacts directly and combine them into
+        a partitioned image.
+        """
+        parts = self._get_parts()
+
+        self._image = Image(self.native_sysroot)
+
+        disk_ids = {}
+        for num, part in enumerate(parts, 1):
+            # as a convenience, set source to the boot partition source
+            # instead of forcing it to be set via bootloader --source
+            if not self.ks.bootloader.source and part.mountpoint == "/boot":
+                self.ks.bootloader.source = part.source
+
+            # generate parition UUIDs
+            if not part.uuid and part.use_uuid:
+                if self.ptable_format == 'gpt':
+                    part.uuid = str(uuid.uuid4())
+                else: # msdos partition table
+                    if part.disk not in disk_ids:
+                        disk_ids[part.disk] = int.from_bytes(os.urandom(4), 'little')
+                    disk_id = disk_ids[part.disk]
+                    part.uuid = '%0x-%02d' % (disk_id, self._get_part_num(num, parts))
+
+        fstab_path = self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
+
+        for part in parts:
+            # get rootfs size from bitbake variable if it's not set in .ks file
+            if not part.size:
+                # and if rootfs name is specified for the partition
+                image_name = self.rootfs_dir.get(part.rootfs_dir)
+                if image_name and os.path.sep not in image_name:
+                    # Bitbake variable ROOTFS_SIZE is calculated in
+                    # Image._get_rootfs_size method from meta/lib/oe/image.py
+                    # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT,
+                    # IMAGE_OVERHEAD_FACTOR and IMAGE_ROOTFS_EXTRA_SPACE
+                    rsize_bb = get_bitbake_var('ROOTFS_SIZE', image_name)
+                    if rsize_bb:
+                        part.size = int(round(float(rsize_bb)))
+            # need to create the filesystems in order to get their
+            # sizes before we can add them and do the layout.
+            # Image.create() actually calls __format_disks() to create
+            # the disk images and carve out the partitions, then
+            # self.assemble() calls Image.assemble() which calls
+            # __write_partitition() for each partition to dd the fs
+            # into the partitions.
+            part.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir,
+                         self.bootimg_dir, self.kernel_dir, self.native_sysroot)
+
+
+            self._image.add_partition(part.disk_size,
+                                       part.disk,
+                                       part.mountpoint,
+                                       part.source_file,
+                                       part.fstype,
+                                       part.label,
+                                       fsopts=part.fsopts,
+                                       boot=part.active,
+                                       align=part.align,
+                                       no_table=part.no_table,
+                                       part_type=part.part_type,
+                                       uuid=part.uuid,
+                                       system_id=part.system_id)
+
+        if fstab_path:
+            shutil.move(fstab_path + ".orig", fstab_path)
+
+        self._image.layout_partitions(self.ptable_format)
+
+        for disk_name, disk in self._image.disks.items():
+            full_path = self._full_path(self.workdir, disk_name, "direct")
+            msger.debug("Adding disk %s as %s with size %s bytes" \
+                        % (disk_name, full_path, disk['min_size']))
+            disk_obj = DiskImage(full_path, disk['min_size'])
+            #self._disks[disk_name] = disk_obj
+            self._image.add_disk(disk_name, disk_obj, disk_ids.get(disk_name))
+
+        self._image.create()
+
+    def assemble(self):
+        """
+        Assemble partitions into disk image(s)
+        """
+        for disk_name, disk in self._image.disks.items():
+            full_path = self._full_path(self.workdir, disk_name, "direct")
+            msger.debug("Assembling disk %s as %s with size %s bytes" \
+                        % (disk_name, full_path, disk['min_size']))
+            self._image.assemble(full_path)
+
+    def finalize(self):
+        """
+        Finalize the disk image.
+
+        For example, prepare the image to be bootable by e.g.
+        creating and installing a bootloader configuration.
+        """
+        source_plugin = self.get_default_source_plugin()
+        if source_plugin:
+            self._source_methods = pluginmgr.get_source_plugin_methods(source_plugin, disk_methods)
+            for disk_name, disk in self._image.disks.items():
+                self._source_methods["do_install_disk"](disk, disk_name, self,
+                                                        self.workdir,
+                                                        self.oe_builddir,
+                                                        self.bootimg_dir,
+                                                        self.kernel_dir,
+                                                        self.native_sysroot)
+
+        for disk_name, disk in self._image.disks.items():
+            full_path = self._full_path(self.workdir, disk_name, "direct")
+            # Generate .bmap
+            if self.bmap:
+                msger.debug("Generating bmap file for %s" % disk_name)
+                exec_native_cmd("bmaptool create %s -o %s.bmap" % (full_path, full_path),
+                                self.native_sysroot)
+            # Compress the image
+            if self.compressor:
+                msger.debug("Compressing disk %s with %s" % (disk_name, self.compressor))
+                exec_cmd("%s %s" % (self.compressor, full_path))
+
+    def print_outimage_info(self):
+        """
+        Print the image(s) and artifacts used, for the user.
+        """
+        msg = "The new image(s) can be found here:\n"
+
+        parts = self._get_parts()
+
+        for disk_name in self._image.disks:
+            extension = "direct" + {"gzip": ".gz",
+                                    "bzip2": ".bz2",
+                                    "xz": ".xz",
+                                    "": ""}.get(self.compressor)
+            full_path = self._full_path(self.outdir, disk_name, extension)
+            msg += '  %s\n\n' % full_path
+
+        msg += 'The following build artifacts were used to create the image(s):\n'
+        for part in parts:
+            if part.rootfs_dir is None:
+                continue
+            if part.mountpoint == '/':
+                suffix = ':'
+            else:
+                suffix = '["%s"]:' % (part.mountpoint or part.label)
+            msg += '  ROOTFS_DIR%s%s\n' % (suffix.ljust(20), part.rootfs_dir)
+
+        msg += '  BOOTIMG_DIR:                  %s\n' % self.bootimg_dir
+        msg += '  KERNEL_DIR:                   %s\n' % self.kernel_dir
+        msg += '  NATIVE_SYSROOT:               %s\n' % self.native_sysroot
+
+        msger.info(msg)
+
+    @property
+    def rootdev(self):
+        """
+        Get root device name to use as a 'root' parameter
+        in kernel command line.
+
+        Assume partition order same as in wks
+        """
+        parts = self._get_parts()
+        for num, part in enumerate(parts, 1):
+            if part.mountpoint == "/":
+                if part.uuid:
+                    return "PARTUUID=%s" % part.uuid
+                else:
+                    suffix = 'p' if part.disk.startswith('mmcblk') else ''
+                    pnum = self._get_part_num(num, parts)
+                    return "/dev/%s%s%-d" % (part.disk, suffix, pnum)
+
+    def cleanup(self):
+        if self._image:
+            try:
+                self._image.cleanup()
+            except ImageError as err:
+                msger.warning("%s" % err)
+
+        # Move results to the output dir
+        if not os.path.exists(self.outdir):
+            os.makedirs(self.outdir)
+
+        for fname in os.listdir(self.workdir):
+            path = os.path.join(self.workdir, fname)
+            if os.path.isfile(path):
+                shutil.move(path, os.path.join(self.outdir, fname))
+
+        # remove work directory
+        shutil.rmtree(self.workdir, ignore_errors=True)
+
-- 
2.1.4




More information about the Openembedded-core mailing list