From: Chee Yang Lee <chee.yang....@intel.com> This patch implement 'installer-partition.py' source plugin for wic. The plugin create an image with systemd-boot and rootfs. The generated image can be use to create wic based image installer.
Signed-off-by: Chee Yang Lee <chee.yang....@intel.com> --- .../lib/wic/plugins/source/installer-partition.py | 192 +++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 scripts/lib/wic/plugins/source/installer-partition.py diff --git a/scripts/lib/wic/plugins/source/installer-partition.py b/scripts/lib/wic/plugins/source/installer-partition.py new file mode 100644 index 0000000..4d8343f --- /dev/null +++ b/scripts/lib/wic/plugins/source/installer-partition.py @@ -0,0 +1,192 @@ +# Copyright (c) 2019, 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 'installer-partition' source plugin class for 'wic' +# This plugin prepare partition with content to be install on target machine. +# +# AUTHORS +# Lee Chee Yang <Chee.Yang.Lee (at] intel.com> +# + +import logging +import os + +from wic import WicError +from wic.engine import get_custom_config +from wic.pluginbase import SourcePlugin +from wic.misc import (exec_cmd, exec_native_cmd, get_bitbake_var) + +logger = logging.getLogger('wic') + +class InstallerImagePlugin(SourcePlugin): + """ + Populate content for wic image based installer + """ + + name = 'installer-partition' + + @classmethod + def do_configure_partition(cls, part, source_params, creator, cr_workdir, + oe_builddir, bootimg_dir, kernel_dir, + native_sysroot): + """ + Called before do_prepare_partition(), creates loader-specific config + """ + if not kernel_dir: + kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") + if not kernel_dir: + raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") + staging_kernel_dir = kernel_dir + + partition_dir = "%s/%s-%s" % (cr_workdir, part.label, part.lineno) + + install_cmd = "install -d %s/EFI/BOOT" % partition_dir + exec_cmd(install_cmd) + + install_cmd = "install -d %s/loader/entries" % partition_dir + exec_cmd(install_cmd) + + bootloader = creator.ks.bootloader + + loader_conf = "" + loader_conf += "default boot\n" + loader_conf += "timeout %d\n" % bootloader.timeout + + initrd = source_params.get('initrd') + + if initrd: + cp_cmd = "cp %s/%s %s" % (kernel_dir, initrd, partition_dir) + exec_cmd(cp_cmd, True) + else: + logger.debug("Ignoring missing initrd") + + logger.debug("Writing systemd-boot config " + "%s/loader/loader.conf", partition_dir) + cfg = open("%s/loader/loader.conf" % partition_dir, "w") + cfg.write(loader_conf) + cfg.close() + + kernel = get_bitbake_var("KERNEL_IMAGETYPE") + if not kernel: + kernel = "bzImage" + + install_cmd = "install -m 0644 %s/%s %s/%s" % \ + (staging_kernel_dir, kernel, partition_dir, kernel) + exec_cmd(install_cmd) + + configfile = creator.ks.bootloader.configfile + custom_cfg = None + if configfile: + custom_cfg = get_custom_config(configfile) + if custom_cfg: + # Use a custom configuration for systemd-boot + boot_conf = custom_cfg + logger.debug("Using custom configuration file " + "%s for systemd-boots's boot.conf", configfile) + else: + raise WicError("configfile is specified but failed to " + "get it from %s.", configfile) + + if not custom_cfg: + # Create systemd-boot configuration using parameters from wks file + title = source_params.get('title') + + boot_conf = "" + boot_conf += "title %s\n" % (title if title else "boot") + boot_conf += "linux /%s\n" % kernel + boot_conf += "options LABEL=Boot %s\n" % (bootloader.append) + + if initrd: + boot_conf += "initrd /%s\n" % initrd + + for mod in [x for x in os.listdir(kernel_dir) if x.startswith("systemd-")]: + cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, partition_dir, mod[8:]) + exec_cmd(cp_cmd, True) + + logger.debug("Writing systemd-boot config " + "%s/loader/entries/boot.conf", partition_dir) + cfg = open("%s//loader/entries/boot.conf" % partition_dir, "w") + cfg.write(boot_conf) + cfg.close() + + + @classmethod + def do_prepare_partition(cls, part, source_params, creator, cr_workdir, + oe_builddir, bootimg_dir, kernel_dir, + rootfs_dir, native_sysroot): + """ + Called to do the actual content population for a partition, + prepare systemd bootloader and rootfs image + """ + partition_dir = "%s/%s-%s" % (cr_workdir, part.label, part.lineno) + + rootfs = "%s/fs_%s.%s.%s" % (cr_workdir, part.label, part.lineno, part.fstype) + + image_deploy_dir = get_bitbake_var("IMGDEPLOYDIR") + if not image_deploy_dir: + raise WicError("Couldn't find IMGDEPLOYDIR, exiting") + + rootfs_img = "%s/%s.%s" % (image_deploy_dir, + get_bitbake_var("IMAGE_LINK_NAME"), part.fstype ) + if not os.path.isfile(rootfs_img): + raise WicError("Couldn't find %s, exiting" % rootfs_img) + + install_cmd = "install -m 0644 %s %s/rootfs.img" % \ + (rootfs_img, partition_dir) + exec_cmd(install_cmd) + + #look for actual size required for the partition + du_cmd = "du -ks %s" % partition_dir + out = exec_cmd(du_cmd) + part.size = cls.get_partition_size(part, int(out.split()[0])) + logger.debug("Set partition size to %d ", part.size) + + with open(rootfs, 'w') as sparse: + os.ftruncate(sparse.fileno(), part.size * 1024) + + extraopts = part.mkfs_extraopts or "-i 8192" + + label_str = "" + if part.label: + label_str = "-L %s" % part.label + + mkfs_cmd = "mkfs.%s -F %s %s -U %s %s -d %s" % \ + (part.fstype, extraopts, label_str, part.fsuuid, rootfs, partition_dir) + exec_native_cmd(mkfs_cmd, native_sysroot) + + part.source_file = rootfs + + + def get_partition_size(part, actual_partition_size=0): + """ + Calculate the required size of the partition, taking into consideration + --size/--fixed-size/--extra-space flags specified in kickstart file. + Raises an error if the `actual_partition_size` is larger than fixed-size. + """ + if part.fixed_size: + partition_size = part.fixed_size + if actual_partition_size > partition_size: + raise WicError("Actual partition size (%d kB) is larger than " + "allowed size %d kB" % + (actual_partition_size, partition_size)) + else: + extra_space = 0 + if extra_space < part.extra_space: + extra_space = part.extra_space + partition_size = actual_partition_size + extra_space + + return partition_size -- 2.7.4 -- _______________________________________________ Openembedded-core mailing list Openembedded-core@lists.openembedded.org http://lists.openembedded.org/mailman/listinfo/openembedded-core