diff options
author | Dave Cobbley <david.j.cobbley@linux.intel.com> | 2018-08-14 10:05:37 -0700 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2018-08-22 21:26:31 -0400 |
commit | eb8dc40360f0cfef56fb6947cc817a547d6d9bc6 (patch) | |
tree | de291a73dc37168da6370e2cf16c347d1eba9df8 /import-layers/yocto-poky/scripts/lib/wic | |
parent | 9c3cf826d853102535ead04cebc2d6023eff3032 (diff) | |
download | blackbird-openbmc-eb8dc40360f0cfef56fb6947cc817a547d6d9bc6.tar.gz blackbird-openbmc-eb8dc40360f0cfef56fb6947cc817a547d6d9bc6.zip |
[Subtree] Removing import-layers directory
As part of the move to subtrees, need to bring all the import layers
content to the top level.
Change-Id: I4a163d10898cbc6e11c27f776f60e1a470049d8f
Signed-off-by: Dave Cobbley <david.j.cobbley@linux.intel.com>
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'import-layers/yocto-poky/scripts/lib/wic')
27 files changed, 0 insertions, 5324 deletions
diff --git a/import-layers/yocto-poky/scripts/lib/wic/__init__.py b/import-layers/yocto-poky/scripts/lib/wic/__init__.py deleted file mode 100644 index 85876b138..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python -tt -# -# Copyright (c) 2007 Red Hat, Inc. -# Copyright (c) 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -class WicError(Exception): - pass diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/common.wks.inc b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/common.wks.inc deleted file mode 100644 index 89880b417..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/common.wks.inc +++ /dev/null @@ -1,3 +0,0 @@ -# This file is included into 3 canned wks files from this directory -part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024 -part / --source rootfs --use-uuid --fstype=ext4 --label platform --align 1024 diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg deleted file mode 100644 index c58e74a85..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg +++ /dev/null @@ -1,27 +0,0 @@ -# This is an example configuration file for syslinux. -TIMEOUT 50 -ALLOWOPTIONS 1 -SERIAL 0 115200 -PROMPT 0 - -UI vesamenu.c32 -menu title Select boot options -menu tabmsg Press [Tab] to edit, [Return] to select - -DEFAULT Graphics console boot - -LABEL Graphics console boot -KERNEL /vmlinuz -APPEND label=boot rootwait - -LABEL Serial console boot -KERNEL /vmlinuz -APPEND label=boot rootwait console=ttyS0,115200 - -LABEL Graphics console install -KERNEL /vmlinuz -APPEND label=install rootwait - -LABEL Serial console install -KERNEL /vmlinuz -APPEND label=install rootwait console=ttyS0,115200 diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.wks deleted file mode 100644 index 3529e05c8..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.wks +++ /dev/null @@ -1,8 +0,0 @@ -# short-description: Create a 'pcbios' direct disk image with custom bootloader config -# long-description: Creates a partitioned legacy BIOS disk image that the user -# can directly dd to boot media. The bootloader configuration source is a user file. - -include common.wks.inc - -bootloader --configfile="directdisk-bootloader-config.cfg" - diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-gpt.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-gpt.wks deleted file mode 100644 index 8d7d8de6e..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-gpt.wks +++ /dev/null @@ -1,10 +0,0 @@ -# short-description: Create a 'pcbios' direct disk image -# long-description: Creates a partitioned legacy BIOS disk image that the user -# can directly dd to boot media. - - -part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024 -part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid - -bootloader --ptable gpt --timeout=0 --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8" - diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-multi-rootfs.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-multi-rootfs.wks deleted file mode 100644 index f61d941d6..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk-multi-rootfs.wks +++ /dev/null @@ -1,23 +0,0 @@ -# short-description: Create multi rootfs image using rootfs plugin -# long-description: Creates a partitioned disk image with two rootfs partitions -# using rootfs plugin. -# -# Partitions can use either -# - indirect rootfs references to image recipe(s): -# wic create directdisk-multi-indirect-recipes -e core-image-minimal \ -# --rootfs-dir rootfs1=core-image-minimal -# --rootfs-dir rootfs2=core-image-minimal-dev -# -# - or paths to rootfs directories: -# wic create directdisk-multi-rootfs \ -# --rootfs-dir rootfs1=tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0-r0/rootfs/ -# --rootfs-dir rootfs2=tmp/work/qemux86_64-poky-linux/core-image-minimal-dev/1.0-r0/rootfs/ -# -# - or any combinations of -r and --rootfs command line options - -part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024 -part / --source rootfs --rootfs-dir=rootfs1 --ondisk sda --fstype=ext4 --label platform --align 1024 -part /rescue --source rootfs --rootfs-dir=rootfs2 --ondisk sda --fstype=ext4 --label secondary --align 1024 - -bootloader --timeout=0 --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8" - diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk.wks deleted file mode 100644 index 8c8e06b02..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/directdisk.wks +++ /dev/null @@ -1,8 +0,0 @@ -# short-description: Create a 'pcbios' direct disk image -# long-description: Creates a partitioned legacy BIOS disk image that the user -# can directly dd to boot media. - -include common.wks.inc - -bootloader --timeout=0 --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8" - diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in deleted file mode 100644 index 7300e65e3..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in +++ /dev/null @@ -1,3 +0,0 @@ -bootloader --ptable gpt -part /boot --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/boot --fstype=vfat --label boot --active --align 1024 --use-uuid --overhead-factor 1.0 -part / --source rootfs --fstype=ext4 --label root --align 1024 --exclude-path boot/ diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/mkefidisk.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/mkefidisk.wks deleted file mode 100644 index 9f534fe18..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/mkefidisk.wks +++ /dev/null @@ -1,11 +0,0 @@ -# short-description: Create an EFI disk image -# long-description: Creates a partitioned EFI disk image that the user -# can directly dd to boot media. - -part /boot --source bootimg-efi --sourceparams="loader=grub-efi" --ondisk sda --label msdos --active --align 1024 - -part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid - -part swap --ondisk sda --size 44 --label swap1 --fstype=swap - -bootloader --ptable gpt --timeout=5 --append="rootfstype=ext4 console=ttyS0,115200 console=tty0" diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/mkhybridiso.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/mkhybridiso.wks deleted file mode 100644 index 9d34e9b47..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/mkhybridiso.wks +++ /dev/null @@ -1,7 +0,0 @@ -# short-description: Create a hybrid ISO image -# long-description: Creates an EFI and legacy bootable hybrid ISO image -# which can be used on optical media as well as USB media. - -part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi,image_name=HYBRID_ISO_IMG" --ondisk cd --label HYBRIDISO --fstype=ext4 - -bootloader --timeout=15 --append="" diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/qemux86-directdisk.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/qemux86-directdisk.wks deleted file mode 100644 index 1f8466af2..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/qemux86-directdisk.wks +++ /dev/null @@ -1,8 +0,0 @@ -# short-description: Create a qemu machine 'pcbios' direct disk image -# long-description: Creates a partitioned legacy BIOS disk image that the user -# can directly use to boot a qemu machine. - -include common.wks.inc - -bootloader --timeout=0 --append="vga=0 uvesafb.mode_option=640x480-32 rw mem=256M ip=192.168.7.2::192.168.7.1:255.255.255.0 oprofile.timer=1 rootfstype=ext4 " - diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/sdimage-bootpart.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/sdimage-bootpart.wks deleted file mode 100644 index 7ffd632f4..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/sdimage-bootpart.wks +++ /dev/null @@ -1,6 +0,0 @@ -# short-description: Create SD card image with a boot partition -# long-description: Creates a partitioned SD card image. Boot files -# are located in the first vfat partition. - -part /boot --source bootimg-partition --ondisk mmcblk --fstype=vfat --label boot --active --align 4 --size 16 -part / --source rootfs --ondisk mmcblk --fstype=ext4 --label root --align 4 diff --git a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/systemd-bootdisk.wks b/import-layers/yocto-poky/scripts/lib/wic/canned-wks/systemd-bootdisk.wks deleted file mode 100644 index 95d7b97a6..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/canned-wks/systemd-bootdisk.wks +++ /dev/null @@ -1,11 +0,0 @@ -# short-description: Create an EFI disk image with systemd-boot -# long-description: Creates a partitioned EFI disk image that the user -# can directly dd to boot media. The selected bootloader is systemd-boot. - -part /boot --source bootimg-efi --sourceparams="loader=systemd-boot" --ondisk sda --label msdos --active --align 1024 --use-uuid - -part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid - -part swap --ondisk sda --size 44 --label swap1 --fstype=swap --use-uuid - -bootloader --ptable gpt --timeout=5 --append="rootwait rootfstype=ext4 console=ttyS0,115200 console=tty0" diff --git a/import-layers/yocto-poky/scripts/lib/wic/engine.py b/import-layers/yocto-poky/scripts/lib/wic/engine.py deleted file mode 100644 index edcfab39e..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/engine.py +++ /dev/null @@ -1,565 +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 module implements the image creation engine used by 'wic' to -# create images. The engine parses through the OpenEmbedded kickstart -# (wks) file specified and generates images that can then be directly -# written onto media. -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import logging -import os -import tempfile -import json -import subprocess - -from collections import namedtuple, OrderedDict -from distutils.spawn import find_executable - -from wic import WicError -from wic.filemap import sparse_copy -from wic.pluginbase import PluginMgr -from wic.misc import get_bitbake_var, exec_cmd - -logger = logging.getLogger('wic') - -def verify_build_env(): - """ - Verify that the build environment is sane. - - Returns True if it is, false otherwise - """ - if not os.environ.get("BUILDDIR"): - raise WicError("BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)") - - return True - - -CANNED_IMAGE_DIR = "lib/wic/canned-wks" # relative to scripts -SCRIPTS_CANNED_IMAGE_DIR = "scripts/" + CANNED_IMAGE_DIR -WIC_DIR = "wic" - -def build_canned_image_list(path): - layers_path = get_bitbake_var("BBLAYERS") - canned_wks_layer_dirs = [] - - if layers_path is not None: - for layer_path in layers_path.split(): - for wks_path in (WIC_DIR, SCRIPTS_CANNED_IMAGE_DIR): - cpath = os.path.join(layer_path, wks_path) - if os.path.isdir(cpath): - canned_wks_layer_dirs.append(cpath) - - cpath = os.path.join(path, CANNED_IMAGE_DIR) - canned_wks_layer_dirs.append(cpath) - - return canned_wks_layer_dirs - -def find_canned_image(scripts_path, wks_file): - """ - Find a .wks file with the given name in the canned files dir. - - Return False if not found - """ - layers_canned_wks_dir = build_canned_image_list(scripts_path) - - for canned_wks_dir in layers_canned_wks_dir: - for root, dirs, files in os.walk(canned_wks_dir): - for fname in files: - if fname.endswith("~") or fname.endswith("#"): - continue - if fname.endswith(".wks") and wks_file + ".wks" == fname: - fullpath = os.path.join(canned_wks_dir, fname) - return fullpath - return None - - -def list_canned_images(scripts_path): - """ - List the .wks files in the canned image dir, minus the extension. - """ - layers_canned_wks_dir = build_canned_image_list(scripts_path) - - for canned_wks_dir in layers_canned_wks_dir: - for root, dirs, files in os.walk(canned_wks_dir): - for fname in files: - if fname.endswith("~") or fname.endswith("#"): - continue - if fname.endswith(".wks"): - fullpath = os.path.join(canned_wks_dir, fname) - with open(fullpath) as wks: - for line in wks: - desc = "" - idx = line.find("short-description:") - if idx != -1: - desc = line[idx + len("short-description:"):].strip() - break - basename = os.path.splitext(fname)[0] - print(" %s\t\t%s" % (basename.ljust(30), desc)) - - -def list_canned_image_help(scripts_path, fullpath): - """ - List the help and params in the specified canned image. - """ - found = False - with open(fullpath) as wks: - for line in wks: - if not found: - idx = line.find("long-description:") - if idx != -1: - print() - print(line[idx + len("long-description:"):].strip()) - found = True - continue - if not line.strip(): - break - idx = line.find("#") - if idx != -1: - print(line[idx + len("#:"):].rstrip()) - else: - break - - -def list_source_plugins(): - """ - List the available source plugins i.e. plugins available for --source. - """ - plugins = PluginMgr.get_plugins('source') - - for plugin in plugins: - print(" %s" % plugin) - - -def wic_create(wks_file, rootfs_dir, bootimg_dir, kernel_dir, - native_sysroot, options): - """ - Create image - - wks_file - user-defined OE kickstart file - rootfs_dir - absolute path to the build's /rootfs dir - bootimg_dir - absolute path to the build's boot artifacts directory - kernel_dir - absolute path to the build's kernel directory - native_sysroot - absolute path to the build's native sysroots dir - image_output_dir - dirname to create for image - options - wic command line options (debug, bmap, etc) - - Normally, the values for the build artifacts values are determined - by 'wic -e' from the output of the 'bitbake -e' command given an - image name e.g. 'core-image-minimal' and a given machine set in - local.conf. If that's the case, the variables get the following - values from the output of 'bitbake -e': - - rootfs_dir: IMAGE_ROOTFS - kernel_dir: DEPLOY_DIR_IMAGE - native_sysroot: STAGING_DIR_NATIVE - - In the above case, bootimg_dir remains unset and the - plugin-specific image creation code is responsible for finding the - bootimg artifacts. - - In the case where the values are passed in explicitly i.e 'wic -e' - is not used but rather the individual 'wic' options are used to - explicitly specify these values. - """ - try: - oe_builddir = os.environ["BUILDDIR"] - except KeyError: - raise WicError("BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)") - - if not os.path.exists(options.outdir): - os.makedirs(options.outdir) - - pname = 'direct' - plugin_class = PluginMgr.get_plugins('imager').get(pname) - if not plugin_class: - raise WicError('Unknown plugin: %s' % pname) - - plugin = plugin_class(wks_file, rootfs_dir, bootimg_dir, kernel_dir, - native_sysroot, oe_builddir, options) - - plugin.do_create() - - logger.info("The image(s) were created using OE kickstart file:\n %s", wks_file) - - -def wic_list(args, scripts_path): - """ - Print the list of images or source plugins. - """ - if args.list_type is None: - return False - - if args.list_type == "images": - - list_canned_images(scripts_path) - return True - elif args.list_type == "source-plugins": - list_source_plugins() - return True - elif len(args.help_for) == 1 and args.help_for[0] == 'help': - wks_file = args.list_type - fullpath = find_canned_image(scripts_path, wks_file) - if not fullpath: - raise WicError("No image named %s found, exiting. " - "(Use 'wic list images' to list available images, " - "or specify a fully-qualified OE kickstart (.wks) " - "filename)" % wks_file) - - list_canned_image_help(scripts_path, fullpath) - return True - - return False - - -class Disk: - def __init__(self, imagepath, native_sysroot, fstypes=('fat', 'ext')): - self.imagepath = imagepath - self.native_sysroot = native_sysroot - self.fstypes = fstypes - self._partitions = None - self._partimages = {} - self._lsector_size = None - self._psector_size = None - self._ptable_format = None - - # find parted - self.paths = "/bin:/usr/bin:/usr/sbin:/sbin/" - if native_sysroot: - for path in self.paths.split(':'): - self.paths = "%s%s:%s" % (native_sysroot, path, self.paths) - - self.parted = find_executable("parted", self.paths) - if not self.parted: - raise WicError("Can't find executable parted") - - self.partitions = self.get_partitions() - - def __del__(self): - for path in self._partimages.values(): - os.unlink(path) - - def get_partitions(self): - if self._partitions is None: - self._partitions = OrderedDict() - out = exec_cmd("%s -sm %s unit B print" % (self.parted, self.imagepath)) - parttype = namedtuple("Part", "pnum start end size fstype") - splitted = out.splitlines() - lsector_size, psector_size, self._ptable_format = splitted[1].split(":")[3:6] - self._lsector_size = int(lsector_size) - self._psector_size = int(psector_size) - for line in splitted[2:]: - pnum, start, end, size, fstype = line.split(':')[:5] - partition = parttype(int(pnum), int(start[:-1]), int(end[:-1]), - int(size[:-1]), fstype) - self._partitions[pnum] = partition - - return self._partitions - - def __getattr__(self, name): - """Get path to the executable in a lazy way.""" - if name in ("mdir", "mcopy", "mdel", "mdeltree", "sfdisk", "e2fsck", - "resize2fs", "mkswap", "mkdosfs", "debugfs"): - aname = "_%s" % name - if aname not in self.__dict__: - setattr(self, aname, find_executable(name, self.paths)) - if aname not in self.__dict__: - raise WicError("Can't find executable {}".format(name)) - return self.__dict__[aname] - return self.__dict__[name] - - def _get_part_image(self, pnum): - if pnum not in self.partitions: - raise WicError("Partition %s is not in the image") - part = self.partitions[pnum] - # check if fstype is supported - for fstype in self.fstypes: - if part.fstype.startswith(fstype): - break - else: - raise WicError("Not supported fstype: {}".format(part.fstype)) - if pnum not in self._partimages: - tmpf = tempfile.NamedTemporaryFile(prefix="wic-part") - dst_fname = tmpf.name - tmpf.close() - sparse_copy(self.imagepath, dst_fname, skip=part.start, length=part.size) - self._partimages[pnum] = dst_fname - - return self._partimages[pnum] - - def _put_part_image(self, pnum): - """Put partition image into partitioned image.""" - sparse_copy(self._partimages[pnum], self.imagepath, - seek=self.partitions[pnum].start) - - def dir(self, pnum, path): - if self.partitions[pnum].fstype.startswith('ext'): - return exec_cmd("{} {} -R 'ls -l {}'".format(self.debugfs, - self._get_part_image(pnum), - path), as_shell=True) - else: # fat - return exec_cmd("{} -i {} ::{}".format(self.mdir, - self._get_part_image(pnum), - path)) - - def copy(self, src, pnum, path): - """Copy partition image into wic image.""" - if self.partitions[pnum].fstype.startswith('ext'): - cmd = "echo -e 'cd {}\nwrite {} {}' | {} -w {}".\ - format(path, src, os.path.basename(src), - self.debugfs, self._get_part_image(pnum)) - else: # fat - cmd = "{} -i {} -snop {} ::{}".format(self.mcopy, - self._get_part_image(pnum), - src, path) - exec_cmd(cmd, as_shell=True) - self._put_part_image(pnum) - - def remove(self, pnum, path): - """Remove files/dirs from the partition.""" - partimg = self._get_part_image(pnum) - if self.partitions[pnum].fstype.startswith('ext'): - exec_cmd("{} {} -wR 'rm {}'".format(self.debugfs, - self._get_part_image(pnum), - path), as_shell=True) - else: # fat - cmd = "{} -i {} ::{}".format(self.mdel, partimg, path) - try: - exec_cmd(cmd) - except WicError as err: - if "not found" in str(err) or "non empty" in str(err): - # mdel outputs 'File ... not found' or 'directory .. non empty" - # try to use mdeltree as path could be a directory - cmd = "{} -i {} ::{}".format(self.mdeltree, - partimg, path) - exec_cmd(cmd) - else: - raise err - self._put_part_image(pnum) - - def write(self, target, expand): - """Write disk image to the media or file.""" - def write_sfdisk_script(outf, parts): - for key, val in parts['partitiontable'].items(): - if key in ("partitions", "device", "firstlba", "lastlba"): - continue - if key == "id": - key = "label-id" - outf.write("{}: {}\n".format(key, val)) - outf.write("\n") - for part in parts['partitiontable']['partitions']: - line = '' - for name in ('attrs', 'name', 'size', 'type', 'uuid'): - if name == 'size' and part['type'] == 'f': - # don't write size for extended partition - continue - val = part.get(name) - if val: - line += '{}={}, '.format(name, val) - if line: - line = line[:-2] # strip ', ' - if part.get('bootable'): - line += ' ,bootable' - outf.write("{}\n".format(line)) - outf.flush() - - def read_ptable(path): - out = exec_cmd("{} -dJ {}".format(self.sfdisk, path)) - return json.loads(out) - - def write_ptable(parts, target): - with tempfile.NamedTemporaryFile(prefix="wic-sfdisk-", mode='w') as outf: - write_sfdisk_script(outf, parts) - cmd = "{} --no-reread {} < {} 2>/dev/null".format(self.sfdisk, target, outf.name) - try: - subprocess.check_output(cmd, shell=True) - except subprocess.CalledProcessError as err: - raise WicError("Can't run '{}' command: {}".format(cmd, err)) - - if expand is None: - sparse_copy(self.imagepath, target) - else: - # copy first sectors that may contain bootloader - sparse_copy(self.imagepath, target, length=2048 * self._lsector_size) - - # copy source partition table to the target - parts = read_ptable(self.imagepath) - write_ptable(parts, target) - - # get size of unpartitioned space - free = None - for line in exec_cmd("{} -F {}".format(self.sfdisk, target)).splitlines(): - if line.startswith("Unpartitioned space ") and line.endswith("sectors"): - free = int(line.split()[-2]) - if free is None: - raise WicError("Can't get size of unpartitioned space") - - # calculate expanded partitions sizes - sizes = {} - for num, part in enumerate(parts['partitiontable']['partitions'], 1): - if num in expand: - if expand[num] != 0: # don't resize partition if size is set to 0 - sectors = expand[num] // self._lsector_size - free -= sectors - part['size'] - part['size'] = sectors - sizes[num] = sectors - elif part['type'] != 'f': - sizes[num] = -1 - - for num, part in enumerate(parts['partitiontable']['partitions'], 1): - if sizes.get(num) == -1: - part['size'] += free // len(sizes) - - # write resized partition table to the target - write_ptable(parts, target) - - # read resized partition table - parts = read_ptable(target) - - # copy partitions content - for num, part in enumerate(parts['partitiontable']['partitions'], 1): - pnum = str(num) - fstype = self.partitions[pnum].fstype - - # copy unchanged partition - if part['size'] == self.partitions[pnum].size // self._lsector_size: - logger.info("copying unchanged partition {}".format(pnum)) - sparse_copy(self._get_part_image(pnum), target, seek=part['start'] * self._lsector_size) - continue - - # resize or re-create partitions - if fstype.startswith('ext') or fstype.startswith('fat') or \ - fstype.startswith('linux-swap'): - - partfname = None - with tempfile.NamedTemporaryFile(prefix="wic-part{}-".format(pnum)) as partf: - partfname = partf.name - - if fstype.startswith('ext'): - logger.info("resizing ext partition {}".format(pnum)) - partimg = self._get_part_image(pnum) - sparse_copy(partimg, partfname) - exec_cmd("{} -pf {}".format(self.e2fsck, partfname)) - exec_cmd("{} {} {}s".format(\ - self.resize2fs, partfname, part['size'])) - elif fstype.startswith('fat'): - logger.info("copying content of the fat partition {}".format(pnum)) - with tempfile.TemporaryDirectory(prefix='wic-fatdir-') as tmpdir: - # copy content to the temporary directory - cmd = "{} -snompi {} :: {}".format(self.mcopy, - self._get_part_image(pnum), - tmpdir) - exec_cmd(cmd) - # create new msdos partition - label = part.get("name") - label_str = "-n {}".format(label) if label else '' - - cmd = "{} {} -C {} {}".format(self.mkdosfs, label_str, partfname, - part['size']) - exec_cmd(cmd) - # copy content from the temporary directory to the new partition - cmd = "{} -snompi {} {}/* ::".format(self.mcopy, partfname, tmpdir) - exec_cmd(cmd, as_shell=True) - elif fstype.startswith('linux-swap'): - logger.info("creating swap partition {}".format(pnum)) - label = part.get("name") - label_str = "-L {}".format(label) if label else '' - uuid = part.get("uuid") - uuid_str = "-U {}".format(uuid) if uuid else '' - with open(partfname, 'w') as sparse: - os.ftruncate(sparse.fileno(), part['size'] * self._lsector_size) - exec_cmd("{} {} {} {}".format(self.mkswap, label_str, uuid_str, partfname)) - sparse_copy(partfname, target, seek=part['start'] * self._lsector_size) - os.unlink(partfname) - elif part['type'] != 'f': - logger.warn("skipping partition {}: unsupported fstype {}".format(pnum, fstype)) - -def wic_ls(args, native_sysroot): - """List contents of partitioned image or vfat partition.""" - disk = Disk(args.path.image, native_sysroot) - if not args.path.part: - if disk.partitions: - print('Num Start End Size Fstype') - for part in disk.partitions.values(): - print("{:2d} {:12d} {:12d} {:12d} {}".format(\ - part.pnum, part.start, part.end, - part.size, part.fstype)) - else: - path = args.path.path or '/' - print(disk.dir(args.path.part, path)) - -def wic_cp(args, native_sysroot): - """ - Copy local file or directory to the vfat partition of - partitioned image. - """ - disk = Disk(args.dest.image, native_sysroot) - disk.copy(args.src, args.dest.part, args.dest.path) - -def wic_rm(args, native_sysroot): - """ - Remove files or directories from the vfat partition of - partitioned image. - """ - disk = Disk(args.path.image, native_sysroot) - disk.remove(args.path.part, args.path.path) - -def wic_write(args, native_sysroot): - """ - Write image to a target device. - """ - disk = Disk(args.image, native_sysroot, ('fat', 'ext', 'swap')) - disk.write(args.target, args.expand) - -def find_canned(scripts_path, file_name): - """ - Find a file either by its path or by name in the canned files dir. - - Return None if not found - """ - if os.path.exists(file_name): - return file_name - - layers_canned_wks_dir = build_canned_image_list(scripts_path) - for canned_wks_dir in layers_canned_wks_dir: - for root, dirs, files in os.walk(canned_wks_dir): - for fname in files: - if fname == file_name: - fullpath = os.path.join(canned_wks_dir, fname) - return fullpath - -def get_custom_config(boot_file): - """ - Get the custom configuration to be used for the bootloader. - - Return None if the file can't be found. - """ - # Get the scripts path of poky - scripts_path = os.path.abspath("%s/../.." % os.path.dirname(__file__)) - - cfg_file = find_canned(scripts_path, boot_file) - if cfg_file: - with open(cfg_file, "r") as f: - config = f.read() - return config diff --git a/import-layers/yocto-poky/scripts/lib/wic/filemap.py b/import-layers/yocto-poky/scripts/lib/wic/filemap.py deleted file mode 100644 index a72fa09ef..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/filemap.py +++ /dev/null @@ -1,600 +0,0 @@ -# Copyright (c) 2012 Intel, Inc. -# -# 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. - -""" -This module implements python implements a way to get file block. Two methods -are supported - the FIEMAP ioctl and the 'SEEK_HOLE / SEEK_DATA' features of -the file seek syscall. The former is implemented by the 'FilemapFiemap' class, -the latter is implemented by the 'FilemapSeek' class. Both classes provide the -same API. The 'filemap' function automatically selects which class can be used -and returns an instance of the class. -""" - -# Disable the following pylint recommendations: -# * Too many instance attributes (R0902) -# pylint: disable=R0902 - -import os -import struct -import array -import fcntl -import tempfile -import logging - -def get_block_size(file_obj): - """ - Returns block size for file object 'file_obj'. Errors are indicated by the - 'IOError' exception. - """ - # Get the block size of the host file-system for the image file by calling - # the FIGETBSZ ioctl (number 2). - binary_data = fcntl.ioctl(file_obj, 2, struct.pack('I', 0)) - bsize = struct.unpack('I', binary_data)[0] - if not bsize: - import os - stat = os.fstat(file_obj.fileno()) - if hasattr(stat, 'st_blksize'): - bsize = stat.st_blksize - else: - raise IOError("Unable to determine block size") - return bsize - -class ErrorNotSupp(Exception): - """ - An exception of this type is raised when the 'FIEMAP' or 'SEEK_HOLE' feature - is not supported either by the kernel or the file-system. - """ - pass - -class Error(Exception): - """A class for all the other exceptions raised by this module.""" - pass - - -class _FilemapBase(object): - """ - This is a base class for a couple of other classes in this module. This - class simply performs the common parts of the initialization process: opens - the image file, gets its size, etc. The 'log' parameter is the logger object - to use for printing messages. - """ - - def __init__(self, image, log=None): - """ - Initialize a class instance. The 'image' argument is full path to the - file or file object to operate on. - """ - - self._log = log - if self._log is None: - self._log = logging.getLogger(__name__) - - self._f_image_needs_close = False - - if hasattr(image, "fileno"): - self._f_image = image - self._image_path = image.name - else: - self._image_path = image - self._open_image_file() - - try: - self.image_size = os.fstat(self._f_image.fileno()).st_size - except IOError as err: - raise Error("cannot get information about file '%s': %s" - % (self._f_image.name, err)) - - try: - self.block_size = get_block_size(self._f_image) - except IOError as err: - raise Error("cannot get block size for '%s': %s" - % (self._image_path, err)) - - self.blocks_cnt = self.image_size + self.block_size - 1 - self.blocks_cnt //= self.block_size - - try: - self._f_image.flush() - except IOError as err: - raise Error("cannot flush image file '%s': %s" - % (self._image_path, err)) - - try: - os.fsync(self._f_image.fileno()), - except OSError as err: - raise Error("cannot synchronize image file '%s': %s " - % (self._image_path, err.strerror)) - - self._log.debug("opened image \"%s\"" % self._image_path) - self._log.debug("block size %d, blocks count %d, image size %d" - % (self.block_size, self.blocks_cnt, self.image_size)) - - def __del__(self): - """The class destructor which just closes the image file.""" - if self._f_image_needs_close: - self._f_image.close() - - def _open_image_file(self): - """Open the image file.""" - try: - self._f_image = open(self._image_path, 'rb') - except IOError as err: - raise Error("cannot open image file '%s': %s" - % (self._image_path, err)) - - self._f_image_needs_close = True - - def block_is_mapped(self, block): # pylint: disable=W0613,R0201 - """ - This method has has to be implemented by child classes. It returns - 'True' if block number 'block' of the image file is mapped and 'False' - otherwise. - """ - - raise Error("the method is not implemented") - - def block_is_unmapped(self, block): # pylint: disable=W0613,R0201 - """ - This method has has to be implemented by child classes. It returns - 'True' if block number 'block' of the image file is not mapped (hole) - and 'False' otherwise. - """ - - raise Error("the method is not implemented") - - def get_mapped_ranges(self, start, count): # pylint: disable=W0613,R0201 - """ - This method has has to be implemented by child classes. This is a - generator which yields ranges of mapped blocks in the file. The ranges - are tuples of 2 elements: [first, last], where 'first' is the first - mapped block and 'last' is the last mapped block. - - The ranges are yielded for the area of the file of size 'count' blocks, - starting from block 'start'. - """ - - raise Error("the method is not implemented") - - def get_unmapped_ranges(self, start, count): # pylint: disable=W0613,R0201 - """ - This method has has to be implemented by child classes. Just like - 'get_mapped_ranges()', but yields unmapped block ranges instead - (holes). - """ - - raise Error("the method is not implemented") - - -# The 'SEEK_HOLE' and 'SEEK_DATA' options of the file seek system call -_SEEK_DATA = 3 -_SEEK_HOLE = 4 - -def _lseek(file_obj, offset, whence): - """This is a helper function which invokes 'os.lseek' for file object - 'file_obj' and with specified 'offset' and 'whence'. The 'whence' - argument is supposed to be either '_SEEK_DATA' or '_SEEK_HOLE'. When - there is no more data or hole starting from 'offset', this function - returns '-1'. Otherwise the data or hole position is returned.""" - - try: - return os.lseek(file_obj.fileno(), offset, whence) - except OSError as err: - # The 'lseek' system call returns the ENXIO if there is no data or - # hole starting from the specified offset. - if err.errno == os.errno.ENXIO: - return -1 - elif err.errno == os.errno.EINVAL: - raise ErrorNotSupp("the kernel or file-system does not support " - "\"SEEK_HOLE\" and \"SEEK_DATA\"") - else: - raise - -class FilemapSeek(_FilemapBase): - """ - This class uses the 'SEEK_HOLE' and 'SEEK_DATA' to find file block mapping. - Unfortunately, the current implementation requires the caller to have write - access to the image file. - """ - - def __init__(self, image, log=None): - """Refer the '_FilemapBase' class for the documentation.""" - - # Call the base class constructor first - _FilemapBase.__init__(self, image, log) - self._log.debug("FilemapSeek: initializing") - - self._probe_seek_hole() - - def _probe_seek_hole(self): - """ - Check whether the system implements 'SEEK_HOLE' and 'SEEK_DATA'. - Unfortunately, there seems to be no clean way for detecting this, - because often the system just fakes them by just assuming that all - files are fully mapped, so 'SEEK_HOLE' always returns EOF and - 'SEEK_DATA' always returns the requested offset. - - I could not invent a better way of detecting the fake 'SEEK_HOLE' - implementation than just to create a temporary file in the same - directory where the image file resides. It would be nice to change this - to something better. - """ - - directory = os.path.dirname(self._image_path) - - try: - tmp_obj = tempfile.TemporaryFile("w+", dir=directory) - except IOError as err: - raise ErrorNotSupp("cannot create a temporary in \"%s\": %s" \ - % (directory, err)) - - try: - os.ftruncate(tmp_obj.fileno(), self.block_size) - except OSError as err: - raise ErrorNotSupp("cannot truncate temporary file in \"%s\": %s" - % (directory, err)) - - offs = _lseek(tmp_obj, 0, _SEEK_HOLE) - if offs != 0: - # We are dealing with the stub 'SEEK_HOLE' implementation which - # always returns EOF. - self._log.debug("lseek(0, SEEK_HOLE) returned %d" % offs) - raise ErrorNotSupp("the file-system does not support " - "\"SEEK_HOLE\" and \"SEEK_DATA\" but only " - "provides a stub implementation") - - tmp_obj.close() - - def block_is_mapped(self, block): - """Refer the '_FilemapBase' class for the documentation.""" - offs = _lseek(self._f_image, block * self.block_size, _SEEK_DATA) - if offs == -1: - result = False - else: - result = (offs // self.block_size == block) - - self._log.debug("FilemapSeek: block_is_mapped(%d) returns %s" - % (block, result)) - return result - - def block_is_unmapped(self, block): - """Refer the '_FilemapBase' class for the documentation.""" - return not self.block_is_mapped(block) - - def _get_ranges(self, start, count, whence1, whence2): - """ - This function implements 'get_mapped_ranges()' and - 'get_unmapped_ranges()' depending on what is passed in the 'whence1' - and 'whence2' arguments. - """ - - assert whence1 != whence2 - end = start * self.block_size - limit = end + count * self.block_size - - while True: - start = _lseek(self._f_image, end, whence1) - if start == -1 or start >= limit or start == self.image_size: - break - - end = _lseek(self._f_image, start, whence2) - if end == -1 or end == self.image_size: - end = self.blocks_cnt * self.block_size - if end > limit: - end = limit - - start_blk = start // self.block_size - end_blk = end // self.block_size - 1 - self._log.debug("FilemapSeek: yielding range (%d, %d)" - % (start_blk, end_blk)) - yield (start_blk, end_blk) - - def get_mapped_ranges(self, start, count): - """Refer the '_FilemapBase' class for the documentation.""" - self._log.debug("FilemapSeek: get_mapped_ranges(%d, %d(%d))" - % (start, count, start + count - 1)) - return self._get_ranges(start, count, _SEEK_DATA, _SEEK_HOLE) - - def get_unmapped_ranges(self, start, count): - """Refer the '_FilemapBase' class for the documentation.""" - self._log.debug("FilemapSeek: get_unmapped_ranges(%d, %d(%d))" - % (start, count, start + count - 1)) - return self._get_ranges(start, count, _SEEK_HOLE, _SEEK_DATA) - - -# Below goes the FIEMAP ioctl implementation, which is not very readable -# because it deals with the rather complex FIEMAP ioctl. To understand the -# code, you need to know the FIEMAP interface, which is documented in the -# "Documentation/filesystems/fiemap.txt" file in the Linux kernel sources. - -# Format string for 'struct fiemap' -_FIEMAP_FORMAT = "=QQLLLL" -# sizeof(struct fiemap) -_FIEMAP_SIZE = struct.calcsize(_FIEMAP_FORMAT) -# Format string for 'struct fiemap_extent' -_FIEMAP_EXTENT_FORMAT = "=QQQQQLLLL" -# sizeof(struct fiemap_extent) -_FIEMAP_EXTENT_SIZE = struct.calcsize(_FIEMAP_EXTENT_FORMAT) -# The FIEMAP ioctl number -_FIEMAP_IOCTL = 0xC020660B -# This FIEMAP ioctl flag which instructs the kernel to sync the file before -# reading the block map -_FIEMAP_FLAG_SYNC = 0x00000001 -# Size of the buffer for 'struct fiemap_extent' elements which will be used -# when invoking the FIEMAP ioctl. The larger is the buffer, the less times the -# FIEMAP ioctl will be invoked. -_FIEMAP_BUFFER_SIZE = 256 * 1024 - -class FilemapFiemap(_FilemapBase): - """ - This class provides API to the FIEMAP ioctl. Namely, it allows to iterate - over all mapped blocks and over all holes. - - This class synchronizes the image file every time it invokes the FIEMAP - ioctl in order to work-around early FIEMAP implementation kernel bugs. - """ - - def __init__(self, image, log=None): - """ - Initialize a class instance. The 'image' argument is full the file - object to operate on. - """ - - # Call the base class constructor first - _FilemapBase.__init__(self, image, log) - self._log.debug("FilemapFiemap: initializing") - - self._buf_size = _FIEMAP_BUFFER_SIZE - - # Calculate how many 'struct fiemap_extent' elements fit the buffer - self._buf_size -= _FIEMAP_SIZE - self._fiemap_extent_cnt = self._buf_size // _FIEMAP_EXTENT_SIZE - assert self._fiemap_extent_cnt > 0 - self._buf_size = self._fiemap_extent_cnt * _FIEMAP_EXTENT_SIZE - self._buf_size += _FIEMAP_SIZE - - # Allocate a mutable buffer for the FIEMAP ioctl - self._buf = array.array('B', [0] * self._buf_size) - - # Check if the FIEMAP ioctl is supported - self.block_is_mapped(0) - - def _invoke_fiemap(self, block, count): - """ - Invoke the FIEMAP ioctl for 'count' blocks of the file starting from - block number 'block'. - - The full result of the operation is stored in 'self._buf' on exit. - Returns the unpacked 'struct fiemap' data structure in form of a python - list (just like 'struct.upack()'). - """ - - if self.blocks_cnt != 0 and (block < 0 or block >= self.blocks_cnt): - raise Error("bad block number %d, should be within [0, %d]" - % (block, self.blocks_cnt)) - - # Initialize the 'struct fiemap' part of the buffer. We use the - # '_FIEMAP_FLAG_SYNC' flag in order to make sure the file is - # synchronized. The reason for this is that early FIEMAP - # implementations had many bugs related to cached dirty data, and - # synchronizing the file is a necessary work-around. - struct.pack_into(_FIEMAP_FORMAT, self._buf, 0, block * self.block_size, - count * self.block_size, _FIEMAP_FLAG_SYNC, 0, - self._fiemap_extent_cnt, 0) - - try: - fcntl.ioctl(self._f_image, _FIEMAP_IOCTL, self._buf, 1) - except IOError as err: - # Note, the FIEMAP ioctl is supported by the Linux kernel starting - # from version 2.6.28 (year 2008). - if err.errno == os.errno.EOPNOTSUPP: - errstr = "FilemapFiemap: the FIEMAP ioctl is not supported " \ - "by the file-system" - self._log.debug(errstr) - raise ErrorNotSupp(errstr) - if err.errno == os.errno.ENOTTY: - errstr = "FilemapFiemap: the FIEMAP ioctl is not supported " \ - "by the kernel" - self._log.debug(errstr) - raise ErrorNotSupp(errstr) - raise Error("the FIEMAP ioctl failed for '%s': %s" - % (self._image_path, err)) - - return struct.unpack(_FIEMAP_FORMAT, self._buf[:_FIEMAP_SIZE]) - - def block_is_mapped(self, block): - """Refer the '_FilemapBase' class for the documentation.""" - struct_fiemap = self._invoke_fiemap(block, 1) - - # The 3rd element of 'struct_fiemap' is the 'fm_mapped_extents' field. - # If it contains zero, the block is not mapped, otherwise it is - # mapped. - result = bool(struct_fiemap[3]) - self._log.debug("FilemapFiemap: block_is_mapped(%d) returns %s" - % (block, result)) - return result - - def block_is_unmapped(self, block): - """Refer the '_FilemapBase' class for the documentation.""" - return not self.block_is_mapped(block) - - def _unpack_fiemap_extent(self, index): - """ - Unpack a 'struct fiemap_extent' structure object number 'index' from - the internal 'self._buf' buffer. - """ - - offset = _FIEMAP_SIZE + _FIEMAP_EXTENT_SIZE * index - return struct.unpack(_FIEMAP_EXTENT_FORMAT, - self._buf[offset : offset + _FIEMAP_EXTENT_SIZE]) - - def _do_get_mapped_ranges(self, start, count): - """ - Implements most the functionality for the 'get_mapped_ranges()' - generator: invokes the FIEMAP ioctl, walks through the mapped extents - and yields mapped block ranges. However, the ranges may be consecutive - (e.g., (1, 100), (100, 200)) and 'get_mapped_ranges()' simply merges - them. - """ - - block = start - while block < start + count: - struct_fiemap = self._invoke_fiemap(block, count) - - mapped_extents = struct_fiemap[3] - if mapped_extents == 0: - # No more mapped blocks - return - - extent = 0 - while extent < mapped_extents: - fiemap_extent = self._unpack_fiemap_extent(extent) - - # Start of the extent - extent_start = fiemap_extent[0] - # Starting block number of the extent - extent_block = extent_start // self.block_size - # Length of the extent - extent_len = fiemap_extent[2] - # Count of blocks in the extent - extent_count = extent_len // self.block_size - - # Extent length and offset have to be block-aligned - assert extent_start % self.block_size == 0 - assert extent_len % self.block_size == 0 - - if extent_block > start + count - 1: - return - - first = max(extent_block, block) - last = min(extent_block + extent_count, start + count) - 1 - yield (first, last) - - extent += 1 - - block = extent_block + extent_count - - def get_mapped_ranges(self, start, count): - """Refer the '_FilemapBase' class for the documentation.""" - self._log.debug("FilemapFiemap: get_mapped_ranges(%d, %d(%d))" - % (start, count, start + count - 1)) - iterator = self._do_get_mapped_ranges(start, count) - first_prev, last_prev = next(iterator) - - for first, last in iterator: - if last_prev == first - 1: - last_prev = last - else: - self._log.debug("FilemapFiemap: yielding range (%d, %d)" - % (first_prev, last_prev)) - yield (first_prev, last_prev) - first_prev, last_prev = first, last - - self._log.debug("FilemapFiemap: yielding range (%d, %d)" - % (first_prev, last_prev)) - yield (first_prev, last_prev) - - def get_unmapped_ranges(self, start, count): - """Refer the '_FilemapBase' class for the documentation.""" - self._log.debug("FilemapFiemap: get_unmapped_ranges(%d, %d(%d))" - % (start, count, start + count - 1)) - hole_first = start - for first, last in self._do_get_mapped_ranges(start, count): - if first > hole_first: - self._log.debug("FilemapFiemap: yielding range (%d, %d)" - % (hole_first, first - 1)) - yield (hole_first, first - 1) - - hole_first = last + 1 - - if hole_first < start + count: - self._log.debug("FilemapFiemap: yielding range (%d, %d)" - % (hole_first, start + count - 1)) - yield (hole_first, start + count - 1) - -def filemap(image, log=None): - """ - Create and return an instance of a Filemap class - 'FilemapFiemap' or - 'FilemapSeek', depending on what the system we run on supports. If the - FIEMAP ioctl is supported, an instance of the 'FilemapFiemap' class is - returned. Otherwise, if 'SEEK_HOLE' is supported an instance of the - 'FilemapSeek' class is returned. If none of these are supported, the - function generates an 'Error' type exception. - """ - - try: - return FilemapFiemap(image, log) - except ErrorNotSupp: - return FilemapSeek(image, log) - -def sparse_copy(src_fname, dst_fname, skip=0, seek=0, - length=0, api=None): - """ - Efficiently copy sparse file to or into another file. - - src_fname: path to source file - dst_fname: path to destination file - skip: skip N bytes at thestart of src - seek: seek N bytes from the start of dst - length: read N bytes from src and write them to dst - api: FilemapFiemap or FilemapSeek object - """ - if not api: - api = filemap - fmap = api(src_fname) - try: - dst_file = open(dst_fname, 'r+b') - except IOError: - dst_file = open(dst_fname, 'wb') - if length: - dst_size = length + seek - else: - dst_size = os.path.getsize(src_fname) + seek - skip - dst_file.truncate(dst_size) - - written = 0 - for first, last in fmap.get_mapped_ranges(0, fmap.blocks_cnt): - start = first * fmap.block_size - end = (last + 1) * fmap.block_size - - if skip >= end: - continue - - if start < skip < end: - start = skip - - fmap._f_image.seek(start, os.SEEK_SET) - - written += start - skip - written - if length and written >= length: - dst_file.seek(seek + length, os.SEEK_SET) - dst_file.close() - return - - dst_file.seek(seek + start - skip, os.SEEK_SET) - - chunk_size = 1024 * 1024 - to_read = end - start - read = 0 - - while read < to_read: - if read + chunk_size > to_read: - chunk_size = to_read - read - size = chunk_size - if length and written + size > length: - size = length - written - chunk = fmap._f_image.read(size) - dst_file.write(chunk) - read += size - written += size - if written == length: - dst_file.close() - return - dst_file.close() diff --git a/import-layers/yocto-poky/scripts/lib/wic/help.py b/import-layers/yocto-poky/scripts/lib/wic/help.py deleted file mode 100644 index 842b868a5..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/help.py +++ /dev/null @@ -1,1055 +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 module implements some basic help invocation functions along -# with the bulk of the help topic text for the OE Core Image Tools. -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import subprocess -import logging - -from wic.pluginbase import PluginMgr, PLUGIN_TYPES - -logger = logging.getLogger('wic') - -def subcommand_error(args): - logger.info("invalid subcommand %s", args[0]) - - -def display_help(subcommand, subcommands): - """ - Display help for subcommand. - """ - if subcommand not in subcommands: - return False - - hlp = subcommands.get(subcommand, subcommand_error)[2] - if callable(hlp): - hlp = hlp() - pager = subprocess.Popen('less', stdin=subprocess.PIPE) - pager.communicate(hlp.encode('utf-8')) - - return True - - -def wic_help(args, usage_str, subcommands): - """ - Subcommand help dispatcher. - """ - if args.help_topic == None or not display_help(args.help_topic, subcommands): - print(usage_str) - - -def get_wic_plugins_help(): - """ - Combine wic_plugins_help with the help for every known - source plugin. - """ - result = wic_plugins_help - for plugin_type in PLUGIN_TYPES: - result += '\n\n%s PLUGINS\n\n' % plugin_type.upper() - for name, plugin in PluginMgr.get_plugins(plugin_type).items(): - result += "\n %s plugin:\n" % name - if plugin.__doc__: - result += plugin.__doc__ - else: - result += "\n %s is missing docstring\n" % plugin - return result - - -def invoke_subcommand(args, parser, main_command_usage, subcommands): - """ - Dispatch to subcommand handler borrowed from combo-layer. - Should use argparse, but has to work in 2.6. - """ - if not args.command: - logger.error("No subcommand specified, exiting") - parser.print_help() - return 1 - elif args.command == "help": - wic_help(args, main_command_usage, subcommands) - elif args.command not in subcommands: - logger.error("Unsupported subcommand %s, exiting\n", args.command) - parser.print_help() - return 1 - else: - subcmd = subcommands.get(args.command, subcommand_error) - usage = subcmd[1] - subcmd[0](args, usage) - - -## -# wic help and usage strings -## - -wic_usage = """ - - Create a customized OpenEmbedded image - - usage: wic [--version] | [--help] | [COMMAND [ARGS]] - - Current 'wic' commands are: - help Show help for command or one of the topics (see below) - create Create a new OpenEmbedded image - list List available canned images and source plugins - - Help topics: - overview wic overview - General overview of wic - plugins wic plugins - Overview and API - kickstart wic kickstart - wic kickstart reference -""" - -wic_help_usage = """ - - usage: wic help <subcommand> - - This command displays detailed help for the specified subcommand. -""" - -wic_create_usage = """ - - Create a new OpenEmbedded image - - usage: wic create <wks file or image name> [-o <DIRNAME> | --outdir <DIRNAME>] - [-e | --image-name] [-s, --skip-build-check] [-D, --debug] - [-r, --rootfs-dir] [-b, --bootimg-dir] - [-k, --kernel-dir] [-n, --native-sysroot] [-f, --build-rootfs] - [-c, --compress-with] [-m, --bmap] - - This command creates an OpenEmbedded image based on the 'OE kickstart - commands' found in the <wks file>. - - The -o option can be used to place the image in a directory with a - different name and location. - - See 'wic help create' for more detailed instructions. -""" - -wic_create_help = """ - -NAME - wic create - Create a new OpenEmbedded image - -SYNOPSIS - wic create <wks file or image name> [-o <DIRNAME> | --outdir <DIRNAME>] - [-e | --image-name] [-s, --skip-build-check] [-D, --debug] - [-r, --rootfs-dir] [-b, --bootimg-dir] - [-k, --kernel-dir] [-n, --native-sysroot] [-f, --build-rootfs] - [-c, --compress-with] [-m, --bmap] [--no-fstab-update] - -DESCRIPTION - This command creates an OpenEmbedded image based on the 'OE - kickstart commands' found in the <wks file>. - - In order to do this, wic needs to know the locations of the - various build artifacts required to build the image. - - Users can explicitly specify the build artifact locations using - the -r, -b, -k, and -n options. See below for details on where - the corresponding artifacts are typically found in a normal - OpenEmbedded build. - - Alternatively, users can use the -e option to have 'wic' determine - those locations for a given image. If the -e option is used, the - user needs to have set the appropriate MACHINE variable in - local.conf, and have sourced the build environment. - - The -e option is used to specify the name of the image to use the - artifacts from e.g. core-image-sato. - - The -r option is used to specify the path to the /rootfs dir to - use as the .wks rootfs source. - - The -b option is used to specify the path to the dir containing - the boot artifacts (e.g. /EFI or /syslinux dirs) to use as the - .wks bootimg source. - - The -k option is used to specify the path to the dir containing - the kernel to use in the .wks bootimg. - - The -n option is used to specify the path to the native sysroot - containing the tools to use to build the image. - - The -f option is used to build rootfs by running "bitbake <image>" - - The -s option is used to skip the build check. The build check is - a simple sanity check used to determine whether the user has - sourced the build environment so that the -e option can operate - correctly. If the user has specified the build artifact locations - explicitly, 'wic' assumes the user knows what he or she is doing - and skips the build check. - - The -D option is used to display debug information detailing - exactly what happens behind the scenes when a create request is - fulfilled (or not, as the case may be). It enumerates and - displays the command sequence used, and should be included in any - bug report describing unexpected results. - - When 'wic -e' is used, the locations for the build artifacts - values are determined by 'wic -e' from the output of the 'bitbake - -e' command given an image name e.g. 'core-image-minimal' and a - given machine set in local.conf. In that case, the image is - created as if the following 'bitbake -e' variables were used: - - -r: IMAGE_ROOTFS - -k: STAGING_KERNEL_DIR - -n: STAGING_DIR_NATIVE - -b: empty (plugin-specific handlers must determine this) - - If 'wic -e' is not used, the user needs to select the appropriate - value for -b (as well as -r, -k, and -n). - - The -o option can be used to place the image in a directory with a - different name and location. - - The -c option is used to specify compressor utility to compress - an image. gzip, bzip2 and xz compressors are supported. - - The -m option is used to produce .bmap file for the image. This file - can be used to flash image using bmaptool utility. - - The --no-fstab-update option is used to doesn't change fstab file. When - using this option the final fstab file will be same that in rootfs and - wic doesn't update file, e.g adding a new mount point. User can control - the fstab file content in base-files recipe. -""" - -wic_list_usage = """ - - List available OpenEmbedded images and source plugins - - usage: wic list images - wic list <image> help - wic list source-plugins - - This command enumerates the set of available canned images as well as - help for those images. It also can be used to list of available source - plugins. - - The first form enumerates all the available 'canned' images. - - The second form lists the detailed help information for a specific - 'canned' image. - - The third form enumerates all the available --sources (source - plugins). - - See 'wic help list' for more details. -""" - -wic_list_help = """ - -NAME - wic list - List available OpenEmbedded images and source plugins - -SYNOPSIS - wic list images - wic list <image> help - wic list source-plugins - -DESCRIPTION - This command enumerates the set of available canned images as well - as help for those images. It also can be used to list available - source plugins. - - The first form enumerates all the available 'canned' images. - These are actually just the set of .wks files that have been moved - into the /scripts/lib/wic/canned-wks directory). - - The second form lists the detailed help information for a specific - 'canned' image. - - The third form enumerates all the available --sources (source - plugins). The contents of a given partition are driven by code - defined in 'source plugins'. Users specify a specific plugin via - the --source parameter of the partition .wks command. Normally - this is the 'rootfs' plugin but can be any of the more specialized - sources listed by the 'list source-plugins' command. Users can - also add their own source plugins - see 'wic help plugins' for - details. -""" - -wic_ls_usage = """ - - List content of a partitioned image - - usage: wic ls <image>[:<partition>[<path>]] [--native-sysroot <path>] - - This command outputs either list of image partitions or directory contents - of vfat and ext* partitions. - - See 'wic help ls' for more detailed instructions. - -""" - -wic_ls_help = """ - -NAME - wic ls - List contents of partitioned image or partition - -SYNOPSIS - wic ls <image> - wic ls <image>:<vfat or ext* partition> - wic ls <image>:<vfat or ext* partition><path> - wic ls <image>:<vfat or ext* partition><path> --native-sysroot <path> - -DESCRIPTION - This command lists either partitions of the image or directory contents - of vfat or ext* partitions. - - The first form it lists partitions of the image. - For example: - $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic - Num Start End Size Fstype - 1 1048576 24438783 23390208 fat16 - 2 25165824 50315263 25149440 ext4 - - Second and third form list directory content of the partition: - $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1 - Volume in drive : is boot - Volume Serial Number is 2DF2-5F02 - Directory for ::/ - - efi <DIR> 2017-05-11 10:54 - startup nsh 26 2017-05-11 10:54 - vmlinuz 6922288 2017-05-11 10:54 - 3 files 6 922 314 bytes - 15 818 752 bytes free - - - $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/EFI/boot/ - Volume in drive : is boot - Volume Serial Number is 2DF2-5F02 - Directory for ::/EFI/boot - - . <DIR> 2017-05-11 10:54 - .. <DIR> 2017-05-11 10:54 - grub cfg 679 2017-05-11 10:54 - bootx64 efi 571392 2017-05-11 10:54 - 4 files 572 071 bytes - 15 818 752 bytes free - - The -n option is used to specify the path to the native sysroot - containing the tools(parted and mtools) to use. - -""" - -wic_cp_usage = """ - - Copy files and directories to the vfat or ext* partition - - usage: wic cp <src> <image>:<partition>[<path>] [--native-sysroot <path>] - - This command copies local files or directories to the vfat or ext* partitions -of partitioned image. - - See 'wic help cp' for more detailed instructions. - -""" - -wic_cp_help = """ - -NAME - wic cp - copy files and directories to the vfat or ext* partitions - -SYNOPSIS - wic cp <src> <image>:<partition> - wic cp <src> <image>:<partition><path> - wic cp <src> <image>:<partition><path> --native-sysroot <path> - -DESCRIPTION - This command copies files and directories to the vfat or ext* partition of - the partitioned image. - - The first form of it copies file or directory to the root directory of - the partition: - $ wic cp test.wks tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1 - $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1 - Volume in drive : is boot - Volume Serial Number is DB4C-FD4C - Directory for ::/ - - efi <DIR> 2017-05-24 18:15 - loader <DIR> 2017-05-24 18:15 - startup nsh 26 2017-05-24 18:15 - vmlinuz 6926384 2017-05-24 18:15 - test wks 628 2017-05-24 21:22 - 5 files 6 927 038 bytes - 15 677 440 bytes free - - The second form of the command copies file or directory to the specified directory - on the partition: - $ wic cp test tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/efi/ - $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/efi/ - Volume in drive : is boot - Volume Serial Number is DB4C-FD4C - Directory for ::/efi - - . <DIR> 2017-05-24 18:15 - .. <DIR> 2017-05-24 18:15 - boot <DIR> 2017-05-24 18:15 - test <DIR> 2017-05-24 21:27 - 4 files 0 bytes - 15 675 392 bytes free - - The -n option is used to specify the path to the native sysroot - containing the tools(parted and mtools) to use. -""" - -wic_rm_usage = """ - - Remove files or directories from the vfat or ext* partitions - - usage: wic rm <image>:<partition><path> [--native-sysroot <path>] - - This command removes files or directories from the vfat or ext* partitions of - the partitioned image. - - See 'wic help rm' for more detailed instructions. - -""" - -wic_rm_help = """ - -NAME - wic rm - remove files or directories from the vfat or ext* partitions - -SYNOPSIS - wic rm <src> <image>:<partition><path> - wic rm <src> <image>:<partition><path> --native-sysroot <path> - -DESCRIPTION - This command removes files or directories from the vfat or ext* partition of the - partitioned image: - - $ wic ls ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1 - Volume in drive : is boot - Volume Serial Number is 11D0-DE21 - Directory for ::/ - - libcom32 c32 186500 2017-06-02 15:15 - libutil c32 24148 2017-06-02 15:15 - syslinux cfg 209 2017-06-02 15:15 - vesamenu c32 27104 2017-06-02 15:15 - vmlinuz 6926384 2017-06-02 15:15 - 5 files 7 164 345 bytes - 16 582 656 bytes free - - $ wic rm ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/libutil.c32 - - $ wic ls ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1 - Volume in drive : is boot - Volume Serial Number is 11D0-DE21 - Directory for ::/ - - libcom32 c32 186500 2017-06-02 15:15 - syslinux cfg 209 2017-06-02 15:15 - vesamenu c32 27104 2017-06-02 15:15 - vmlinuz 6926384 2017-06-02 15:15 - 4 files 7 140 197 bytes - 16 607 232 bytes free - - The -n option is used to specify the path to the native sysroot - containing the tools(parted and mtools) to use. -""" - -wic_write_usage = """ - - Write image to a device - - usage: wic write <image> <target device> [--expand [rules]] [--native-sysroot <path>] - - This command writes partitioned image to a target device (USB stick, SD card etc). - - See 'wic help write' for more detailed instructions. - -""" - -wic_write_help = """ - -NAME - wic write - write an image to a device - -SYNOPSIS - wic write <image> <target> - wic write <image> <target> --expand auto - wic write <image> <target> --expand 1:100M-2:300M - wic write <image> <target> --native-sysroot <path> - -DESCRIPTION - This command writes an image to a target device (USB stick, SD card etc) - - $ wic write ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic /dev/sdb - - The --expand option is used to resize image partitions. - --expand auto expands partitions to occupy all free space available on the target device. - It's also possible to specify expansion rules in a format - <partition>:<size>[-<partition>:<size>...] for one or more partitions. - Specifying size 0 will keep partition unmodified. - Note: Resizing boot partition can result in non-bootable image for non-EFI images. It is - recommended to use size 0 for boot partition to keep image bootable. - - The --native-sysroot option is used to specify the path to the native sysroot - containing the tools(parted, resize2fs) to use. -""" - -wic_plugins_help = """ - -NAME - wic plugins - Overview and API - -DESCRIPTION - plugins allow wic functionality to be extended and specialized by - users. This section documents the plugin interface, which is - currently restricted to 'source' plugins. - - 'Source' plugins provide a mechanism to customize various aspects - of the image generation process in wic, mainly the contents of - partitions. - - Source plugins provide a mechanism for mapping values specified in - .wks files using the --source keyword to a particular plugin - implementation that populates a corresponding partition. - - A source plugin is created as a subclass of SourcePlugin (see - scripts/lib/wic/pluginbase.py) and the plugin file containing it - is added to scripts/lib/wic/plugins/source/ to make the plugin - implementation available to the wic implementation. - - Source plugins can also be implemented and added by external - layers - any plugins found in a scripts/lib/wic/plugins/source/ - directory in an external layer will also be made available. - - When the wic implementation needs to invoke a partition-specific - implementation, it looks for the plugin that has the same name as - the --source param given to that partition. For example, if the - partition is set up like this: - - part /boot --source bootimg-pcbios ... - - then the methods defined as class members of the plugin having the - matching bootimg-pcbios .name class member would be used. - - To be more concrete, here's the plugin definition that would match - a '--source bootimg-pcbios' usage, along with an example method - that would be called by the wic implementation when it needed to - invoke an implementation-specific partition-preparation function: - - class BootimgPcbiosPlugin(SourcePlugin): - name = 'bootimg-pcbios' - - @classmethod - def do_prepare_partition(self, part, ...) - - If the subclass itself doesn't implement a function, a 'default' - version in a superclass will be located and used, which is why all - plugins must be derived from SourcePlugin. - - The SourcePlugin class defines the following methods, which is the - current set of methods that can be implemented/overridden by - --source plugins. Any methods not implemented by a SourcePlugin - subclass inherit the implementations present in the SourcePlugin - class (see the SourcePlugin source for details): - - do_prepare_partition() - Called to do the actual content population for a - partition. In other words, it 'prepares' the final partition - image which will be incorporated into the disk image. - - do_post_partition() - Called after the partition is created. It is useful to add post - operations e.g. signing the partition. - - do_configure_partition() - Called before do_prepare_partition(), typically used to - create custom configuration files for a partition, for - example syslinux or grub config files. - - do_install_disk() - Called after all partitions have been prepared and assembled - into a disk image. This provides a hook to allow - finalization of a disk image, for example to write an MBR to - it. - - do_stage_partition() - Special content-staging hook called before - do_prepare_partition(), normally empty. - - Typically, a partition will just use the passed-in - parameters, for example the unmodified value of bootimg_dir. - In some cases however, things may need to be more tailored. - As an example, certain files may additionally need to be - take from bootimg_dir + /boot. This hook allows those files - to be staged in a customized fashion. Note that - get_bitbake_var() allows you to access non-standard - variables that you might want to use for these types of - situations. - - This scheme is extensible - adding more hooks is a simple matter - of adding more plugin methods to SourcePlugin and derived classes. - Please see the implementation for details. -""" - -wic_overview_help = """ - -NAME - wic overview - General overview of wic - -DESCRIPTION - The 'wic' command generates partitioned images from existing - OpenEmbedded build artifacts. Image generation is driven by - partitioning commands contained in an 'Openembedded kickstart' - (.wks) file (see 'wic help kickstart') specified either directly - on the command-line or as one of a selection of canned .wks files - (see 'wic list images'). When applied to a given set of build - artifacts, the result is an image or set of images that can be - directly written onto media and used on a particular system. - - The 'wic' command and the infrastructure it's based on is by - definition incomplete - its purpose is to allow the generation of - customized images, and as such was designed to be completely - extensible via a plugin interface (see 'wic help plugins'). - - Background and Motivation - - wic is meant to be a completely independent standalone utility - that initially provides easier-to-use and more flexible - replacements for a couple bits of existing functionality in - oe-core: directdisk.bbclass and mkefidisk.sh. The difference - between wic and those examples is that with wic the functionality - of those scripts is implemented by a general-purpose partitioning - 'language' based on Redhat kickstart syntax). - - The initial motivation and design considerations that lead to the - current tool are described exhaustively in Yocto Bug #3847 - (https://bugzilla.yoctoproject.org/show_bug.cgi?id=3847). - - Implementation and Examples - - wic can be used in two different modes, depending on how much - control the user needs in specifying the Openembedded build - artifacts that will be used in creating the image: 'raw' and - 'cooked'. - - If used in 'raw' mode, artifacts are explicitly specified via - command-line arguments (see example below). - - The more easily usable 'cooked' mode uses the current MACHINE - setting and a specified image name to automatically locate the - artifacts used to create the image. - - OE kickstart files (.wks) can of course be specified directly on - the command-line, but the user can also choose from a set of - 'canned' .wks files available via the 'wic list images' command - (example below). - - In any case, the prerequisite for generating any image is to have - the build artifacts already available. The below examples assume - the user has already build a 'core-image-minimal' for a specific - machine (future versions won't require this redundant step, but - for now that's typically how build artifacts get generated). - - The other prerequisite is to source the build environment: - - $ source oe-init-build-env - - To start out with, we'll generate an image from one of the canned - .wks files. The following generates a list of availailable - images: - - $ wic list images - mkefidisk Create an EFI disk image - directdisk Create a 'pcbios' direct disk image - - You can get more information about any of the available images by - typing 'wic list xxx help', where 'xxx' is one of the image names: - - $ wic list mkefidisk help - - Creates a partitioned EFI disk image that the user can directly dd - to boot media. - - At any time, you can get help on the 'wic' command or any - subcommand (currently 'list' and 'create'). For instance, to get - the description of 'wic create' command and its parameters: - - $ wic create - - Usage: - - Create a new OpenEmbedded image - - usage: wic create <wks file or image name> [-o <DIRNAME> | ...] - [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>] - [-e | --image-name] [-s, --skip-build-check] [-D, --debug] - [-r, --rootfs-dir] [-b, --bootimg-dir] [-k, --kernel-dir] - [-n, --native-sysroot] [-f, --build-rootfs] - - This command creates an OpenEmbedded image based on the 'OE - kickstart commands' found in the <wks file>. - - The -o option can be used to place the image in a directory - with a different name and location. - - See 'wic help create' for more detailed instructions. - ... - - As mentioned in the command, you can get even more detailed - information by adding 'help' to the above: - - $ wic help create - - So, the easiest way to create an image is to use the -e option - with a canned .wks file. To use the -e option, you need to - specify the image used to generate the artifacts and you actually - need to have the MACHINE used to build them specified in your - local.conf (these requirements aren't necessary if you aren't - using the -e options.) Below, we generate a directdisk image, - pointing the process at the core-image-minimal artifacts for the - current MACHINE: - - $ wic create directdisk -e core-image-minimal - - Checking basic build environment... - Done. - - Creating image(s)... - - Info: The new image(s) can be found here: - /var/tmp/wic/build/directdisk-201309252350-sda.direct - - The following build artifacts were used to create the image(s): - - ROOTFS_DIR: ... - BOOTIMG_DIR: ... - KERNEL_DIR: ... - NATIVE_SYSROOT: ... - - The image(s) were created using OE kickstart file: - .../scripts/lib/wic/canned-wks/directdisk.wks - - The output shows the name and location of the image created, and - so that you know exactly what was used to generate the image, each - of the artifacts and the kickstart file used. - - Similarly, you can create a 'mkefidisk' image in the same way - (notice that this example uses a different machine - because it's - using the -e option, you need to change the MACHINE in your - local.conf): - - $ wic create mkefidisk -e core-image-minimal - Checking basic build environment... - Done. - - Creating image(s)... - - Info: The new image(s) can be found here: - /var/tmp/wic/build/mkefidisk-201309260027-sda.direct - - ... - - Here's an example that doesn't take the easy way out and manually - specifies each build artifact, along with a non-canned .wks file, - and also uses the -o option to have wic create the output - somewhere other than the default /var/tmp/wic: - - $ wic create ./test.wks -o ./out --rootfs-dir - tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0-r0/rootfs - --bootimg-dir tmp/sysroots/qemux86-64/usr/share - --kernel-dir tmp/deploy/images/qemux86-64 - --native-sysroot tmp/sysroots/x86_64-linux - - Creating image(s)... - - Info: The new image(s) can be found here: - out/build/test-201507211313-sda.direct - - The following build artifacts were used to create the image(s): - ROOTFS_DIR: tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0-r0/rootfs - BOOTIMG_DIR: tmp/sysroots/qemux86-64/usr/share - KERNEL_DIR: tmp/deploy/images/qemux86-64 - NATIVE_SYSROOT: tmp/sysroots/x86_64-linux - - The image(s) were created using OE kickstart file: - ./test.wks - - Here is a content of test.wks: - - part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024 - part / --source rootfs --ondisk sda --fstype=ext3 --label platform --align 1024 - - bootloader --timeout=0 --append="rootwait rootfstype=ext3 video=vesafb vga=0x318 console=tty0" - - - Finally, here's an example of the actual partition language - commands used to generate the mkefidisk image i.e. these are the - contents of the mkefidisk.wks OE kickstart file: - - # short-description: Create an EFI disk image - # long-description: Creates a partitioned EFI disk image that the user - # can directly dd to boot media. - - part /boot --source bootimg-efi --ondisk sda --fstype=efi --active - - part / --source rootfs --ondisk sda --fstype=ext3 --label platform - - part swap --ondisk sda --size 44 --label swap1 --fstype=swap - - bootloader --timeout=10 --append="rootwait console=ttyPCH0,115200" - - You can get a complete listing and description of all the - kickstart commands available for use in .wks files from 'wic help - kickstart'. -""" - -wic_kickstart_help = """ - -NAME - wic kickstart - wic kickstart reference - -DESCRIPTION - This section provides the definitive reference to the wic - kickstart language. It also provides documentation on the list of - --source plugins available for use from the 'part' command (see - the 'Platform-specific Plugins' section below). - - The current wic implementation supports only the basic kickstart - partitioning commands: partition (or part for short) and - bootloader. - - The following is a listing of the commands, their syntax, and - meanings. The commands are based on the Fedora kickstart - documentation but with modifications to reflect wic capabilities. - - http://fedoraproject.org/wiki/Anaconda/Kickstart#part_or_partition - http://fedoraproject.org/wiki/Anaconda/Kickstart#bootloader - - Commands - - * 'part' or 'partition' - - This command creates a partition on the system and uses the - following syntax: - - part [<mountpoint>] - - The <mountpoint> is where the partition will be mounted and - must take of one of the following forms: - - /<path>: For example: /, /usr, or /home - - swap: The partition will be used as swap space. - - If a <mountpoint> is not specified the partition will be created - but will not be mounted. - - Partitions with a <mountpoint> specified will be automatically mounted. - This is achieved by wic adding entries to the fstab during image - generation. In order for a valid fstab to be generated one of the - --ondrive, --ondisk or --use-uuid partition options must be used for - each partition that specifies a mountpoint. Note that with --use-uuid - and non-root <mountpoint>, including swap, the mount program must - understand the PARTUUID syntax. This currently excludes the busybox - versions of these applications. - - - The following are supported 'part' options: - - --size: The minimum partition size. Specify an integer value - such as 500. Multipliers k, M ang G can be used. If - not specified, the size is in MB. - You do not need this option if you use --source. - - --fixed-size: Exact partition size. Value format is the same - as for --size option. This option cannot be - specified along with --size. If partition data - is larger than --fixed-size and error will be - raised when assembling disk image. - - --source: This option is a wic-specific option that names the - source of the data that will populate the - partition. The most common value for this option - is 'rootfs', but can be any value which maps to a - valid 'source plugin' (see 'wic help plugins'). - - If '--source rootfs' is used, it tells the wic - command to create a partition as large as needed - and to fill it with the contents of the root - filesystem pointed to by the '-r' wic command-line - option (or the equivalent rootfs derived from the - '-e' command-line option). The filesystem type - that will be used to create the partition is driven - by the value of the --fstype option specified for - the partition (see --fstype below). - - If --source <plugin-name>' is used, it tells the - wic command to create a partition as large as - needed and to fill with the contents of the - partition that will be generated by the specified - plugin name using the data pointed to by the '-r' - wic command-line option (or the equivalent rootfs - derived from the '-e' command-line option). - Exactly what those contents and filesystem type end - up being are dependent on the given plugin - implementation. - - If --source option is not used, the wic command - will create empty partition. --size parameter has - to be used to specify size of empty partition. - - --ondisk or --ondrive: Forces the partition to be created on - a particular disk. - - --fstype: Sets the file system type for the partition. These - apply to partitions created using '--source rootfs' (see - --source above). Valid values are: - - vfat - msdos - ext2 - ext3 - ext4 - btrfs - squashfs - swap - - --fsoptions: Specifies a free-form string of options to be - used when mounting the filesystem. This string - will be copied into the /etc/fstab file of the - installed system and should be enclosed in - quotes. If not specified, the default string is - "defaults". - - --label label: Specifies the label to give to the filesystem - to be made on the partition. If the given - label is already in use by another filesystem, - a new label is created for the partition. - - --active: Marks the partition as active. - - --align (in KBytes): This option is specific to wic and says - to start a partition on an x KBytes - boundary. - - --no-table: This option is specific to wic. Space will be - reserved for the partition and it will be - populated but it will not be added to the - partition table. It may be useful for - bootloaders. - - --exclude-path: This option is specific to wic. It excludes the given - relative path from the resulting image. If the path - ends with a slash, only the content of the directory - is omitted, not the directory itself. This option only - has an effect with the rootfs source plugin. - - --extra-space: This option is specific to wic. It adds extra - space after the space filled by the content - of the partition. The final size can go - beyond the size specified by --size. - By default, 10MB. This option cannot be used - with --fixed-size option. - - --overhead-factor: This option is specific to wic. The - size of the partition is multiplied by - this factor. It has to be greater than or - equal to 1. The default value is 1.3. - This option cannot be used with --fixed-size - option. - - --part-name: This option is specific to wic. It specifies name for GPT partitions. - - --part-type: This option is specific to wic. It specifies partition - type GUID for GPT partitions. - List of partition type GUIDS can be found here: - http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs - - --use-uuid: This option is specific to wic. It makes wic to generate - random globally unique identifier (GUID) for the partition - and use it in bootloader configuration to specify root partition. - - --uuid: This option is specific to wic. It specifies partition UUID. - It's useful if preconfigured partition UUID is added to kernel command line - in bootloader configuration before running wic. In this case .wks file can - be generated or modified to set preconfigured parition UUID using this option. - - --fsuuid: This option is specific to wic. It specifies filesystem UUID. - It's useful if preconfigured filesystem UUID is added to kernel command line - in bootloader configuration before running wic. In this case .wks file can - be generated or modified to set preconfigured filesystem UUID using this option. - - --system-id: This option is specific to wic. It specifies partition system id. It's useful - for the harware that requires non-default partition system ids. The parameter - in one byte long hex number either with 0x prefix or without it. - - --mkfs-extraopts: This option specifies extra options to pass to mkfs utility. - NOTE, that wic uses default options for some filesystems, for example - '-S 512' for mkfs.fat or '-F -i 8192' for mkfs.ext. Those options will - not take effect when --mkfs-extraopts is used. This should be taken into - account when using --mkfs-extraopts. - - * bootloader - - This command allows the user to specify various bootloader - options. The following are supported 'bootloader' options: - - --timeout: Specifies the number of seconds before the - bootloader times out and boots the default option. - - --append: Specifies kernel parameters. These will be added to - bootloader command-line - for example, the syslinux - APPEND or grub kernel command line. - - --configfile: Specifies a user defined configuration file for - the bootloader. This file must be located in the - canned-wks folder or could be the full path to the - file. Using this option will override any other - bootloader option. - - Note that bootloader functionality and boot partitions are - implemented by the various --source plugins that implement - bootloader functionality; the bootloader command essentially - provides a means of modifying bootloader configuration. - - * include - - This command allows the user to include the content of .wks file - into original .wks file. - - Command uses the following syntax: - - include <file> - - The <file> is either path to the file or its name. If name is - specified wic will try to find file in the directories with canned - .wks files. - -""" - -wic_help_help = """ -NAME - wic help - display a help topic - -DESCRIPTION - Specify a help topic to display it. Topics are shown above. -""" diff --git a/import-layers/yocto-poky/scripts/lib/wic/ksparser.py b/import-layers/yocto-poky/scripts/lib/wic/ksparser.py deleted file mode 100644 index e590b2fe3..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/ksparser.py +++ /dev/null @@ -1,235 +0,0 @@ -#!/usr/bin/env python -tt -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2016 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# DESCRIPTION -# This module provides parser for kickstart format -# -# AUTHORS -# Ed Bartosh <ed.bartosh> (at] linux.intel.com> - -"""Kickstart parser module.""" - -import os -import shlex -import logging - -from argparse import ArgumentParser, ArgumentError, ArgumentTypeError - -from wic.engine import find_canned -from wic.partition import Partition - -logger = logging.getLogger('wic') - -class KickStartError(Exception): - """Custom exception.""" - pass - -class KickStartParser(ArgumentParser): - """ - This class overwrites error method to throw exception - instead of producing usage message(default argparse behavior). - """ - def error(self, message): - raise ArgumentError(None, message) - -def sizetype(arg): - """ - Custom type for ArgumentParser - Converts size string in <num>[K|k|M|G] format into the integer value - """ - if arg.isdigit(): - return int(arg) * 1024 - - if not arg[:-1].isdigit(): - raise ArgumentTypeError("Invalid size: %r" % arg) - - size = int(arg[:-1]) - if arg.endswith("k") or arg.endswith("K"): - return size - if arg.endswith("M"): - return size * 1024 - if arg.endswith("G"): - return size * 1024 * 1024 - - raise ArgumentTypeError("Invalid size: %r" % arg) - -def overheadtype(arg): - """ - Custom type for ArgumentParser - Converts overhead string to float and checks if it's bigger than 1.0 - """ - try: - result = float(arg) - except ValueError: - raise ArgumentTypeError("Invalid value: %r" % arg) - - if result < 1.0: - raise ArgumentTypeError("Overhead factor should be > 1.0" % arg) - - return result - -def cannedpathtype(arg): - """ - Custom type for ArgumentParser - Tries to find file in the list of canned wks paths - """ - scripts_path = os.path.abspath(os.path.dirname(__file__) + '../../..') - result = find_canned(scripts_path, arg) - if not result: - raise ArgumentTypeError("file not found: %s" % arg) - return result - -def systemidtype(arg): - """ - Custom type for ArgumentParser - Checks if the argument sutisfies system id requirements, - i.e. if it's one byte long integer > 0 - """ - error = "Invalid system type: %s. must be hex "\ - "between 0x1 and 0xFF" % arg - try: - result = int(arg, 16) - except ValueError: - raise ArgumentTypeError(error) - - if result <= 0 or result > 0xff: - raise ArgumentTypeError(error) - - return arg - -class KickStart(): - """Kickstart parser implementation.""" - - DEFAULT_EXTRA_SPACE = 10*1024 - DEFAULT_OVERHEAD_FACTOR = 1.3 - - def __init__(self, confpath): - - self.partitions = [] - self.bootloader = None - self.lineno = 0 - self.partnum = 0 - - parser = KickStartParser() - subparsers = parser.add_subparsers() - - part = subparsers.add_parser('part') - part.add_argument('mountpoint', nargs='?') - part.add_argument('--active', action='store_true') - part.add_argument('--align', type=int) - part.add_argument('--exclude-path', nargs='+') - part.add_argument("--extra-space", type=sizetype) - part.add_argument('--fsoptions', dest='fsopts') - part.add_argument('--fstype', default='vfat', - choices=('ext2', 'ext3', 'ext4', 'btrfs', - 'squashfs', 'vfat', 'msdos', 'swap')) - part.add_argument('--mkfs-extraopts', default='') - part.add_argument('--label') - part.add_argument('--no-table', action='store_true') - part.add_argument('--ondisk', '--ondrive', dest='disk', default='sda') - part.add_argument("--overhead-factor", type=overheadtype) - part.add_argument('--part-name') - part.add_argument('--part-type') - part.add_argument('--rootfs-dir') - - # --size and --fixed-size cannot be specified together; options - # ----extra-space and --overhead-factor should also raise a parser - # --error, but since nesting mutually exclusive groups does not work, - # ----extra-space/--overhead-factor are handled later - sizeexcl = part.add_mutually_exclusive_group() - sizeexcl.add_argument('--size', type=sizetype, default=0) - sizeexcl.add_argument('--fixed-size', type=sizetype, default=0) - - part.add_argument('--source') - part.add_argument('--sourceparams') - part.add_argument('--system-id', type=systemidtype) - part.add_argument('--use-uuid', action='store_true') - part.add_argument('--uuid') - part.add_argument('--fsuuid') - - bootloader = subparsers.add_parser('bootloader') - bootloader.add_argument('--append') - bootloader.add_argument('--configfile') - bootloader.add_argument('--ptable', choices=('msdos', 'gpt'), - default='msdos') - bootloader.add_argument('--timeout', type=int) - bootloader.add_argument('--source') - - include = subparsers.add_parser('include') - include.add_argument('path', type=cannedpathtype) - - self._parse(parser, confpath) - if not self.bootloader: - logger.warning('bootloader config not specified, using defaults\n') - self.bootloader = bootloader.parse_args([]) - - def _parse(self, parser, confpath): - """ - Parse file in .wks format using provided parser. - """ - with open(confpath) as conf: - lineno = 0 - for line in conf: - line = line.strip() - lineno += 1 - if line and line[0] != '#': - try: - line_args = shlex.split(line) - parsed = parser.parse_args(line_args) - except ArgumentError as err: - raise KickStartError('%s:%d: %s' % \ - (confpath, lineno, err)) - if line.startswith('part'): - # SquashFS does not support UUID - if parsed.fstype == 'squashfs' and parsed.use_uuid: - err = "%s:%d: SquashFS does not support UUID" \ - % (confpath, lineno) - raise KickStartError(err) - # using ArgumentParser one cannot easily tell if option - # was passed as argument, if said option has a default - # value; --overhead-factor/--extra-space cannot be used - # with --fixed-size, so at least detect when these were - # passed with non-0 values ... - if parsed.fixed_size: - if parsed.overhead_factor or parsed.extra_space: - err = "%s:%d: arguments --overhead-factor and --extra-space not "\ - "allowed with argument --fixed-size" \ - % (confpath, lineno) - raise KickStartError(err) - else: - # ... and provide defaults if not using - # --fixed-size iff given option was not used - # (again, one cannot tell if option was passed but - # with value equal to 0) - if '--overhead-factor' not in line_args: - parsed.overhead_factor = self.DEFAULT_OVERHEAD_FACTOR - if '--extra-space' not in line_args: - parsed.extra_space = self.DEFAULT_EXTRA_SPACE - - self.partnum += 1 - self.partitions.append(Partition(parsed, self.partnum)) - elif line.startswith('include'): - self._parse(parser, parsed.path) - elif line.startswith('bootloader'): - if not self.bootloader: - self.bootloader = parsed - else: - err = "%s:%d: more than one bootloader specified" \ - % (confpath, lineno) - raise KickStartError(err) diff --git a/import-layers/yocto-poky/scripts/lib/wic/misc.py b/import-layers/yocto-poky/scripts/lib/wic/misc.py deleted file mode 100644 index ee888b478..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/misc.py +++ /dev/null @@ -1,263 +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 module provides a place to collect various wic-related utils -# for the OpenEmbedded Image Tools. -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# -"""Miscellaneous functions.""" - -import logging -import os -import re -import subprocess - -from collections import defaultdict -from distutils import spawn - -from wic import WicError - -logger = logging.getLogger('wic') - -# executable -> recipe pairs for exec_native_cmd -NATIVE_RECIPES = {"bmaptool": "bmap-tools", - "grub-mkimage": "grub-efi", - "isohybrid": "syslinux", - "mcopy": "mtools", - "mdel" : "mtools", - "mdeltree" : "mtools", - "mdir" : "mtools", - "mkdosfs": "dosfstools", - "mkisofs": "cdrtools", - "mkfs.btrfs": "btrfs-tools", - "mkfs.ext2": "e2fsprogs", - "mkfs.ext3": "e2fsprogs", - "mkfs.ext4": "e2fsprogs", - "mkfs.vfat": "dosfstools", - "mksquashfs": "squashfs-tools", - "mkswap": "util-linux", - "mmd": "mtools", - "parted": "parted", - "sfdisk": "util-linux", - "sgdisk": "gptfdisk", - "syslinux": "syslinux" - } - -def runtool(cmdln_or_args): - """ wrapper for most of the subprocess calls - input: - cmdln_or_args: can be both args and cmdln str (shell=True) - return: - rc, output - """ - if isinstance(cmdln_or_args, list): - cmd = cmdln_or_args[0] - shell = False - else: - import shlex - cmd = shlex.split(cmdln_or_args)[0] - shell = True - - sout = subprocess.PIPE - serr = subprocess.STDOUT - - try: - process = subprocess.Popen(cmdln_or_args, stdout=sout, - stderr=serr, shell=shell) - sout, serr = process.communicate() - # combine stdout and stderr, filter None out and decode - out = ''.join([out.decode('utf-8') for out in [sout, serr] if out]) - except OSError as err: - if err.errno == 2: - # [Errno 2] No such file or directory - raise WicError('Cannot run command: %s, lost dependency?' % cmd) - else: - raise # relay - - return process.returncode, out - -def _exec_cmd(cmd_and_args, as_shell=False): - """ - Execute command, catching stderr, stdout - - Need to execute as_shell if the command uses wildcards - """ - logger.debug("_exec_cmd: %s", cmd_and_args) - args = cmd_and_args.split() - logger.debug(args) - - if as_shell: - ret, out = runtool(cmd_and_args) - else: - ret, out = runtool(args) - out = out.strip() - if ret != 0: - raise WicError("_exec_cmd: %s returned '%s' instead of 0\noutput: %s" % \ - (cmd_and_args, ret, out)) - - logger.debug("_exec_cmd: output for %s (rc = %d): %s", - cmd_and_args, ret, out) - - return ret, out - - -def exec_cmd(cmd_and_args, as_shell=False): - """ - Execute command, return output - """ - return _exec_cmd(cmd_and_args, as_shell)[1] - - -def exec_native_cmd(cmd_and_args, native_sysroot, pseudo=""): - """ - Execute native command, catching stderr, stdout - - Need to execute as_shell if the command uses wildcards - - Always need to execute native commands as_shell - """ - # The reason -1 is used is because there may be "export" commands. - args = cmd_and_args.split(';')[-1].split() - logger.debug(args) - - if pseudo: - cmd_and_args = pseudo + cmd_and_args - - native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin" % \ - (native_sysroot, native_sysroot, native_sysroot) - - native_cmd_and_args = "export PATH=%s:$PATH;%s" % \ - (native_paths, cmd_and_args) - logger.debug("exec_native_cmd: %s", native_cmd_and_args) - - # If the command isn't in the native sysroot say we failed. - if spawn.find_executable(args[0], native_paths): - ret, out = _exec_cmd(native_cmd_and_args, True) - else: - ret = 127 - out = "can't find native executable %s in %s" % (args[0], native_paths) - - prog = args[0] - # shell command-not-found - if ret == 127 \ - or (pseudo and ret == 1 and out == "Can't find '%s' in $PATH." % prog): - msg = "A native program %s required to build the image "\ - "was not found (see details above).\n\n" % prog - recipe = NATIVE_RECIPES.get(prog) - if recipe: - msg += "Please make sure wic-tools have %s-native in its DEPENDS, "\ - "build it with 'bitbake wic-tools' and try again.\n" % recipe - else: - msg += "Wic failed to find a recipe to build native %s. Please "\ - "file a bug against wic.\n" % prog - raise WicError(msg) - - return ret, out - -BOOTDD_EXTRA_SPACE = 16384 - -class BitbakeVars(defaultdict): - """ - Container for Bitbake variables. - """ - def __init__(self): - defaultdict.__init__(self, dict) - - # default_image and vars_dir attributes should be set from outside - self.default_image = None - self.vars_dir = None - - def _parse_line(self, line, image, matcher=re.compile(r"^([a-zA-Z0-9\-_+./~]+)=(.*)")): - """ - Parse one line from bitbake -e output or from .env file. - Put result key-value pair into the storage. - """ - if "=" not in line: - return - match = matcher.match(line) - if not match: - return - key, val = match.groups() - self[image][key] = val.strip('"') - - def get_var(self, var, image=None, cache=True): - """ - Get bitbake variable from 'bitbake -e' output or from .env file. - This is a lazy method, i.e. it runs bitbake or parses file only when - only when variable is requested. It also caches results. - """ - if not image: - image = self.default_image - - if image not in self: - if image and self.vars_dir: - fname = os.path.join(self.vars_dir, image + '.env') - if os.path.isfile(fname): - # parse .env file - with open(fname) as varsfile: - for line in varsfile: - self._parse_line(line, image) - else: - print("Couldn't get bitbake variable from %s." % fname) - print("File %s doesn't exist." % fname) - return - else: - # Get bitbake -e output - cmd = "bitbake -e" - if image: - cmd += " %s" % image - - log_level = logger.getEffectiveLevel() - logger.setLevel(logging.INFO) - ret, lines = _exec_cmd(cmd) - logger.setLevel(log_level) - - if ret: - logger.error("Couldn't get '%s' output.", cmd) - logger.error("Bitbake failed with error:\n%s\n", lines) - return - - # Parse bitbake -e output - for line in lines.split('\n'): - self._parse_line(line, image) - - # Make first image a default set of variables - if cache: - images = [key for key in self if key] - if len(images) == 1: - self[None] = self[image] - - result = self[image].get(var) - if not cache: - self.pop(image, None) - - return result - -# Create BB_VARS singleton -BB_VARS = BitbakeVars() - -def get_bitbake_var(var, image=None, cache=True): - """ - Provide old get_bitbake_var API by wrapping - get_var method of BB_VARS singleton. - """ - return BB_VARS.get_var(var, image, cache) diff --git a/import-layers/yocto-poky/scripts/lib/wic/partition.py b/import-layers/yocto-poky/scripts/lib/wic/partition.py deleted file mode 100644 index 3fe5c4e26..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/partition.py +++ /dev/null @@ -1,425 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2013-2016 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 module provides the OpenEmbedded partition object definitions. -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# Ed Bartosh <ed.bartosh> (at] linux.intel.com> - -import logging -import os -import uuid - -from wic import WicError -from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var -from wic.pluginbase import PluginMgr - -logger = logging.getLogger('wic') - -class Partition(): - - def __init__(self, args, lineno): - self.args = args - self.active = args.active - self.align = args.align - self.disk = args.disk - self.device = None - self.extra_space = args.extra_space - self.exclude_path = args.exclude_path - self.fsopts = args.fsopts - self.fstype = args.fstype - self.label = args.label - self.mkfs_extraopts = args.mkfs_extraopts - self.mountpoint = args.mountpoint - self.no_table = args.no_table - self.num = None - self.overhead_factor = args.overhead_factor - self.part_name = args.part_name - self.part_type = args.part_type - self.rootfs_dir = args.rootfs_dir - self.size = args.size - self.fixed_size = args.fixed_size - self.source = args.source - self.sourceparams = args.sourceparams - self.system_id = args.system_id - self.use_uuid = args.use_uuid - self.uuid = args.uuid - self.fsuuid = args.fsuuid - - self.lineno = lineno - self.source_file = "" - self.sourceparams_dict = {} - - def get_extra_block_count(self, current_blocks): - """ - The --size param is reflected in self.size (in kB), and we already - have current_blocks (1k) blocks, calculate and return the - number of (1k) blocks we need to add to get to --size, 0 if - we're already there or beyond. - """ - logger.debug("Requested partition size for %s: %d", - self.mountpoint, self.size) - - if not self.size: - return 0 - - requested_blocks = self.size - - logger.debug("Requested blocks %d, current_blocks %d", - requested_blocks, current_blocks) - - if requested_blocks > current_blocks: - return requested_blocks - current_blocks - else: - return 0 - - def get_rootfs_size(self, actual_rootfs_size=0): - """ - Calculate the required size of rootfs taking into consideration - --size/--fixed-size flags as well as overhead and extra space, as - specified in kickstart file. Raises an error if the - `actual_rootfs_size` is larger than fixed-size rootfs. - - """ - if self.fixed_size: - rootfs_size = self.fixed_size - if actual_rootfs_size > rootfs_size: - raise WicError("Actual rootfs size (%d kB) is larger than " - "allowed size %d kB" % - (actual_rootfs_size, rootfs_size)) - else: - extra_blocks = self.get_extra_block_count(actual_rootfs_size) - if extra_blocks < self.extra_space: - extra_blocks = self.extra_space - - rootfs_size = actual_rootfs_size + extra_blocks - rootfs_size *= self.overhead_factor - - logger.debug("Added %d extra blocks to %s to get to %d total blocks", - extra_blocks, self.mountpoint, rootfs_size) - - return rootfs_size - - @property - def disk_size(self): - """ - Obtain on-disk size of partition taking into consideration - --size/--fixed-size options. - - """ - return self.fixed_size if self.fixed_size else self.size - - def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Prepare content for individual partitions, depending on - partition command parameters. - """ - if not self.source: - if not self.size and not self.fixed_size: - raise WicError("The %s partition has a size of zero. Please " - "specify a non-zero --size/--fixed-size for that " - "partition." % self.mountpoint) - - if self.fstype == "swap": - self.prepare_swap_partition(cr_workdir, oe_builddir, - native_sysroot) - self.source_file = "%s/fs.%s" % (cr_workdir, self.fstype) - else: - if self.fstype == 'squashfs': - raise WicError("It's not possible to create empty squashfs " - "partition '%s'" % (self.mountpoint)) - - rootfs = "%s/fs_%s.%s.%s" % (cr_workdir, self.label, - self.lineno, self.fstype) - if os.path.isfile(rootfs): - os.remove(rootfs) - - prefix = "ext" if self.fstype.startswith("ext") else self.fstype - method = getattr(self, "prepare_empty_partition_" + prefix) - method(rootfs, oe_builddir, native_sysroot) - self.source_file = rootfs - return - - plugins = PluginMgr.get_plugins('source') - - if self.source not in plugins: - raise WicError("The '%s' --source specified for %s doesn't exist.\n\t" - "See 'wic list source-plugins' for a list of available" - " --sources.\n\tSee 'wic help source-plugins' for " - "details on adding a new source plugin." % - (self.source, self.mountpoint)) - - srcparams_dict = {} - if self.sourceparams: - # Split sourceparams string of the form key1=val1[,key2=val2,...] - # into a dict. Also accepts valueless keys i.e. without = - splitted = self.sourceparams.split(',') - srcparams_dict = dict(par.split('=') for par in splitted if par) - - plugin = PluginMgr.get_plugins('source')[self.source] - plugin.do_configure_partition(self, srcparams_dict, creator, - cr_workdir, oe_builddir, bootimg_dir, - kernel_dir, native_sysroot) - plugin.do_stage_partition(self, srcparams_dict, creator, - cr_workdir, oe_builddir, bootimg_dir, - kernel_dir, native_sysroot) - plugin.do_prepare_partition(self, srcparams_dict, creator, - cr_workdir, oe_builddir, bootimg_dir, - kernel_dir, rootfs_dir, native_sysroot) - plugin.do_post_partition(self, srcparams_dict, creator, - cr_workdir, oe_builddir, bootimg_dir, - kernel_dir, rootfs_dir, native_sysroot) - - # further processing required Partition.size to be an integer, make - # sure that it is one - if not isinstance(self.size, int): - raise WicError("Partition %s internal size is not an integer. " - "This a bug in source plugin %s and needs to be fixed." % - (self.mountpoint, self.source)) - - if self.fixed_size and self.size > self.fixed_size: - raise WicError("File system image of partition %s is " - "larger (%d kB) than its allowed size %d kB" % - (self.mountpoint, self.size, self.fixed_size)) - - def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir, - native_sysroot, real_rootfs = True): - """ - Prepare content for a rootfs partition i.e. create a partition - and fill it from a /rootfs dir. - - Currently handles ext2/3/4, btrfs, vfat and squashfs. - """ - p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) - p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR", - "%s/../pseudo" % get_bitbake_var("IMAGE_ROOTFS")) - p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir) - p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1") - pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix - pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % p_localstatedir - pseudo += "export PSEUDO_PASSWD=%s;" % p_passwd - pseudo += "export PSEUDO_NOSYMLINKEXP=%s;" % p_nosymlinkexp - pseudo += "%s " % get_bitbake_var("FAKEROOTCMD") - - rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label, - self.lineno, self.fstype) - if os.path.isfile(rootfs): - os.remove(rootfs) - - # Get rootfs size from bitbake variable if it's not set in .ks file - if not self.size and real_rootfs: - # 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') - if rsize_bb: - logger.warning('overhead-factor was specified, but size was not,' - ' so bitbake variables will be used for the size.' - ' In this case both IMAGE_OVERHEAD_FACTOR and ' - '--overhead-factor will be applied') - self.size = int(round(float(rsize_bb))) - - prefix = "ext" if self.fstype.startswith("ext") else self.fstype - method = getattr(self, "prepare_rootfs_" + prefix) - method(rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo) - self.source_file = rootfs - - # get the rootfs size in the right units for kickstart (kB) - du_cmd = "du -Lbks %s" % rootfs - out = exec_cmd(du_cmd) - self.size = int(out.split()[0]) - - def prepare_rootfs_ext(self, rootfs, oe_builddir, rootfs_dir, - native_sysroot, pseudo): - """ - Prepare content for an ext2/3/4 rootfs partition. - """ - du_cmd = "du -ks %s" % rootfs_dir - out = exec_cmd(du_cmd) - actual_rootfs_size = int(out.split()[0]) - - rootfs_size = self.get_rootfs_size(actual_rootfs_size) - - with open(rootfs, 'w') as sparse: - os.ftruncate(sparse.fileno(), rootfs_size * 1024) - - extraopts = self.mkfs_extraopts or "-F -i 8192" - - label_str = "" - if self.label: - label_str = "-L %s" % self.label - - mkfs_cmd = "mkfs.%s %s %s %s -U %s -d %s" % \ - (self.fstype, extraopts, rootfs, label_str, self.fsuuid, rootfs_dir) - exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) - - mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs) - exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) - - def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir, - native_sysroot, pseudo): - """ - Prepare content for a btrfs rootfs partition. - """ - du_cmd = "du -ks %s" % rootfs_dir - out = exec_cmd(du_cmd) - actual_rootfs_size = int(out.split()[0]) - - rootfs_size = self.get_rootfs_size(actual_rootfs_size) - - with open(rootfs, 'w') as sparse: - os.ftruncate(sparse.fileno(), rootfs_size * 1024) - - label_str = "" - if self.label: - label_str = "-L %s" % self.label - - mkfs_cmd = "mkfs.%s -b %d -r %s %s %s -U %s %s" % \ - (self.fstype, rootfs_size * 1024, rootfs_dir, label_str, - self.mkfs_extraopts, self.fsuuid, rootfs) - exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo) - - def prepare_rootfs_msdos(self, rootfs, oe_builddir, rootfs_dir, - native_sysroot, pseudo): - """ - Prepare content for a msdos/vfat rootfs partition. - """ - du_cmd = "du -bks %s" % rootfs_dir - out = exec_cmd(du_cmd) - blocks = int(out.split()[0]) - - rootfs_size = self.get_rootfs_size(blocks) - - label_str = "-n boot" - if self.label: - label_str = "-n %s" % self.label - - size_str = "" - if self.fstype == 'msdos': - size_str = "-F 16" # FAT 16 - - extraopts = self.mkfs_extraopts or '-S 512' - - dosfs_cmd = "mkdosfs %s -i %s %s %s -C %s %d" % \ - (label_str, self.fsuuid, size_str, extraopts, rootfs, - max(8250, rootfs_size)) - exec_native_cmd(dosfs_cmd, native_sysroot) - - mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir) - exec_native_cmd(mcopy_cmd, native_sysroot) - - chmod_cmd = "chmod 644 %s" % rootfs - exec_cmd(chmod_cmd) - - prepare_rootfs_vfat = prepare_rootfs_msdos - - def prepare_rootfs_squashfs(self, rootfs, oe_builddir, rootfs_dir, - native_sysroot, pseudo): - """ - Prepare content for a squashfs rootfs partition. - """ - extraopts = self.mkfs_extraopts or '-noappend' - squashfs_cmd = "mksquashfs %s %s %s" % \ - (rootfs_dir, rootfs, extraopts) - exec_native_cmd(squashfs_cmd, native_sysroot, pseudo=pseudo) - - def prepare_empty_partition_ext(self, rootfs, oe_builddir, - native_sysroot): - """ - Prepare an empty ext2/3/4 partition. - """ - size = self.disk_size - with open(rootfs, 'w') as sparse: - os.ftruncate(sparse.fileno(), size * 1024) - - extraopts = self.mkfs_extraopts or "-i 8192" - - label_str = "" - if self.label: - label_str = "-L %s" % self.label - - mkfs_cmd = "mkfs.%s -F %s %s -U %s %s" % \ - (self.fstype, extraopts, label_str, self.fsuuid, rootfs) - exec_native_cmd(mkfs_cmd, native_sysroot) - - def prepare_empty_partition_btrfs(self, rootfs, oe_builddir, - native_sysroot): - """ - Prepare an empty btrfs partition. - """ - size = self.disk_size - with open(rootfs, 'w') as sparse: - os.ftruncate(sparse.fileno(), size * 1024) - - label_str = "" - if self.label: - label_str = "-L %s" % self.label - - mkfs_cmd = "mkfs.%s -b %d %s -U %s %s %s" % \ - (self.fstype, self.size * 1024, label_str, self.fsuuid, - self.mkfs_extraopts, rootfs) - exec_native_cmd(mkfs_cmd, native_sysroot) - - def prepare_empty_partition_msdos(self, rootfs, oe_builddir, - native_sysroot): - """ - Prepare an empty vfat partition. - """ - blocks = self.disk_size - - label_str = "-n boot" - if self.label: - label_str = "-n %s" % self.label - - size_str = "" - if self.fstype == 'msdos': - size_str = "-F 16" # FAT 16 - - extraopts = self.mkfs_extraopts or '-S 512' - - dosfs_cmd = "mkdosfs %s -i %s %s %s -C %s %d" % \ - (label_str, self.fsuuid, extraopts, size_str, rootfs, - blocks) - - exec_native_cmd(dosfs_cmd, native_sysroot) - - chmod_cmd = "chmod 644 %s" % rootfs - exec_cmd(chmod_cmd) - - prepare_empty_partition_vfat = prepare_empty_partition_msdos - - def prepare_swap_partition(self, cr_workdir, oe_builddir, native_sysroot): - """ - Prepare a swap partition. - """ - path = "%s/fs.%s" % (cr_workdir, self.fstype) - - with open(path, 'w') as sparse: - os.ftruncate(sparse.fileno(), self.size * 1024) - - label_str = "" - if self.label: - label_str = "-L %s" % self.label - - mkswap_cmd = "mkswap %s -U %s %s" % (label_str, self.fsuuid, path) - exec_native_cmd(mkswap_cmd, native_sysroot) diff --git a/import-layers/yocto-poky/scripts/lib/wic/pluginbase.py b/import-layers/yocto-poky/scripts/lib/wic/pluginbase.py deleted file mode 100644 index 686d2fee3..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/pluginbase.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python -tt -# -# Copyright (c) 2011 Intel, Inc. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; version 2 of the License -# -# 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., 59 -# Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -__all__ = ['ImagerPlugin', 'SourcePlugin'] - -import os -import logging - -from collections import defaultdict -from importlib.machinery import SourceFileLoader - -from wic import WicError -from wic.misc import get_bitbake_var - -PLUGIN_TYPES = ["imager", "source"] - -SCRIPTS_PLUGIN_DIR = "scripts/lib/wic/plugins" - -logger = logging.getLogger('wic') - -PLUGINS = defaultdict(dict) - -class PluginMgr: - _plugin_dirs = [] - - @classmethod - def get_plugins(cls, ptype): - """Get dictionary of <plugin_name>:<class> pairs.""" - if ptype not in PLUGIN_TYPES: - raise WicError('%s is not valid plugin type' % ptype) - - # collect plugin directories - if not cls._plugin_dirs: - cls._plugin_dirs = [os.path.join(os.path.dirname(__file__), 'plugins')] - layers = get_bitbake_var("BBLAYERS") or '' - for layer_path in layers.split(): - path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR) - path = os.path.abspath(os.path.expanduser(path)) - if path not in cls._plugin_dirs and os.path.isdir(path): - cls._plugin_dirs.insert(0, path) - - if ptype not in PLUGINS: - # load all ptype plugins - for pdir in cls._plugin_dirs: - ppath = os.path.join(pdir, ptype) - if os.path.isdir(ppath): - for fname in os.listdir(ppath): - if fname.endswith('.py'): - mname = fname[:-3] - mpath = os.path.join(ppath, fname) - logger.debug("loading plugin module %s", mpath) - SourceFileLoader(mname, mpath).load_module() - - return PLUGINS.get(ptype) - -class PluginMeta(type): - def __new__(cls, name, bases, attrs): - class_type = type.__new__(cls, name, bases, attrs) - if 'name' in attrs: - PLUGINS[class_type.wic_plugin_type][attrs['name']] = class_type - - return class_type - -class ImagerPlugin(metaclass=PluginMeta): - wic_plugin_type = "imager" - - def do_create(self): - raise WicError("Method %s.do_create is not implemented" % - self.__class__.__name__) - -class SourcePlugin(metaclass=PluginMeta): - wic_plugin_type = "source" - """ - The methods that can be implemented by --source plugins. - - Any methods not implemented in a subclass inherit these. - """ - - @classmethod - def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Called after all partitions have been prepared and assembled into a - disk image. This provides a hook to allow finalization of a - disk image e.g. to write an MBR to it. - """ - logger.debug("SourcePlugin: do_install_disk: disk: %s", disk_name) - - @classmethod - def do_stage_partition(cls, part, source_params, creator, cr_workdir, - oe_builddir, bootimg_dir, kernel_dir, - native_sysroot): - """ - Special content staging hook called before do_prepare_partition(), - normally empty. - - Typically, a partition will just use the passed-in parame e.g - straight bootimg_dir, etc, but in some cases, things need to - be more tailored e.g. to use a deploy dir + /boot, etc. This - hook allows those files to be staged in a customized fashion. - Not that get_bitbake_var() allows you to acces non-standard - variables that you might want to use for this. - """ - logger.debug("SourcePlugin: do_stage_partition: part: %s", part) - - @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(), typically used to create - custom configuration files for a partition, for example - syslinux or grub config files. - """ - logger.debug("SourcePlugin: do_configure_partition: part: %s", part) - - @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 i.e. it - 'prepares' the partition to be incorporated into the image. - """ - logger.debug("SourcePlugin: do_prepare_partition: part: %s", part) - - @classmethod - def do_post_partition(cls, part, source_params, creator, cr_workdir, - oe_builddir, bootimg_dir, kernel_dir, rootfs_dir, - native_sysroot): - """ - Called after the partition is created. It is useful to add post - operations e.g. security signing the partition. - """ - logger.debug("SourcePlugin: do_post_partition: part: %s", part) diff --git a/import-layers/yocto-poky/scripts/lib/wic/plugins/imager/direct.py b/import-layers/yocto-poky/scripts/lib/wic/plugins/imager/direct.py deleted file mode 100644 index 1fa6b917e..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/plugins/imager/direct.py +++ /dev/null @@ -1,607 +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' imager plugin class for 'wic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import logging -import os -import random -import shutil -import tempfile -import uuid - -from time import strftime - -from oe.path import copyhardlinktree - -from wic import WicError -from wic.filemap import sparse_copy -from wic.ksparser import KickStart, KickStartError -from wic.pluginbase import PluginMgr, ImagerPlugin -from wic.misc import get_bitbake_var, exec_cmd, exec_native_cmd - -logger = logging.getLogger('wic') - -class DirectPlugin(ImagerPlugin): - """ - Install a system into a file containing a partitioned disk image. - - 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. - """ - name = 'direct' - - def __init__(self, wks_file, rootfs_dir, bootimg_dir, kernel_dir, - native_sysroot, oe_builddir, options): - try: - self.ks = KickStart(wks_file) - except KickStartError as err: - raise WicError(str(err)) - - # parse possible 'rootfs=name' items - self.rootfs_dir = dict(rdir.split('=') for rdir in rootfs_dir.split(' ')) - self.replaced_rootfs_paths = {} - self.bootimg_dir = bootimg_dir - self.kernel_dir = kernel_dir - self.native_sysroot = native_sysroot - self.oe_builddir = oe_builddir - - self.outdir = options.outdir - self.compressor = options.compressor - self.bmap = options.bmap - self.no_fstab_update = options.no_fstab_update - - self.name = "%s-%s" % (os.path.splitext(os.path.basename(wks_file))[0], - strftime("%Y%m%d%H%M")) - self.workdir = tempfile.mkdtemp(dir=self.outdir, prefix='tmp.wic.') - self._image = None - self.ptable_format = self.ks.bootloader.ptable - self.parts = self.ks.partitions - - # as a convenience, set source to the boot partition source - # instead of forcing it to be set via bootloader --source - for part in self.parts: - if not self.ks.bootloader.source and part.mountpoint == "/boot": - self.ks.bootloader.source = part.source - break - - image_path = self._full_path(self.workdir, self.parts[0].disk, "direct") - self._image = PartitionedImage(image_path, self.ptable_format, - self.parts, self.native_sysroot) - - def do_create(self): - """ - Plugin entry point. - """ - try: - self.create() - self.assemble() - self.finalize() - self.print_info() - finally: - self.cleanup() - - 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.parts): - # copy rootfs dir to workdir to update fstab - # as rootfs can be used by other tasks and can't be modified - new_rootfs = os.path.realpath(os.path.join(self.workdir, "rootfs_copy")) - copyhardlinktree(image_rootfs, new_rootfs) - fstab_path = os.path.join(new_rootfs, 'etc/fstab') - - os.unlink(fstab_path) - - with open(fstab_path, "w") as fstab: - fstab.writelines(fstab_lines) - - return new_rootfs - - def _update_fstab(self, fstab_lines, parts): - """Assume partition order same as in wks""" - updated = False - for part in parts: - if not part.realnum or not part.mountpoint \ - or part.mountpoint == "/": - continue - - if part.use_uuid: - if part.fsuuid: - # FAT UUID is different from others - if len(part.fsuuid) == 10: - device_name = "UUID=%s-%s" % \ - (part.fsuuid[2:6], part.fsuuid[6:]) - else: - device_name = "UUID=%s" % part.fsuuid - else: - device_name = "PARTUUID=%s" % part.uuid - else: - # mmc device partitions are named mmcblk0p1, mmcblk0p2.. - prefix = 'p' if part.disk.startswith('mmcblk') else '' - device_name = "/dev/%s%s%d" % (part.disk, prefix, part.realnum) - - 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 _full_path(self, path, name, extention): - """ Construct full file path to a file we generate. """ - return os.path.join(path, "%s-%s.%s" % (self.name, name, extention)) - - # - # 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. - """ - if self.no_fstab_update: - new_rootfs = None - else: - new_rootfs = self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR")) - if new_rootfs: - # rootfs was copied to update fstab - self.replaced_rootfs_paths[new_rootfs] = self.rootfs_dir['ROOTFS_DIR'] - self.rootfs_dir['ROOTFS_DIR'] = new_rootfs - - for part in self.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))) - - self._image.prepare(self) - self._image.layout_partitions() - self._image.create() - - def assemble(self): - """ - Assemble partitions into disk image - """ - self._image.assemble() - - 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.ks.bootloader.source - disk_name = self.parts[0].disk - if source_plugin: - plugin = PluginMgr.get_plugins('source')[source_plugin] - plugin.do_install_disk(self._image, disk_name, self, self.workdir, - self.oe_builddir, self.bootimg_dir, - self.kernel_dir, self.native_sysroot) - - full_path = self._image.path - # Generate .bmap - if self.bmap: - logger.debug("Generating bmap file for %s", disk_name) - python = os.path.join(self.native_sysroot, 'usr/bin/python3-native/python3') - bmaptool = os.path.join(self.native_sysroot, 'usr/bin/bmaptool') - exec_native_cmd("%s %s create %s -o %s.bmap" % \ - (python, bmaptool, full_path, full_path), self.native_sysroot) - # Compress the image - if self.compressor: - logger.debug("Compressing disk %s with %s", disk_name, self.compressor) - exec_cmd("%s %s" % (self.compressor, full_path)) - - def print_info(self): - """ - Print the image(s) and artifacts used, for the user. - """ - msg = "The new image(s) can be found here:\n" - - extension = "direct" + {"gzip": ".gz", - "bzip2": ".bz2", - "xz": ".xz", - None: ""}.get(self.compressor) - full_path = self._full_path(self.outdir, self.parts[0].disk, extension) - msg += ' %s\n\n' % full_path - - msg += 'The following build artifacts were used to create the image(s):\n' - for part in self.parts: - if part.rootfs_dir is None: - continue - if part.mountpoint == '/': - suffix = ':' - else: - suffix = '["%s"]:' % (part.mountpoint or part.label) - rootdir = part.rootfs_dir - if rootdir in self.replaced_rootfs_paths: - rootdir = self.replaced_rootfs_paths[rootdir] - msg += ' ROOTFS_DIR%s%s\n' % (suffix.ljust(20), rootdir) - - msg += ' BOOTIMG_DIR: %s\n' % self.bootimg_dir - msg += ' KERNEL_DIR: %s\n' % self.kernel_dir - msg += ' NATIVE_SYSROOT: %s\n' % self.native_sysroot - - logger.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 - """ - for part in self.parts: - if part.mountpoint == "/": - if part.uuid: - return "PARTUUID=%s" % part.uuid - else: - suffix = 'p' if part.disk.startswith('mmcblk') else '' - return "/dev/%s%s%-d" % (part.disk, suffix, part.realnum) - - def cleanup(self): - if self._image: - self._image.cleanup() - - # 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) - -# Overhead of the MBR partitioning scheme (just one sector) -MBR_OVERHEAD = 1 - -# Overhead of the GPT partitioning scheme -GPT_OVERHEAD = 34 - -# Size of a sector in bytes -SECTOR_SIZE = 512 - -class PartitionedImage(): - """ - Partitioned image in a file. - """ - - def __init__(self, path, ptable_format, partitions, native_sysroot=None): - self.path = path # Path to the image file - self.numpart = 0 # Number of allocated partitions - self.realpart = 0 # Number of partitions in the partition table - self.offset = 0 # Offset of next partition (in sectors) - self.min_size = 0 # Minimum required disk size to fit - # all partitions (in bytes) - self.ptable_format = ptable_format # Partition table format - # Disk system identifier - self.identifier = random.SystemRandom().randint(1, 0xffffffff) - - self.partitions = partitions - self.partimages = [] - # Size of a sector used in calculations - self.sector_size = SECTOR_SIZE - self.native_sysroot = native_sysroot - - # calculate the real partition number, accounting for partitions not - # in the partition table and logical partitions - realnum = 0 - for part in self.partitions: - if part.no_table: - part.realnum = 0 - else: - realnum += 1 - if self.ptable_format == 'msdos' and realnum > 3 and len(partitions) > 4: - part.realnum = realnum + 1 - continue - part.realnum = realnum - - # generate parition and filesystem UUIDs - for part in self.partitions: - if not part.uuid and part.use_uuid: - if self.ptable_format == 'gpt': - part.uuid = str(uuid.uuid4()) - else: # msdos partition table - part.uuid = '%08x-%02d' % (self.identifier, part.realnum) - if not part.fsuuid: - if part.fstype == 'vfat' or part.fstype == 'msdos': - part.fsuuid = '0x' + str(uuid.uuid4())[:8].upper() - else: - part.fsuuid = str(uuid.uuid4()) - - def prepare(self, imager): - """Prepare an image. Call prepare method of all image partitions.""" - for part in self.partitions: - # need to create the filesystems in order to get their - # sizes before we can add them and do the layout. - part.prepare(imager, imager.workdir, imager.oe_builddir, - imager.rootfs_dir, imager.bootimg_dir, - imager.kernel_dir, imager.native_sysroot) - - # Converting kB to sectors for parted - part.size_sec = part.disk_size * 1024 // self.sector_size - - def layout_partitions(self): - """ Layout the partitions, meaning calculate the position of every - partition on the disk. The 'ptable_format' parameter defines the - partition table format and may be "msdos". """ - - logger.debug("Assigning %s partitions to disks", self.ptable_format) - - # The number of primary and logical partitions. Extended partition and - # partitions not listed in the table are not included. - num_real_partitions = len([p for p in self.partitions if not p.no_table]) - - # Go through partitions in the order they are added in .ks file - for num in range(len(self.partitions)): - part = self.partitions[num] - - if self.ptable_format == 'msdos' and part.part_name: - raise WicError("setting custom partition name is not " \ - "implemented for msdos partitions") - - if self.ptable_format == 'msdos' and part.part_type: - # The --part-type can also be implemented for MBR partitions, - # in which case it would map to the 1-byte "partition type" - # filed at offset 3 of the partition entry. - raise WicError("setting custom partition type is not " \ - "implemented for msdos partitions") - - # Get the disk where the partition is located - self.numpart += 1 - if not part.no_table: - self.realpart += 1 - - if self.numpart == 1: - if self.ptable_format == "msdos": - overhead = MBR_OVERHEAD - elif self.ptable_format == "gpt": - overhead = GPT_OVERHEAD - - # Skip one sector required for the partitioning scheme overhead - self.offset += overhead - - if self.realpart > 3 and num_real_partitions > 4: - # Reserve a sector for EBR for every logical partition - # before alignment is performed. - if self.ptable_format == "msdos": - self.offset += 1 - - if part.align: - # If not first partition and we do have alignment set we need - # to align the partition. - # FIXME: This leaves a empty spaces to the disk. To fill the - # gaps we could enlargea the previous partition? - - # Calc how much the alignment is off. - align_sectors = self.offset % (part.align * 1024 // self.sector_size) - - if align_sectors: - # If partition is not aligned as required, we need - # to move forward to the next alignment point - align_sectors = (part.align * 1024 // self.sector_size) - align_sectors - - logger.debug("Realignment for %s%s with %s sectors, original" - " offset %s, target alignment is %sK.", - part.disk, self.numpart, align_sectors, - self.offset, part.align) - - # increase the offset so we actually start the partition on right alignment - self.offset += align_sectors - - part.start = self.offset - self.offset += part.size_sec - - part.type = 'primary' - if not part.no_table: - part.num = self.realpart - else: - part.num = 0 - - if self.ptable_format == "msdos": - # only count the partitions that are in partition table - if num_real_partitions > 4: - if self.realpart > 3: - part.type = 'logical' - part.num = self.realpart + 1 - - logger.debug("Assigned %s to %s%d, sectors range %d-%d size %d " - "sectors (%d bytes).", part.mountpoint, part.disk, - part.num, part.start, self.offset - 1, part.size_sec, - part.size_sec * self.sector_size) - - # Once all the partitions have been layed out, we can calculate the - # minumim disk size - self.min_size = self.offset - if self.ptable_format == "gpt": - self.min_size += GPT_OVERHEAD - - self.min_size *= self.sector_size - - def _create_partition(self, device, parttype, fstype, start, size): - """ Create a partition on an image described by the 'device' object. """ - - # Start is included to the size so we need to substract one from the end. - end = start + size - 1 - logger.debug("Added '%s' partition, sectors %d-%d, size %d sectors", - parttype, start, end, size) - - cmd = "parted -s %s unit s mkpart %s" % (device, parttype) - if fstype: - cmd += " %s" % fstype - cmd += " %d %d" % (start, end) - - return exec_native_cmd(cmd, self.native_sysroot) - - def create(self): - logger.debug("Creating sparse file %s", self.path) - with open(self.path, 'w') as sparse: - os.ftruncate(sparse.fileno(), self.min_size) - - logger.debug("Initializing partition table for %s", self.path) - exec_native_cmd("parted -s %s mklabel %s" % - (self.path, self.ptable_format), self.native_sysroot) - - logger.debug("Set disk identifier %x", self.identifier) - with open(self.path, 'r+b') as img: - img.seek(0x1B8) - img.write(self.identifier.to_bytes(4, 'little')) - - logger.debug("Creating partitions") - - for part in self.partitions: - if part.num == 0: - continue - - if self.ptable_format == "msdos" and part.num == 5: - # Create an extended partition (note: extended - # partition is described in MBR and contains all - # logical partitions). The logical partitions save a - # sector for an EBR just before the start of a - # partition. The extended partition must start one - # sector before the start of the first logical - # partition. This way the first EBR is inside of the - # extended partition. Since the extended partitions - # starts a sector before the first logical partition, - # add a sector at the back, so that there is enough - # room for all logical partitions. - self._create_partition(self.path, "extended", - None, part.start - 1, - self.offset - part.start + 1) - - if part.fstype == "swap": - parted_fs_type = "linux-swap" - elif part.fstype == "vfat": - parted_fs_type = "fat32" - elif part.fstype == "msdos": - parted_fs_type = "fat16" - if not part.system_id: - part.system_id = '0x6' # FAT16 - else: - # Type for ext2/ext3/ext4/btrfs - parted_fs_type = "ext2" - - # Boot ROM of OMAP boards require vfat boot partition to have an - # even number of sectors. - if part.mountpoint == "/boot" and part.fstype in ["vfat", "msdos"] \ - and part.size_sec % 2: - logger.debug("Subtracting one sector from '%s' partition to " - "get even number of sectors for the partition", - part.mountpoint) - part.size_sec -= 1 - - self._create_partition(self.path, part.type, - parted_fs_type, part.start, part.size_sec) - - if part.part_name: - logger.debug("partition %d: set name to %s", - part.num, part.part_name) - exec_native_cmd("sgdisk --change-name=%d:%s %s" % \ - (part.num, part.part_name, - self.path), self.native_sysroot) - - if part.part_type: - logger.debug("partition %d: set type UID to %s", - part.num, part.part_type) - exec_native_cmd("sgdisk --typecode=%d:%s %s" % \ - (part.num, part.part_type, - self.path), self.native_sysroot) - - if part.uuid and self.ptable_format == "gpt": - logger.debug("partition %d: set UUID to %s", - part.num, part.uuid) - exec_native_cmd("sgdisk --partition-guid=%d:%s %s" % \ - (part.num, part.uuid, self.path), - self.native_sysroot) - - if part.label and self.ptable_format == "gpt": - logger.debug("partition %d: set name to %s", - part.num, part.label) - exec_native_cmd("parted -s %s name %d %s" % \ - (self.path, part.num, part.label), - self.native_sysroot) - - if part.active: - flag_name = "legacy_boot" if self.ptable_format == 'gpt' else "boot" - logger.debug("Set '%s' flag for partition '%s' on disk '%s'", - flag_name, part.num, self.path) - exec_native_cmd("parted -s %s set %d %s on" % \ - (self.path, part.num, flag_name), - self.native_sysroot) - if part.system_id: - exec_native_cmd("sfdisk --part-type %s %s %s" % \ - (self.path, part.num, part.system_id), - self.native_sysroot) - - def cleanup(self): - # remove partition images - for image in set(self.partimages): - os.remove(image) - - def assemble(self): - logger.debug("Installing partitions") - - for part in self.partitions: - source = part.source_file - if source: - # install source_file contents into a partition - sparse_copy(source, self.path, seek=part.start * self.sector_size) - - logger.debug("Installed %s in partition %d, sectors %d-%d, " - "size %d sectors", source, part.num, part.start, - part.start + part.size_sec - 1, part.size_sec) - - partimage = self.path + '.p%d' % part.num - os.rename(source, partimage) - self.partimages.append(partimage) diff --git a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-efi.py b/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-efi.py deleted file mode 100644 index beb74d7a7..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-efi.py +++ /dev/null @@ -1,258 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2014, 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 'bootimg-efi' source plugin class for 'wic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# - -import logging -import os -import shutil - -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, BOOTDD_EXTRA_SPACE) - -logger = logging.getLogger('wic') - -class BootimgEFIPlugin(SourcePlugin): - """ - Create EFI boot partition. - This plugin supports GRUB 2 and systemd-boot bootloaders. - """ - - name = 'bootimg-efi' - - @classmethod - def do_configure_grubefi(cls, creator, cr_workdir): - """ - Create loader-specific (grub-efi) config - """ - configfile = creator.ks.bootloader.configfile - custom_cfg = None - if configfile: - custom_cfg = get_custom_config(configfile) - if custom_cfg: - # Use a custom configuration for grub - grubefi_conf = custom_cfg - logger.debug("Using custom configuration file " - "%s for grub.cfg", configfile) - else: - raise WicError("configfile is specified but failed to " - "get it from %s." % configfile) - - if not custom_cfg: - # Create grub configuration using parameters from wks file - bootloader = creator.ks.bootloader - - grubefi_conf = "" - grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n" - grubefi_conf += "default=boot\n" - grubefi_conf += "timeout=%s\n" % bootloader.timeout - grubefi_conf += "menuentry 'boot'{\n" - - kernel = "/bzImage" - - grubefi_conf += "linux %s root=%s rootwait %s\n" \ - % (kernel, creator.rootdev, bootloader.append) - grubefi_conf += "}\n" - - logger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg", - cr_workdir) - cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w") - cfg.write(grubefi_conf) - cfg.close() - - @classmethod - def do_configure_systemdboot(cls, hdddir, creator, cr_workdir, source_params): - """ - Create loader-specific systemd-boot/gummiboot config - """ - install_cmd = "install -d %s/loader" % hdddir - exec_cmd(install_cmd) - - install_cmd = "install -d %s/loader/entries" % hdddir - 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: - # obviously we need to have a common common deploy var - bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") - if not bootimg_dir: - raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") - - cp_cmd = "cp %s/%s %s" % (bootimg_dir, initrd, hdddir) - exec_cmd(cp_cmd, True) - else: - logger.debug("Ignoring missing initrd") - - logger.debug("Writing systemd-boot config " - "%s/hdd/boot/loader/loader.conf", cr_workdir) - cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w") - cfg.write(loader_conf) - cfg.close() - - 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 - kernel = "/bzImage" - - boot_conf = "" - boot_conf += "title boot\n" - boot_conf += "linux %s\n" % kernel - boot_conf += "options LABEL=Boot root=%s %s\n" % \ - (creator.rootdev, bootloader.append) - - if initrd: - boot_conf += "initrd /%s\n" % initrd - - logger.debug("Writing systemd-boot config " - "%s/hdd/boot/loader/entries/boot.conf", cr_workdir) - cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w") - cfg.write(boot_conf) - cfg.close() - - - @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 - """ - hdddir = "%s/hdd/boot" % cr_workdir - - install_cmd = "install -d %s/EFI/BOOT" % hdddir - exec_cmd(install_cmd) - - try: - if source_params['loader'] == 'grub-efi': - cls.do_configure_grubefi(creator, cr_workdir) - elif source_params['loader'] == 'systemd-boot': - cls.do_configure_systemdboot(hdddir, creator, cr_workdir, source_params) - else: - raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader']) - except KeyError: - raise WicError("bootimg-efi requires a loader, none specified") - - - @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 i.e. it - 'prepares' the partition to be incorporated into the image. - In this case, prepare content for an EFI (grub) boot partition. - """ - 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 - - hdddir = "%s/hdd/boot" % cr_workdir - - install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \ - (staging_kernel_dir, hdddir) - exec_cmd(install_cmd) - - - try: - if source_params['loader'] == 'grub-efi': - shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, - "%s/grub.cfg" % cr_workdir) - for mod in [x for x in os.listdir(kernel_dir) if x.startswith("grub-efi-")]: - cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[9:]) - exec_cmd(cp_cmd, True) - shutil.move("%s/grub.cfg" % cr_workdir, - "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir) - elif source_params['loader'] == 'systemd-boot': - 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, hdddir, mod[8:]) - exec_cmd(cp_cmd, True) - else: - raise WicError("unrecognized bootimg-efi loader: %s" % - source_params['loader']) - except KeyError: - raise WicError("bootimg-efi requires a loader, none specified") - - startup = os.path.join(kernel_dir, "startup.nsh") - if os.path.exists(startup): - cp_cmd = "cp %s %s/" % (startup, hdddir) - exec_cmd(cp_cmd, True) - - du_cmd = "du -bks %s" % hdddir - out = exec_cmd(du_cmd) - blocks = int(out.split()[0]) - - extra_blocks = part.get_extra_block_count(blocks) - - if extra_blocks < BOOTDD_EXTRA_SPACE: - extra_blocks = BOOTDD_EXTRA_SPACE - - blocks += extra_blocks - - logger.debug("Added %d extra blocks to %s to get to %d total blocks", - extra_blocks, part.mountpoint, blocks) - - # dosfs image, created by mkdosfs - bootimg = "%s/boot.img" % cr_workdir - - dosfs_cmd = "mkdosfs -n efi -i %s -C %s %d" % \ - (part.fsuuid, bootimg, blocks) - exec_native_cmd(dosfs_cmd, native_sysroot) - - mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) - exec_native_cmd(mcopy_cmd, native_sysroot) - - chmod_cmd = "chmod 644 %s" % bootimg - exec_cmd(chmod_cmd) - - du_cmd = "du -Lbks %s" % bootimg - out = exec_cmd(du_cmd) - bootimg_size = out.split()[0] - - part.size = int(bootimg_size) - part.source_file = bootimg diff --git a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-partition.py b/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-partition.py deleted file mode 100644 index b239fc0b4..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-partition.py +++ /dev/null @@ -1,132 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# 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 'bootimg-partition' source plugin class for -# 'wic'. The plugin creates an image of boot partition, copying over -# files listed in IMAGE_BOOT_FILES bitbake variable. -# -# AUTHORS -# Maciej Borzecki <maciej.borzecki (at] open-rnd.pl> -# - -import logging -import os -import re - -from glob import glob - -from wic import WicError -from wic.pluginbase import SourcePlugin -from wic.misc import exec_cmd, get_bitbake_var - -logger = logging.getLogger('wic') - -class BootimgPartitionPlugin(SourcePlugin): - """ - Create an image of boot partition, copying over files - listed in IMAGE_BOOT_FILES bitbake variable. - """ - - name = 'bootimg-partition' - - @classmethod - def do_prepare_partition(cls, part, source_params, cr, cr_workdir, - oe_builddir, bootimg_dir, kernel_dir, - rootfs_dir, native_sysroot): - """ - Called to do the actual content population for a partition i.e. it - 'prepares' the partition to be incorporated into the image. - In this case, does the following: - - sets up a vfat partition - - copies all files listed in IMAGE_BOOT_FILES variable - """ - hdddir = "%s/boot.%d" % (cr_workdir, part.lineno) - install_cmd = "install -d %s" % hdddir - exec_cmd(install_cmd) - - 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") - - logger.debug('Kernel dir: %s', bootimg_dir) - - boot_files = None - for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)): - if fmt: - var = fmt % id - else: - var = "" - - boot_files = get_bitbake_var("IMAGE_BOOT_FILES" + var) - if boot_files is not None: - break - - if boot_files is None: - raise WicError('No boot files defined, IMAGE_BOOT_FILES unset for entry #%d' % part.lineno) - - logger.debug('Boot files: %s', boot_files) - - # list of tuples (src_name, dst_name) - deploy_files = [] - for src_entry in re.findall(r'[\w;\-\./\*]+', boot_files): - if ';' in src_entry: - dst_entry = tuple(src_entry.split(';')) - if not dst_entry[0] or not dst_entry[1]: - raise WicError('Malformed boot file entry: %s' % src_entry) - else: - dst_entry = (src_entry, src_entry) - - logger.debug('Destination entry: %r', dst_entry) - deploy_files.append(dst_entry) - - for deploy_entry in deploy_files: - src, dst = deploy_entry - install_task = [] - if '*' in src: - # by default install files under their basename - entry_name_fn = os.path.basename - if dst != src: - # unless a target name was given, then treat name - # as a directory and append a basename - entry_name_fn = lambda name: \ - os.path.join(dst, - os.path.basename(name)) - - srcs = glob(os.path.join(kernel_dir, src)) - - logger.debug('Globbed sources: %s', ', '.join(srcs)) - for entry in srcs: - entry_dst_name = entry_name_fn(entry) - install_task.append((entry, - os.path.join(hdddir, - entry_dst_name))) - else: - install_task = [(os.path.join(kernel_dir, src), - os.path.join(hdddir, dst))] - - for task in install_task: - src_path, dst_path = task - logger.debug('Install %s as %s', - os.path.basename(src_path), dst_path) - install_cmd = "install -m 0644 -D %s %s" \ - % (src_path, dst_path) - exec_cmd(install_cmd) - - logger.debug('Prepare boot partition using rootfs in %s', hdddir) - part.prepare_rootfs(cr_workdir, oe_builddir, hdddir, - native_sysroot, False) diff --git a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py b/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py deleted file mode 100644 index d599112dd..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py +++ /dev/null @@ -1,207 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2014, 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 'bootimg-pcbios' source plugin class for 'wic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.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, BOOTDD_EXTRA_SPACE) - -logger = logging.getLogger('wic') - -class BootimgPcbiosPlugin(SourcePlugin): - """ - Create MBR boot partition and install syslinux on it. - """ - - name = 'bootimg-pcbios' - - @classmethod - def _get_bootimg_dir(cls, bootimg_dir, dirname): - """ - Check if dirname exists in default bootimg_dir or in STAGING_DIR. - """ - for result in (bootimg_dir, get_bitbake_var("STAGING_DATADIR")): - if os.path.exists("%s/%s" % (result, dirname)): - return result - - raise WicError("Couldn't find correct bootimg_dir, exiting") - - @classmethod - def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Called after all partitions have been prepared and assembled into a - disk image. In this case, we install the MBR. - """ - bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux') - mbrfile = "%s/syslinux/" % bootimg_dir - if creator.ptable_format == 'msdos': - mbrfile += "mbr.bin" - elif creator.ptable_format == 'gpt': - mbrfile += "gptmbr.bin" - else: - raise WicError("Unsupported partition table: %s" % - creator.ptable_format) - - if not os.path.exists(mbrfile): - raise WicError("Couldn't find %s. If using the -e option, do you " - "have the right MACHINE set in local.conf? If not, " - "is the bootimg_dir path correct?" % mbrfile) - - full_path = creator._full_path(workdir, disk_name, "direct") - logger.debug("Installing MBR on disk %s as %s with size %s bytes", - disk_name, full_path, disk.min_size) - - dd_cmd = "dd if=%s of=%s conv=notrunc" % (mbrfile, full_path) - exec_cmd(dd_cmd, native_sysroot) - - @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 syslinux config - """ - hdddir = "%s/hdd/boot" % cr_workdir - - install_cmd = "install -d %s" % hdddir - exec_cmd(install_cmd) - - bootloader = creator.ks.bootloader - - custom_cfg = None - if bootloader.configfile: - custom_cfg = get_custom_config(bootloader.configfile) - if custom_cfg: - # Use a custom configuration for grub - syslinux_conf = custom_cfg - logger.debug("Using custom configuration file %s " - "for syslinux.cfg", bootloader.configfile) - else: - raise WicError("configfile is specified but failed to " - "get it from %s." % bootloader.configfile) - - if not custom_cfg: - # Create syslinux configuration using parameters from wks file - splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg") - if os.path.exists(splash): - splashline = "menu background splash.jpg" - else: - splashline = "" - - syslinux_conf = "" - syslinux_conf += "PROMPT 0\n" - syslinux_conf += "TIMEOUT " + str(bootloader.timeout) + "\n" - syslinux_conf += "\n" - syslinux_conf += "ALLOWOPTIONS 1\n" - syslinux_conf += "SERIAL 0 115200\n" - syslinux_conf += "\n" - if splashline: - syslinux_conf += "%s\n" % splashline - syslinux_conf += "DEFAULT boot\n" - syslinux_conf += "LABEL boot\n" - - kernel = "/vmlinuz" - syslinux_conf += "KERNEL " + kernel + "\n" - - syslinux_conf += "APPEND label=boot root=%s %s\n" % \ - (creator.rootdev, bootloader.append) - - logger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg", - cr_workdir) - cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w") - cfg.write(syslinux_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 i.e. it - 'prepares' the partition to be incorporated into the image. - In this case, prepare content for legacy bios boot partition. - """ - bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux') - - staging_kernel_dir = kernel_dir - - hdddir = "%s/hdd/boot" % cr_workdir - - cmds = ("install -m 0644 %s/bzImage %s/vmlinuz" % - (staging_kernel_dir, hdddir), - "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" % - (bootimg_dir, hdddir), - "install -m 0644 %s/syslinux/vesamenu.c32 %s/vesamenu.c32" % - (bootimg_dir, hdddir), - "install -m 444 %s/syslinux/libcom32.c32 %s/libcom32.c32" % - (bootimg_dir, hdddir), - "install -m 444 %s/syslinux/libutil.c32 %s/libutil.c32" % - (bootimg_dir, hdddir)) - - for install_cmd in cmds: - exec_cmd(install_cmd) - - du_cmd = "du -bks %s" % hdddir - out = exec_cmd(du_cmd) - blocks = int(out.split()[0]) - - extra_blocks = part.get_extra_block_count(blocks) - - if extra_blocks < BOOTDD_EXTRA_SPACE: - extra_blocks = BOOTDD_EXTRA_SPACE - - blocks += extra_blocks - - logger.debug("Added %d extra blocks to %s to get to %d total blocks", - extra_blocks, part.mountpoint, blocks) - - # dosfs image, created by mkdosfs - bootimg = "%s/boot%s.img" % (cr_workdir, part.lineno) - - dosfs_cmd = "mkdosfs -n boot -i %s -S 512 -C %s %d" % \ - (part.fsuuid, bootimg, blocks) - exec_native_cmd(dosfs_cmd, native_sysroot) - - mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir) - exec_native_cmd(mcopy_cmd, native_sysroot) - - syslinux_cmd = "syslinux %s" % bootimg - exec_native_cmd(syslinux_cmd, native_sysroot) - - chmod_cmd = "chmod 644 %s" % bootimg - exec_cmd(chmod_cmd) - - du_cmd = "du -Lbks %s" % bootimg - out = exec_cmd(du_cmd) - bootimg_size = out.split()[0] - - part.size = int(bootimg_size) - part.source_file = bootimg diff --git a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py b/import-layers/yocto-poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py deleted file mode 100644 index d6bd3bff7..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py +++ /dev/null @@ -1,466 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- - -# 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 'isoimage-isohybrid' source plugin class for 'wic' -# -# AUTHORS -# Mihaly Varga <mihaly.varga (at] ni.com> - -import glob -import logging -import os -import re -import shutil - -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 IsoImagePlugin(SourcePlugin): - """ - Create a bootable ISO image - - This plugin creates a hybrid, legacy and EFI bootable ISO image. The - generated image can be used on optical media as well as USB media. - - Legacy boot uses syslinux and EFI boot uses grub or gummiboot (not - implemented yet) as bootloader. The plugin creates the directories required - by bootloaders and populates them by creating and configuring the - bootloader files. - - Example kickstart file: - part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\ - image_name= IsoImage" --ondisk cd --label LIVECD --fstype=ext2 - bootloader --timeout=10 --append=" " - - In --sourceparams "loader" specifies the bootloader used for booting in EFI - mode, while "image_name" specifies the name of the generated image. In the - example above, wic creates an ISO image named IsoImage-cd.direct (default - extension added by direct imeger plugin) and a file named IsoImage-cd.iso - """ - - name = 'isoimage-isohybrid' - - @classmethod - def do_configure_syslinux(cls, creator, cr_workdir): - """ - Create loader-specific (syslinux) config - """ - splash = os.path.join(cr_workdir, "ISO/boot/splash.jpg") - if os.path.exists(splash): - splashline = "menu background splash.jpg" - else: - splashline = "" - - bootloader = creator.ks.bootloader - - syslinux_conf = "" - syslinux_conf += "PROMPT 0\n" - syslinux_conf += "TIMEOUT %s \n" % (bootloader.timeout or 10) - syslinux_conf += "\n" - syslinux_conf += "ALLOWOPTIONS 1\n" - syslinux_conf += "SERIAL 0 115200\n" - syslinux_conf += "\n" - if splashline: - syslinux_conf += "%s\n" % splashline - syslinux_conf += "DEFAULT boot\n" - syslinux_conf += "LABEL boot\n" - - kernel = "/bzImage" - syslinux_conf += "KERNEL " + kernel + "\n" - syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \ - % bootloader.append - - logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg", - cr_workdir) - - with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg: - cfg.write(syslinux_conf) - - @classmethod - def do_configure_grubefi(cls, part, creator, target_dir): - """ - Create loader-specific (grub-efi) config - """ - configfile = creator.ks.bootloader.configfile - if configfile: - grubefi_conf = get_custom_config(configfile) - if grubefi_conf: - logger.debug("Using custom configuration file %s for grub.cfg", - configfile) - else: - raise WicError("configfile is specified " - "but failed to get it from %s", configfile) - else: - splash = os.path.join(target_dir, "splash.jpg") - if os.path.exists(splash): - splashline = "menu background splash.jpg" - else: - splashline = "" - - bootloader = creator.ks.bootloader - - grubefi_conf = "" - grubefi_conf += "serial --unit=0 --speed=115200 --word=8 " - grubefi_conf += "--parity=no --stop=1\n" - grubefi_conf += "default=boot\n" - grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10) - grubefi_conf += "\n" - grubefi_conf += "search --set=root --label %s " % part.label - grubefi_conf += "\n" - grubefi_conf += "menuentry 'boot'{\n" - - kernel = "/bzImage" - - grubefi_conf += "linux %s rootwait %s\n" \ - % (kernel, bootloader.append) - grubefi_conf += "initrd /initrd \n" - grubefi_conf += "}\n" - - if splashline: - grubefi_conf += "%s\n" % splashline - - cfg_path = os.path.join(target_dir, "grub.cfg") - logger.debug("Writing grubefi config %s", cfg_path) - - with open(cfg_path, "w") as cfg: - cfg.write(grubefi_conf) - - @staticmethod - def _build_initramfs_path(rootfs_dir, cr_workdir): - """ - Create path for initramfs image - """ - - initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD") - if not initrd: - initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") - if not initrd_dir: - raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.") - - image_name = get_bitbake_var("IMAGE_BASENAME") - if not image_name: - raise WicError("Couldn't find IMAGE_BASENAME, exiting.") - - image_type = get_bitbake_var("INITRAMFS_FSTYPES") - if not image_type: - raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.") - - machine = os.path.basename(initrd_dir) - - pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type) - files = glob.glob(pattern) - if files: - initrd = files[0] - - if not initrd or not os.path.exists(initrd): - # Create initrd from rootfs directory - initrd = "%s/initrd.cpio.gz" % cr_workdir - initrd_dir = "%s/INITRD" % cr_workdir - shutil.copytree("%s" % rootfs_dir, \ - "%s" % initrd_dir, symlinks=True) - - if os.path.isfile("%s/init" % rootfs_dir): - shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir) - elif os.path.lexists("%s/init" % rootfs_dir): - os.symlink(os.readlink("%s/init" % rootfs_dir), \ - "%s/init" % initrd_dir) - elif os.path.isfile("%s/sbin/init" % rootfs_dir): - shutil.copy2("%s/sbin/init" % rootfs_dir, \ - "%s" % initrd_dir) - elif os.path.lexists("%s/sbin/init" % rootfs_dir): - os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \ - "%s/init" % initrd_dir) - else: - raise WicError("Couldn't find or build initrd, exiting.") - - exec_cmd("cd %s && find . | cpio -o -H newc -R +0:+0 >./initrd.cpio " \ - % initrd_dir, as_shell=True) - exec_cmd("gzip -f -9 -c %s/initrd.cpio > %s" \ - % (cr_workdir, initrd), as_shell=True) - shutil.rmtree(initrd_dir) - - return initrd - - @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 - """ - isodir = "%s/ISO/" % cr_workdir - - if os.path.exists(isodir): - shutil.rmtree(isodir) - - install_cmd = "install -d %s " % isodir - exec_cmd(install_cmd) - - # Overwrite the name of the created image - logger.debug(source_params) - if 'image_name' in source_params and \ - source_params['image_name'].strip(): - creator.name = source_params['image_name'].strip() - logger.debug("The name of the image is: %s", creator.name) - - @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 i.e. it - 'prepares' the partition to be incorporated into the image. - In this case, prepare content for a bootable ISO image. - """ - - isodir = "%s/ISO" % cr_workdir - - if part.rootfs_dir is None: - if not 'ROOTFS_DIR' in rootfs_dir: - raise WicError("Couldn't find --rootfs-dir, exiting.") - rootfs_dir = rootfs_dir['ROOTFS_DIR'] - else: - if part.rootfs_dir in rootfs_dir: - rootfs_dir = rootfs_dir[part.rootfs_dir] - elif part.rootfs_dir: - rootfs_dir = part.rootfs_dir - else: - raise WicError("Couldn't find --rootfs-dir=%s connection " - "or it is not a valid path, exiting." % - part.rootfs_dir) - - if not os.path.isdir(rootfs_dir): - rootfs_dir = get_bitbake_var("IMAGE_ROOTFS") - if not os.path.isdir(rootfs_dir): - raise WicError("Couldn't find IMAGE_ROOTFS, exiting.") - - part.rootfs_dir = rootfs_dir - - # Prepare rootfs.img - deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") - img_iso_dir = get_bitbake_var("ISODIR") - rootfs_img = "%s/rootfs.img" % img_iso_dir - if not os.path.isfile(rootfs_img): - # check if rootfs.img is in deploydir - deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE") - image_name = get_bitbake_var("IMAGE_LINK_NAME") - rootfs_img = "%s/%s.%s" \ - % (deploy_dir, image_name, part.fstype) - - if not os.path.isfile(rootfs_img): - # create image file with type specified by --fstype - # which contains rootfs - du_cmd = "du -bks %s" % rootfs_dir - out = exec_cmd(du_cmd) - part.size = int(out.split()[0]) - part.extra_space = 0 - part.overhead_factor = 1.2 - part.prepare_rootfs(cr_workdir, oe_builddir, rootfs_dir, \ - native_sysroot) - rootfs_img = part.source_file - - install_cmd = "install -m 0644 %s %s/rootfs.img" \ - % (rootfs_img, isodir) - exec_cmd(install_cmd) - - # Remove the temporary file created by part.prepare_rootfs() - if os.path.isfile(part.source_file): - os.remove(part.source_file) - - # Support using a different initrd other than default - if source_params.get('initrd'): - initrd = source_params['initrd'] - if not deploy_dir: - raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting") - cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir) - exec_cmd(cp_cmd) - else: - # Prepare initial ramdisk - initrd = "%s/initrd" % deploy_dir - if not os.path.isfile(initrd): - initrd = "%s/initrd" % img_iso_dir - if not os.path.isfile(initrd): - initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir) - - install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir) - exec_cmd(install_cmd) - - # Remove the temporary file created by _build_initramfs_path function - if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir): - os.remove("%s/initrd.cpio.gz" % cr_workdir) - - # Install bzImage - install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \ - (kernel_dir, isodir) - exec_cmd(install_cmd) - - #Create bootloader for efi boot - try: - target_dir = "%s/EFI/BOOT" % isodir - if os.path.exists(target_dir): - shutil.rmtree(target_dir) - - os.makedirs(target_dir) - - if source_params['loader'] == 'grub-efi': - # Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or - # didn't contains it - target_arch = get_bitbake_var("TARGET_SYS") - if not target_arch: - raise WicError("Coludn't find target architecture") - - if re.match("x86_64", target_arch): - grub_image = "grub-efi-bootx64.efi" - elif re.match('i.86', target_arch): - grub_image = "grub-efi-bootia32.efi" - else: - raise WicError("grub-efi is incompatible with target %s" % - target_arch) - - grub_target = os.path.join(target_dir, grub_image) - if not os.path.isfile(grub_target): - grub_src = os.path.join(deploy_dir, grub_image) - if not os.path.exists(grub_src): - raise WicError("Grub loader %s is not found in %s. " - "Please build grub-efi first" % (grub_image, deploy_dir)) - shutil.copy(grub_src, grub_target) - - if not os.path.isfile(os.path.join(target_dir, "boot.cfg")): - cls.do_configure_grubefi(part, creator, target_dir) - - else: - raise WicError("unrecognized bootimg-efi loader: %s" % - source_params['loader']) - except KeyError: - raise WicError("bootimg-efi requires a loader, none specified") - - # Create efi.img that contains bootloader files for EFI booting - # if ISODIR didn't exist or didn't contains it - if os.path.isfile("%s/efi.img" % img_iso_dir): - install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \ - (img_iso_dir, isodir) - exec_cmd(install_cmd) - else: - du_cmd = "du -bks %s/EFI" % isodir - out = exec_cmd(du_cmd) - blocks = int(out.split()[0]) - # Add some extra space for file system overhead - blocks += 100 - logger.debug("Added 100 extra blocks to %s to get to %d " - "total blocks", part.mountpoint, blocks) - - # dosfs image for EFI boot - bootimg = "%s/efi.img" % isodir - - dosfs_cmd = 'mkfs.vfat -n "EFIimg" -S 512 -C %s %d' \ - % (bootimg, blocks) - exec_native_cmd(dosfs_cmd, native_sysroot) - - mmd_cmd = "mmd -i %s ::/EFI" % bootimg - exec_native_cmd(mmd_cmd, native_sysroot) - - mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \ - % (bootimg, isodir) - exec_native_cmd(mcopy_cmd, native_sysroot) - - chmod_cmd = "chmod 644 %s" % bootimg - exec_cmd(chmod_cmd) - - # Prepare files for legacy boot - syslinux_dir = get_bitbake_var("STAGING_DATADIR") - if not syslinux_dir: - raise WicError("Couldn't find STAGING_DATADIR, exiting.") - - if os.path.exists("%s/isolinux" % isodir): - shutil.rmtree("%s/isolinux" % isodir) - - install_cmd = "install -d %s/isolinux" % isodir - exec_cmd(install_cmd) - - cls.do_configure_syslinux(creator, cr_workdir) - - install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir - install_cmd += "%s/isolinux/ldlinux.sys" % isodir - exec_cmd(install_cmd) - - install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir - install_cmd += "%s/isolinux/isohdpfx.bin" % isodir - exec_cmd(install_cmd) - - install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir - install_cmd += "%s/isolinux/isolinux.bin" % isodir - exec_cmd(install_cmd) - - install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir - install_cmd += "%s/isolinux/ldlinux.c32" % isodir - exec_cmd(install_cmd) - - #create ISO image - iso_img = "%s/tempiso_img.iso" % cr_workdir - iso_bootimg = "isolinux/isolinux.bin" - iso_bootcat = "isolinux/boot.cat" - efi_img = "efi.img" - - mkisofs_cmd = "mkisofs -V %s " % part.label - mkisofs_cmd += "-o %s -U " % iso_img - mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg - mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat - mkisofs_cmd += "-boot-info-table -eltorito-alt-boot " - mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img - mkisofs_cmd += "-no-emul-boot %s " % isodir - - logger.debug("running command: %s", mkisofs_cmd) - exec_native_cmd(mkisofs_cmd, native_sysroot) - - shutil.rmtree(isodir) - - du_cmd = "du -Lbks %s" % iso_img - out = exec_cmd(du_cmd) - isoimg_size = int(out.split()[0]) - - part.size = isoimg_size - part.source_file = iso_img - - @classmethod - def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir, - bootimg_dir, kernel_dir, native_sysroot): - """ - Called after all partitions have been prepared and assembled into a - disk image. In this case, we insert/modify the MBR using isohybrid - utility for booting via BIOS from disk storage devices. - """ - - iso_img = "%s.p1" % disk.path - full_path = creator._full_path(workdir, disk_name, "direct") - full_path_iso = creator._full_path(workdir, disk_name, "iso") - - isohybrid_cmd = "isohybrid -u %s" % iso_img - logger.debug("running command: %s", isohybrid_cmd) - exec_native_cmd(isohybrid_cmd, native_sysroot) - - # Replace the image created by direct plugin with the one created by - # mkisofs command. This is necessary because the iso image created by - # mkisofs has a very specific MBR is system area of the ISO image, and - # direct plugin adds and configures an another MBR. - logger.debug("Replaceing the image created by direct plugin\n") - os.remove(disk.path) - shutil.copy2(iso_img, full_path_iso) - shutil.copy2(full_path_iso, full_path) diff --git a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/rawcopy.py b/import-layers/yocto-poky/scripts/lib/wic/plugins/source/rawcopy.py deleted file mode 100644 index e86398ac8..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/rawcopy.py +++ /dev/null @@ -1,91 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# 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. -# - -import logging -import os - -from wic import WicError -from wic.pluginbase import SourcePlugin -from wic.misc import exec_cmd, get_bitbake_var -from wic.filemap import sparse_copy - -logger = logging.getLogger('wic') - -class RawCopyPlugin(SourcePlugin): - """ - Populate partition content from raw image file. - """ - - name = 'rawcopy' - - @staticmethod - def do_image_label(fstype, dst, label): - if fstype.startswith('ext'): - cmd = 'tune2fs -L %s %s' % (label, dst) - elif fstype in ('msdos', 'vfat'): - cmd = 'dosfslabel %s %s' % (dst, label) - elif fstype == 'btrfs': - cmd = 'btrfs filesystem label %s %s' % (dst, label) - elif fstype == 'swap': - cmd = 'mkswap -L %s %s' % (label, dst) - elif fstype == 'squashfs': - raise WicError("It's not possible to update a squashfs " - "filesystem label '%s'" % (label)) - else: - raise WicError("Cannot update filesystem label: " - "Unknown fstype: '%s'" % (fstype)) - - exec_cmd(cmd) - - @classmethod - def do_prepare_partition(cls, part, source_params, cr, cr_workdir, - oe_builddir, bootimg_dir, kernel_dir, - rootfs_dir, native_sysroot): - """ - Called to do the actual content population for a partition i.e. it - 'prepares' the partition to be incorporated into the image. - """ - 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") - - logger.debug('Kernel dir: %s', kernel_dir) - - if 'file' not in source_params: - raise WicError("No file specified") - - src = os.path.join(kernel_dir, source_params['file']) - dst = os.path.join(cr_workdir, "%s.%s" % (source_params['file'], part.lineno)) - - if 'skip' in source_params: - sparse_copy(src, dst, skip=int(source_params['skip'])) - else: - sparse_copy(src, dst) - - # get the size in the right units for kickstart (kB) - du_cmd = "du -Lbks %s" % dst - out = exec_cmd(du_cmd) - filesize = int(out.split()[0]) - - if filesize > part.size: - part.size = filesize - - if part.label: - RawCopyPlugin.do_image_label(part.fstype, dst, part.label) - - part.source_file = dst diff --git a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/rootfs.py b/import-layers/yocto-poky/scripts/lib/wic/plugins/source/rootfs.py deleted file mode 100644 index aec720fb2..000000000 --- a/import-layers/yocto-poky/scripts/lib/wic/plugins/source/rootfs.py +++ /dev/null @@ -1,126 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (c) 2014, 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 'rootfs' source plugin class for 'wic' -# -# AUTHORS -# Tom Zanussi <tom.zanussi (at] linux.intel.com> -# Joao Henrique Ferreira de Freitas <joaohf (at] gmail.com> -# - -import logging -import os -import shutil -import sys - -from oe.path import copyhardlinktree - -from wic import WicError -from wic.pluginbase import SourcePlugin -from wic.misc import get_bitbake_var - -logger = logging.getLogger('wic') - -class RootfsPlugin(SourcePlugin): - """ - Populate partition content from a rootfs directory. - """ - - name = 'rootfs' - - @staticmethod - def __get_rootfs_dir(rootfs_dir): - if os.path.isdir(rootfs_dir): - return os.path.realpath(rootfs_dir) - - image_rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", rootfs_dir) - if not os.path.isdir(image_rootfs_dir): - raise WicError("No valid artifact IMAGE_ROOTFS from image " - "named %s has been found at %s, exiting." % - (rootfs_dir, image_rootfs_dir)) - - return os.path.realpath(image_rootfs_dir) - - @classmethod - def do_prepare_partition(cls, part, source_params, cr, cr_workdir, - oe_builddir, bootimg_dir, kernel_dir, - krootfs_dir, native_sysroot): - """ - Called to do the actual content population for a partition i.e. it - 'prepares' the partition to be incorporated into the image. - In this case, prepare content for legacy bios boot partition. - """ - if part.rootfs_dir is None: - if not 'ROOTFS_DIR' in krootfs_dir: - raise WicError("Couldn't find --rootfs-dir, exiting") - - rootfs_dir = krootfs_dir['ROOTFS_DIR'] - else: - if part.rootfs_dir in krootfs_dir: - rootfs_dir = krootfs_dir[part.rootfs_dir] - elif part.rootfs_dir: - rootfs_dir = part.rootfs_dir - else: - raise WicError("Couldn't find --rootfs-dir=%s connection or " - "it is not a valid path, exiting" % part.rootfs_dir) - - part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir) - - new_rootfs = None - # Handle excluded paths. - if part.exclude_path is not None: - # We need a new rootfs directory we can delete files from. Copy to - # workdir. - new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs%d" % part.lineno)) - - if os.path.lexists(new_rootfs): - shutil.rmtree(os.path.join(new_rootfs)) - - copyhardlinktree(part.rootfs_dir, new_rootfs) - - for orig_path in part.exclude_path: - path = orig_path - if os.path.isabs(path): - logger.error("Must be relative: --exclude-path=%s" % orig_path) - sys.exit(1) - - full_path = os.path.realpath(os.path.join(new_rootfs, path)) - - # Disallow climbing outside of parent directory using '..', - # because doing so could be quite disastrous (we will delete the - # directory). - if not full_path.startswith(new_rootfs): - logger.error("'%s' points to a path outside the rootfs" % orig_path) - sys.exit(1) - - if path.endswith(os.sep): - # Delete content only. - for entry in os.listdir(full_path): - full_entry = os.path.join(full_path, entry) - if os.path.isdir(full_entry) and not os.path.islink(full_entry): - shutil.rmtree(full_entry) - else: - os.remove(full_entry) - else: - # Delete whole directory. - shutil.rmtree(full_path) - - part.prepare_rootfs(cr_workdir, oe_builddir, - new_rootfs or part.rootfs_dir, native_sysroot) |