From mboxrd@z Thu Jan 1 00:00:00 1970 X-GM-THRID: 6864480010557718528 X-Received: by 2002:aa7:92cb:: with SMTP id k11mr12201534pfa.233.1599297678742; Sat, 05 Sep 2020 02:21:18 -0700 (PDT) X-BeenThere: isar-users@googlegroups.com Received: by 2002:a63:79c6:: with SMTP id u189ls3508405pgc.9.gmail; Sat, 05 Sep 2020 02:21:18 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzNgWuCTtRDb3oGgEvMOdkkvTz2suxWaHu1djP4lbRXzpB0a9kcf5LJRhh9YwTfsFnvbt6n X-Received: by 2002:a05:6a00:16c2:: with SMTP id l2mr12687526pfc.112.1599297677759; Sat, 05 Sep 2020 02:21:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599297677; cv=none; d=google.com; s=arc-20160816; b=vJd6K4oQsc6ua0+sO91hnmdv4tZEEnFmhr4Isplc4uUR9WDS4nTprHjh+WNjS1HK76 vISZ7icv3iKIxO9AJ3kyJO/t3+T3D+e7eLJM3C09mxiN8mTEx8nQpcTD/D5dnRGlWa3M vwNnbk7IdUEmPTyBx3ebQ+8n0wgaEUNPRm1NGlXLe/ftMALXyrg+WVtKwUmzouPaQpG+ vA0o+lhwHyIxdSUoZxk4A9fJZKH1NaHYI1nj+3B7YV8pVETWV0Oi1UYUObM5E+Dk5jiv FIk0m8I9IU+QpM3hw+6C2RAXo7Fzes1BRBB8+oFrEDvCHbWFErwR7Zvk1G1DYYu6LKF7 n7ww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=t4hWM4jy+OPLXd3vcqK6bC5J5sWEG72ggppEb2avPz8=; b=oDxuuoxMvD5OJy5mTCg38y66IYUz1g+hjSQzC0GCssu6yKC9KeiKUu/1tRdyEZmjou 3WTWRaKjhrfzea+GP0E9/uHC/yNr0wH0mKIWK91k45gBdu8yj4PwIABg5D+7VBZq1ra1 xQnCBrDBDPRzPglRVf/eDYySe4mnsMajAwnY4NHDUEOG2V42CYFfDK6fFNlFRsvSemPw TNK3V3/jm04HLPBu+ZSW7/bzByJ1PJQtEAMrz0amjfreHmuSOgRtV2oIWTEynMmndCsZ qNKhp4qiL0moVKG187lcEYRmKmTfp0AIDCc2FwGz5fWTtdkUVwMXfR+xShd1ZCDWtdib FuNw== ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Dviibhnr; spf=pass (google.com: domain of vijaikumar.kanagarajan@gmail.com designates 2607:f8b0:4864:20::82b as permitted sender) smtp.mailfrom=vijaikumar.kanagarajan@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from mail-qt1-x82b.google.com (mail-qt1-x82b.google.com. [2607:f8b0:4864:20::82b]) by gmr-mx.google.com with ESMTPS id k5si441093pjl.1.2020.09.05.02.21.17 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 05 Sep 2020 02:21:17 -0700 (PDT) Received-SPF: pass (google.com: domain of vijaikumar.kanagarajan@gmail.com designates 2607:f8b0:4864:20::82b as permitted sender) client-ip=2607:f8b0:4864:20::82b; Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Dviibhnr; spf=pass (google.com: domain of vijaikumar.kanagarajan@gmail.com designates 2607:f8b0:4864:20::82b as permitted sender) smtp.mailfrom=vijaikumar.kanagarajan@gmail.com; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: by mail-qt1-x82b.google.com with SMTP id z2so6572649qtv.12 for ; Sat, 05 Sep 2020 02:21:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=t4hWM4jy+OPLXd3vcqK6bC5J5sWEG72ggppEb2avPz8=; b=Dviibhnr2hmYxZkbKdVT6jjQuEs7oBiOM42i9VPIY+76DiHM9vgg4ET+EYp3bp/ot+ WIZ/IGC7af8BlD+2oizuVRIFRso4cAdI/VJwkrwFkSiZgDKNorMgU7KPIOxRGXgcUcXg x4PJgqorp1ZRjjSKuz4LiR1Z11ctPhz9dt25S5uNHpv931/RUEIyHmvL4/2XSvWBU/9x pi7h2RGEoKyFYOd0j1vsCTikzkSxf/WGTszPtTW+PgErEk5UDdueV3GFO2/+SzNtkMmZ JoIBJZbXXunhZVbG+wy09t2FUER4EZQ8xIO9ZB+os9Pcfwcdl+sPNhjFhBQfBNaRIXMR F82A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=t4hWM4jy+OPLXd3vcqK6bC5J5sWEG72ggppEb2avPz8=; b=aAqx2bI3Rzck4cP3PIxhp0xQrYaxJfyILdQr+mmvz9ixjaNHM4dQ18yRMQF5ioHnTT F/+8/4O616YKE7DlloRP1QMlwEPCjGAs6/cMdtmJzjiNeVEXRGlyoZni9060yErRrIyG hBhcPj3zO9KuFHA8GRxgTA6dP66evsmhz3WdbNIjJVUEjR2DGR/nKExA92R8taVLBhxp eUJ2IlgGf51zoEhtaoOEHIdUSfQ59qmMC3WNs25Hj2RgbnfFqRor+53Rty5SDJZbwKS9 L4Sz10mEhOaYx+ty7+riIAbFdH8rmP5w8Dj5iScpO1meOfaBeQ6HSdw55Al2GdEQ0CAb KPIg== X-Gm-Message-State: AOAM532JHDs0lJHqmMKAyqQPm9TQN8ps9RufuGuO2EAE88lVUiB5zuBV AIgl62RvpcGMvAk5ejkiz/S+rZtKOIEox0Itvpbrfq5RScE= X-Received: by 2002:aed:3387:: with SMTP id v7mr12339738qtd.68.1599297676026; Sat, 05 Sep 2020 02:21:16 -0700 (PDT) MIME-Version: 1.0 References: <20200902185624.15044-1-Vijaikumar_Kanagarajan@mentor.com> <20200902185624.15044-2-Vijaikumar_Kanagarajan@mentor.com> <20200905110055.6d9ce1f1@md1za8fc.ad001.siemens.net> In-Reply-To: <20200905110055.6d9ce1f1@md1za8fc.ad001.siemens.net> From: vijai kumar Date: Sat, 5 Sep 2020 14:51:04 +0530 Message-ID: Subject: Re: [PATCH v2 01/10] wic: Update to the latest wic from openembedded core To: Henning Schild Cc: Vijai Kumar K , isar-users@googlegroups.com Content-Type: multipart/alternative; boundary="000000000000dead7205ae8d811e" X-TUID: /DrhSa+ubAa/ --000000000000dead7205ae8d811e Content-Type: text/plain; charset="UTF-8" On Sat, 5 Sep 2020 at 2:30 PM, Henning Schild wrote: > I assume if i took that commit and copied it over i would end up with > > 100% the same patch, right? Yes. This patch is just copying the wic from the oe core. Although, we have one other separate patch (P9)which is cherry picked from oe core over the top of this copy based commit. Thanks, Vijai Kumar K > > > > > On Thu, 3 Sep 2020 00:26:15 +0530 > > Vijai Kumar K wrote: > > > > > Update to the latest wic from OE-core. > > > > > > OE-core Revision: 532ae127c52c9f7b1d2e4ca5cbca91881d23a2ac > > > > > > Signed-off-by: Vijai Kumar K > > > --- > > > scripts/lib/scriptpath.py | 32 ++ > > > scripts/lib/wic/__init__.py | 14 +- > > > scripts/lib/wic/canned-wks/common.wks.inc | 2 +- > > > .../directdisk-bootloader-config.cfg | 8 +- > > > .../lib/wic/canned-wks/efi-bootdisk.wks.in | 3 + > > > scripts/lib/wic/canned-wks/mkhybridiso.wks | 2 +- > > > scripts/lib/wic/canned-wks/qemuriscv.wks | 3 + > > > .../lib/wic/canned-wks/qemux86-directdisk.wks | 2 +- > > > .../lib/wic/canned-wks/sdimage-bootpart.wks | 4 +- > > > .../lib/wic/canned-wks/systemd-bootdisk.wks | 4 +- > > > scripts/lib/wic/engine.py | 421 +++++++++++++++- > > > scripts/lib/wic/filemap.py | 170 ++++--- > > > scripts/lib/wic/help.py | 401 ++++++++++++++-- > > > scripts/lib/wic/ksparser.py | 115 +++-- > > > scripts/lib/wic/{utils => }/misc.py | 99 ++-- > > > scripts/lib/wic/partition.py | 234 ++++----- > > > scripts/lib/wic/pluginbase.py | 36 +- > > > scripts/lib/wic/plugins/imager/direct.py | 175 ++++--- > > > .../wic/plugins/source/bootimg-biosplusefi.py | 213 +++++++++ > > > scripts/lib/wic/plugins/source/bootimg-efi.py | 111 +++-- > > > .../wic/plugins/source/bootimg-partition.py | 153 ++++-- > > > .../lib/wic/plugins/source/bootimg-pcbios.py | 91 ++-- > > > scripts/lib/wic/plugins/source/fsimage.py | 56 --- > > > .../wic/plugins/source/isoimage-isohybrid.py | 185 +++---- > > > scripts/lib/wic/plugins/source/rawcopy.py | 44 +- > > > scripts/lib/wic/plugins/source/rootfs.py | 159 ++++-- > > > scripts/lib/wic/utils/__init__.py | 0 > > > scripts/lib/wic/utils/runner.py | 114 ----- > > > scripts/wic | 452 > > > +++++++++++++----- 29 files changed, 2283 insertions(+), 1020 > > > deletions(-) create mode 100644 scripts/lib/scriptpath.py > > > create mode 100644 scripts/lib/wic/canned-wks/efi-bootdisk.wks.in > > > create mode 100644 scripts/lib/wic/canned-wks/qemuriscv.wks > > > rename scripts/lib/wic/{utils => }/misc.py (70%) > > > create mode 100644 > > > scripts/lib/wic/plugins/source/bootimg-biosplusefi.py delete mode > > > 100644 scripts/lib/wic/plugins/source/fsimage.py delete mode 100644 > > > scripts/lib/wic/utils/__init__.py delete mode 100644 > > > scripts/lib/wic/utils/runner.py > > > > > > diff --git a/scripts/lib/scriptpath.py b/scripts/lib/scriptpath.py > > > new file mode 100644 > > > index 0000000..f32326d > > > --- /dev/null > > > +++ b/scripts/lib/scriptpath.py > > > @@ -0,0 +1,32 @@ > > > +# Path utility functions for OE python scripts > > > +# > > > +# Copyright (C) 2012-2014 Intel Corporation > > > +# Copyright (C) 2011 Mentor Graphics Corporation > > > +# > > > +# SPDX-License-Identifier: GPL-2.0-only > > > +# > > > + > > > +import sys > > > +import os > > > +import os.path > > > + > > > +def add_oe_lib_path(): > > > + basepath = os.path.abspath(os.path.dirname(__file__) + '/../..') > > > + newpath = basepath + '/meta/lib' > > > + sys.path.insert(0, newpath) > > > + > > > +def add_bitbake_lib_path(): > > > + basepath = os.path.abspath(os.path.dirname(__file__) + '/../..') > > > + bitbakepath = None > > > + if os.path.exists(basepath + '/bitbake/lib/bb'): > > > + bitbakepath = basepath + '/bitbake' > > > + else: > > > + # look for bitbake/bin dir in PATH > > > + for pth in os.environ['PATH'].split(':'): > > > + if os.path.exists(os.path.join(pth, '../lib/bb')): > > > + bitbakepath = os.path.abspath(os.path.join(pth, > > > '..')) > > > + break > > > + > > > + if bitbakepath: > > > + sys.path.insert(0, bitbakepath + '/lib') > > > + return bitbakepath > > > diff --git a/scripts/lib/wic/__init__.py b/scripts/lib/wic/__init__.py > > > index 85876b1..8556793 100644 > > > --- a/scripts/lib/wic/__init__.py > > > +++ b/scripts/lib/wic/__init__.py > > > @@ -1,20 +1,10 @@ > > > -#!/usr/bin/env python -tt > > > +#!/usr/bin/env python3 > > > # > > > # 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 > > > +# SPDX-License-Identifier: GPL-2.0-only > > > # > > > -# 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/scripts/lib/wic/canned-wks/common.wks.inc > > > b/scripts/lib/wic/canned-wks/common.wks.inc index 5cf2fd1..89880b4 > > > 100644 --- a/scripts/lib/wic/canned-wks/common.wks.inc > > > +++ b/scripts/lib/wic/canned-wks/common.wks.inc > > > @@ -1,3 +1,3 @@ > > > # 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 --ondisk sda > > > --fstype=ext4 --label platform --align 1024 +part / --source rootfs > > > --use-uuid --fstype=ext4 --label platform --align 1024 diff --git > > > a/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg > > > b/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg index > > > d5a07d2..c58e74a 100644 --- > > > a/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg +++ > > > b/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg @@ > > > -12,16 +12,16 @@ DEFAULT Graphics console boot LABEL Graphics console > > > boot KERNEL /vmlinuz > > > -APPEND label=boot root=/dev/sda2 rootwait > > > +APPEND label=boot rootwait > > > > > > LABEL Serial console boot > > > KERNEL /vmlinuz > > > -APPEND label=boot root=/dev/sda2 rootwait console=ttyS0,115200 > > > +APPEND label=boot rootwait console=ttyS0,115200 > > > > > > LABEL Graphics console install > > > KERNEL /vmlinuz > > > -APPEND label=install root=/dev/sda2 rootwait > > > +APPEND label=install rootwait > > > > > > LABEL Serial console install > > > KERNEL /vmlinuz > > > -APPEND label=install root=/dev/sda2 rootwait console=ttyS0,115200 > > > +APPEND label=install rootwait console=ttyS0,115200 > > > diff --git a/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in > > > b/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in new file mode 100644 > > > index 0000000..7300e65 > > > --- /dev/null > > > +++ b/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in > > > @@ -0,0 +1,3 @@ > > > +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/scripts/lib/wic/canned-wks/mkhybridiso.wks > > > b/scripts/lib/wic/canned-wks/mkhybridiso.wks index 9d34e9b..48c5ac4 > > > 100644 --- a/scripts/lib/wic/canned-wks/mkhybridiso.wks +++ > > > b/scripts/lib/wic/canned-wks/mkhybridiso.wks @@ -2,6 +2,6 @@ # > > > 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 +part /boot --source > > > isoimage-isohybrid > > > --sourceparams="loader=grub-efi,image_name=HYBRID_ISO_IMG" --ondisk > > > cd --label HYBRIDISO bootloader --timeout=15 --append="" diff --git > > > a/scripts/lib/wic/canned-wks/qemuriscv.wks > > > b/scripts/lib/wic/canned-wks/qemuriscv.wks new file mode 100644 index > > > 0000000..12c68b7 --- /dev/null +++ > > > b/scripts/lib/wic/canned-wks/qemuriscv.wks @@ -0,0 +1,3 @@ > > > +# short-description: Create qcow2 image for RISC-V QEMU machines > > > + > > > +part / --source rootfs --fstype=ext4 --label root --align 4096 > > > --size 5G diff --git > > > a/scripts/lib/wic/canned-wks/qemux86-directdisk.wks > > > b/scripts/lib/wic/canned-wks/qemux86-directdisk.wks index > > > a6518a0..22b4521 100644 --- > > > a/scripts/lib/wic/canned-wks/qemux86-directdisk.wks +++ > > > b/scripts/lib/wic/canned-wks/qemux86-directdisk.wks @@ -4,5 +4,5 @@ > > > include common.wks.inc > > > > > > -bootloader --timeout=0 --append="vga=0 > > > uvesafb.mode_option=640x480-32 root=/dev/vda2 rw mem=256M > > > ip=192.168.7.2::192.168.7.1:255.255.255.0 oprofile.timer=1 > > > rootfstype=ext4 " +bootloader --timeout=0 --append="rw > > > oprofile.timer=1 rootfstype=ext4 " diff --git > > > a/scripts/lib/wic/canned-wks/sdimage-bootpart.wks > > > b/scripts/lib/wic/canned-wks/sdimage-bootpart.wks index > > > 7ffd632..63bc4da 100644 --- > > > a/scripts/lib/wic/canned-wks/sdimage-bootpart.wks +++ > > > b/scripts/lib/wic/canned-wks/sdimage-bootpart.wks @@ -2,5 +2,5 @@ # > > > 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 +part /boot --source > > > bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot > > > --active --align 4 --size 16 +part / --source rootfs --ondisk mmcblk0 > > > --fstype=ext4 --label root --align 4 diff --git > > > a/scripts/lib/wic/canned-wks/systemd-bootdisk.wks > > > b/scripts/lib/wic/canned-wks/systemd-bootdisk.wks index > > > 4bd9d6a..95d7b97 100644 --- > > > a/scripts/lib/wic/canned-wks/systemd-bootdisk.wks +++ > > > b/scripts/lib/wic/canned-wks/systemd-bootdisk.wks @@ -2,10 +2,10 @@ # > > > 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 +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 +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/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py index > > > f59821f..018815b 100644 --- a/scripts/lib/wic/engine.py +++ > > > b/scripts/lib/wic/engine.py @@ -1,21 +1,7 @@ -# 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 G > NU > 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. +# SPDX-License-Identifier: GPL-2.0-only > > > # > > > # DESCRIPTION > > > > > > @@ -30,10 +16,18 @@ > > > > > > import logging > > > import os > > > +import tempfile > > > +import json > > > +import subprocess > > > +import re > > > + > > > +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.utils.misc import get_bitbake_var > > > +from wic.misc import get_bitbake_var, exec_cmd > > > > > > logger = logging.getLogger('wic') > > > > > > @@ -82,7 +76,8 @@ def find_canned_image(scripts_path, wks_file): > > > for fname in files: > > > if fname.endswith("~") or fname.endswith("#"): > > > continue > > > - if fname.endswith(".wks") and wks_file + ".wks" == > > > fname: > > > + if ((fname.endswith(".wks") and wks_file + ".wks" == > > > fname) or \ > > > + (fname.endswith(".wks.in") and wks_file + > > > ".wks.in" == fname)): fullpath = os.path.join(canned_wks_dir, fname) > > > return fullpath > > > return None > > > @@ -99,7 +94,7 @@ def list_canned_images(scripts_path): > > > for fname in files: > > > if fname.endswith("~") or fname.endswith("#"): > > > continue > > > - if fname.endswith(".wks"): > > > + if fname.endswith(".wks") or > > > fname.endswith(".wks.in"): fullpath = os.path.join(canned_wks_dir, > > > fname) with open(fullpath) as wks: > > > for line in wks: > > > @@ -108,7 +103,7 @@ def list_canned_images(scripts_path): > > > if idx != -1: > > > desc = line[idx + > > > len("short-description:"):].strip() break > > > - basename = os.path.splitext(fname)[0] > > > + basename = fname.split('.')[0] > > > print(" %s\t\t%s" % (basename.ljust(30), desc)) > > > > > > > > > @@ -184,7 +179,7 @@ def wic_create(wks_file, rootfs_dir, bootimg_dir, > > > kernel_dir, if not os.path.exists(options.outdir): > > > os.makedirs(options.outdir) > > > > > > - pname = 'direct' > > > + pname = options.imager > > > plugin_class = PluginMgr.get_plugins('imager').get(pname) > > > if not plugin_class: > > > raise WicError('Unknown plugin: %s' % pname) > > > @@ -201,17 +196,18 @@ def wic_list(args, scripts_path): > > > """ > > > Print the list of images or source plugins. > > > """ > > > - if len(args) < 1: > > > + if args.list_type is None: > > > return False > > > > > > - if args == ["images"]: > > > + if args.list_type == "images": > > > + > > > list_canned_images(scripts_path) > > > return True > > > - elif args == ["source-plugins"]: > > > + elif args.list_type == "source-plugins": > > > list_source_plugins() > > > return True > > > - elif len(args) == 2 and args[1] == "help": > > > - wks_file = args[0] > > > + 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. " > > > @@ -224,6 +220,381 @@ def wic_list(args, scripts_path): > > > > > > 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 > > > + # read paths from $PATH environment variable > > > + # if it fails, use hardcoded paths > > > + pathlist = "/bin:/usr/bin:/usr/sbin:/sbin/" > > > + try: > > > + self.paths = os.environ['PATH'] + ":" + pathlist > > > + except KeyError: > > > + self.paths = pathlist > > > + > > > + if native_sysroot: > > > + for path in pathlist.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() > > > + # skip over possible errors in exec_cmd output > > > + try: > > > + idx =splitted.index("BYT;") > > > + except ValueError: > > > + raise WicError("Error getting partition information > > > from %s" % (self.parted)) > > > + lsector_size, psector_size, self._ptable_format = > > > splitted[idx + 1].split(":")[3:6] > > > + self._lsector_size = int(lsector_size) > > > + self._psector_size = int(psector_size) > > > + for line in splitted[idx + 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","blkid"): > > > + aname = "_%s" % name > > > + if aname not in self.__dict__: > > > + setattr(self, aname, find_executable(name, > > > self.paths)) > > > + if aname not in self.__dict__ or > > > self.__dict__[aname] is None: > > > + 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" % pnum) > > > + 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 pnum not in self.partitions: > > > + raise WicError("Partition %s is not in the image" % pnum) > > > + > > > + 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, dest): > > > + """Copy partition image into wic image.""" > > > + pnum = dest.part if isinstance(src, str) else src.part > > > + > > > + if self.partitions[pnum].fstype.startswith('ext'): > > > + if isinstance(src, str): > > > + cmd = "printf 'cd {}\nwrite {} {}\n' | {} -w {}".\ > > > + format(os.path.dirname(dest.path), src, > > > os.path.basename(src), > > > + self.debugfs, > > > self._get_part_image(pnum)) > > > + else: # copy from wic > > > + # run both dump and rdump to support both files and > > > directory > > > + cmd = "printf 'cd {}\ndump /{} {}\nrdump /{} {}\n' | > > > {} {}".\ > > > + format(os.path.dirname(src.path), src.path, > > > + dest, src.path, dest, self.debugfs, > > > + self._get_part_image(pnum)) > > > + else: # fat > > > + if isinstance(src, str): > > > + cmd = "{} -i {} -snop {} ::{}".format(self.mcopy, > > > + > > > self._get_part_image(pnum), > > > + src, dest.path) > > > + else: > > > + cmd = "{} -i {} -snop ::{} {}".format(self.mcopy, > > > + > > > self._get_part_image(pnum), > > > + src.path, dest) > > > + > > > + exec_cmd(cmd, as_shell=True) > > > + self._put_part_image(pnum) > > > + > > > + def remove_ext(self, pnum, path, recursive): > > > + """ > > > + Remove files/dirs and their contents from the partition. > > > + This only applies to ext* partition. > > > + """ > > > + abs_path = re.sub('\/\/+', '/', path) > > > + cmd = "{} {} -wR 'rm \"{}\"'".format(self.debugfs, > > > + > > > self._get_part_image(pnum), > > > + abs_path) > > > + out = exec_cmd(cmd , as_shell=True) > > > + for line in out.splitlines(): > > > + if line.startswith("rm:"): > > > + if "file is a directory" in line: > > > + if recursive: > > > + # loop through content and delete them one > > > by one if > > > + # flaged with -r > > > + subdirs = iter(self.dir(pnum, > > > abs_path).splitlines()) > > > + next(subdirs) > > > + for subdir in subdirs: > > > + dir = subdir.split(':')[1].split(" ", > > > 1)[1] > > > + if not dir == "." and not dir == "..": > > > + self.remove_ext(pnum, "%s/%s" % > > > (abs_path, dir), recursive) + > > > + rmdir_out = exec_cmd("{} {} -wR 'rmdir > > > \"{}\"'".format(self.debugfs, > > > + > > > self._get_part_image(pnum), > > > + > > > abs_path.rstrip('/')) > > > + , as_shell=True) > > > + > > > + for rmdir_line in rmdir_out.splitlines(): > > > + if "directory not empty" in rmdir_line: > > > + raise WicError("Could not complete > > > operation: \n%s \n" > > > + "use -r to remove > > > non-empty directory" % rmdir_line) > > > + if rmdir_line.startswith("rmdir:"): > > > + raise WicError("Could not complete > > > operation: \n%s " > > > + "\n%s" % (str(line), > > > rmdir_line)) + > > > + else: > > > + raise WicError("Could not complete operation: > > > \n%s " > > > + "\nUnable to remove %s" % > > > (str(line), abs_path)) + > > > + def remove(self, pnum, path, recursive): > > > + """Remove files/dirs from the partition.""" > > > + partimg = self._get_part_image(pnum) > > > + if self.partitions[pnum].fstype.startswith('ext'): > > > + self.remove_ext(pnum, path, recursive) > > > + > > > + 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("{} -J {}".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 {} < {} ".format(self.sfdisk, > > > target, outf.name) > > > + exec_cmd(cmd, as_shell=True) > > > + > > > + 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]) > > > + # Align free space to a 2048 sector boundary. > > > YOCTO #12840. > > > + free = free - (free % 2048) > > > + if free is None: > > > + raise WicError("Can't get size of unpartitioned > > > space") + > > > + # calculate expanded partitions sizes > > > + sizes = {} > > > + num_auto_resize = 0 > > > + 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 > > > + num_auto_resize += 1 > > > + > > > + for num, part in > > > enumerate(parts['partitiontable']['partitions'], 1): > > > + if sizes.get(num) == -1: > > > + part['size'] += free // num_auto_resize > > > + > > > + # 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 '' > > > + out = exec_cmd("{} --probe > > > {}".format(self.blkid, self._get_part_image(pnum))) > > > + uuid = > > > out[out.index("UUID=\"")+6:out.index("UUID=\"")+42] > > > + 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.warning("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 file or directory to/from the vfat/ext partition of > > > + partitioned image. > > > + """ > > > + if isinstance(args.dest, str): > > > + disk = Disk(args.src.image, native_sysroot) > > > + else: > > > + disk = Disk(args.dest.image, native_sysroot) > > > + disk.copy(args.src, args.dest) > > > + > > > + > > > +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, > > > args.recursive_delete) + > > > +def wic_write(args, native_sysroot): > > > + """ > > > + Write image to a target device. > > > + """ > > > + disk = Disk(args.image, native_sysroot, ('fat', 'ext', > > > 'linux-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. diff --git a/scripts/lib/wic/filemap.py > > > b/scripts/lib/wic/filemap.py index 080668e..4d9da28 100644 > > > --- a/scripts/lib/wic/filemap.py > > > +++ b/scripts/lib/wic/filemap.py > > > @@ -1,13 +1,8 @@ > > > +# > > > # 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. > > > +# SPDX-License-Identifier: GPL-2.0-only > > > # > > > -# 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 @@ -22,6 +17,7 @@ and returns an instance of the class. > > > # * Too many instance attributes (R0902) > > > # pylint: disable=R0902 > > > > > > +import errno > > > import os > > > import struct > > > import array > > > @@ -34,14 +30,23 @@ def get_block_size(file_obj): > > > Returns block size for file object 'file_obj'. Errors are > > > indicated by the 'IOError' exception. > > > """ > > > - > > > - from fcntl import ioctl > > > - import struct > > > - > > > # Get the block size of the host file-system for the image file > > > by calling # the FIGETBSZ ioctl (number 2). > > > - binary_data = ioctl(file_obj, 2, struct.pack('I', 0)) > > > - return struct.unpack('I', binary_data)[0] > > > + try: > > > + binary_data = fcntl.ioctl(file_obj, 2, struct.pack('I', 0)) > > > + bsize = struct.unpack('I', binary_data)[0] > > > + except OSError: > > > + bsize = None > > > + > > > + # If ioctl causes OSError or give bsize to zero failback to > > > os.fstat > > > + 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): > > > """ > > > @@ -137,15 +142,6 @@ class _FilemapBase(object): > > > > > > 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 @@ -159,15 +155,6 @@ class _FilemapBase(object): > > > > > > 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 > > > @@ -185,9 +172,9 @@ def _lseek(file_obj, 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: > > > + if err.errno == errno.ENXIO: > > > return -1 > > > - elif err.errno == os.errno.EINVAL: > > > + elif err.errno == errno.EINVAL: > > > raise ErrorNotSupp("the kernel or file-system does not > > > support " "\"SEEK_HOLE\" and \"SEEK_DATA\"") > > > else: > > > @@ -228,7 +215,7 @@ class FilemapSeek(_FilemapBase): > > > try: > > > tmp_obj = tempfile.TemporaryFile("w+", dir=directory) > > > except IOError as err: > > > - raise ErrorNotSupp("cannot create a temporary in \"%s\": > > > %s" > > > + raise ErrorNotSupp("cannot create a temporary in \"%s\": > > > %s" \ % (directory, err)) > > > > > > try: > > > @@ -260,15 +247,10 @@ class FilemapSeek(_FilemapBase): > > > % (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. > > > + This function implements 'get_mapped_ranges()' depending > > > + on what is passed in the 'whence1' and 'whence2' arguments. > > > """ > > > > > > assert whence1 != whence2 > > > @@ -298,12 +280,6 @@ class FilemapSeek(_FilemapBase): > > > % (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 @@ -390,12 +366,12 @@ class > > > FilemapFiemap(_FilemapBase): 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: > > > + if err.errno == 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: > > > + if err.errno == errno.ENOTTY: > > > errstr = "FilemapFiemap: the FIEMAP ioctl is not > > > supported " \ "by the kernel" > > > self._log.debug(errstr) > > > @@ -417,10 +393,6 @@ class FilemapFiemap(_FilemapBase): > > > % (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 @@ -497,23 +469,28 @@ class FilemapFiemap(_FilemapBase): > > > % (first_prev, last_prev)) > > > yield (first_prev, last_prev) > > > > > > - def get_unmapped_ranges(self, start, count): > > > +class FilemapNobmap(_FilemapBase): > > > + """ > > > + This class is used when both the 'SEEK_DATA/HOLE' and FIEMAP are > > > not > > > + supported by the filesystem or kernel. > > > + """ > > > + > > > + def __init__(self, image, log=None): > > > """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 > > > + # Call the base class constructor first > > > + _FilemapBase.__init__(self, image, log) > > > + self._log.debug("FilemapNobmap: initializing") > > > > > > - 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 block_is_mapped(self, block): > > > + """Refer the '_FilemapBase' class for the documentation.""" > > > + return True > > > + > > > + def get_mapped_ranges(self, start, count): > > > + """Refer the '_FilemapBase' class for the documentation.""" > > > + self._log.debug("FilemapNobmap: get_mapped_ranges(%d, > > > %d(%d))" > > > + % (start, count, start + count - 1)) > > > + yield (start, start + count -1) > > > > > > def filemap(image, log=None): > > > """ > > > @@ -528,26 +505,56 @@ def filemap(image, log=None): > > > try: > > > return FilemapFiemap(image, log) > > > except ErrorNotSupp: > > > - return FilemapSeek(image, log) > > > + try: > > > + return FilemapSeek(image, log) > > > + except ErrorNotSupp: > > > + return FilemapNobmap(image, log) > > > > > > -def sparse_copy(src_fname, dst_fname, offset=0, skip=0): > > > - """Efficiently copy sparse file to or into another file.""" > > > - fmap = filemap(src_fname) > > > +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') > > > - dst_file.truncate(os.path.getsize(src_fname)) > > > + 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: > > > - fmap._f_image.seek(skip, os.SEEK_SET) > > > - else: > > > - fmap._f_image.seek(start, os.SEEK_SET) > > > - dst_file.seek(offset + start, os.SEEK_SET) > > > + 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 > > > @@ -556,7 +563,14 @@ def sparse_copy(src_fname, dst_fname, offset=0, > > > skip=0): while read < to_read: > > > if read + chunk_size > to_read: > > > chunk_size = to_read - read > > > - chunk = fmap._f_image.read(chunk_size) > > > + size = chunk_size > > > + if length and written + size > length: > > > + size = length - written > > > + chunk = fmap._f_image.read(size) > > > dst_file.write(chunk) > > > - read += chunk_size > > > + read += size > > > + written += size > > > + if written == length: > > > + dst_file.close() > > > + return > > > dst_file.close() > > > diff --git a/scripts/lib/wic/help.py b/scripts/lib/wic/help.py > > > index 148da89..bd3a2b9 100644 > > > --- a/scripts/lib/wic/help.py > > > +++ b/scripts/lib/wic/help.py > > > @@ -1,21 +1,6 @@ > > > -# 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. +# SPDX-License-Identifier: GPL-2.0-only > > > # > > > # DESCRIPTION > > > # This module implements some basic help invocation functions along > > > @@ -56,7 +41,7 @@ def wic_help(args, usage_str, subcommands): > > > """ > > > Subcommand help dispatcher. > > > """ > > > - if len(args) == 1 or not display_help(args[1], subcommands): > > > + if args.help_topic == None or not display_help(args.help_topic, > > > subcommands): print(usage_str) > > > > > > > > > @@ -82,19 +67,20 @@ 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: > > > + if not args.command: > > > logger.error("No subcommand specified, exiting") > > > parser.print_help() > > > return 1 > > > - elif args[0] == "help": > > > + elif args.command == "help": > > > wic_help(args, main_command_usage, subcommands) > > > - elif args[0] not in subcommands: > > > - logger.error("Unsupported subcommand %s, exiting\n", args[0]) > > > + elif args.command not in subcommands: > > > + logger.error("Unsupported subcommand %s, exiting\n", > > > args.command) parser.print_help() > > > return 1 > > > else: > > > - usage = subcommands.get(args[0], subcommand_error)[1] > > > - subcommands.get(args[0], subcommand_error)[0](args[1:], > > > usage) > > > + subcmd = subcommands.get(args.command, subcommand_error) > > > + usage = subcmd[1] > > > + subcmd[0](args, usage) > > > > > > > > > ## > > > @@ -130,10 +116,10 @@ wic_create_usage = """ > > > Create a new OpenEmbedded image > > > > > > usage: wic create [-o | --outdir > > > ] > > > - [-i | --infile ] > > > [-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 . > > > @@ -154,7 +140,7 @@ SYNOPSIS > > > [-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] > > > + [-c, --compress-with] [-m, --bmap] [--no-fstab-update] > > > > > > DESCRIPTION > > > This command creates an OpenEmbedded image based on the 'OE > > > @@ -226,6 +212,11 @@ DESCRIPTION > > > > > > 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 = """ > > > @@ -283,6 +274,243 @@ DESCRIPTION > > > details. > > > """ > > > > > > +wic_ls_usage = """ > > > + > > > + List content of a partitioned image > > > + > > > + usage: wic ls [:[]] [--native-sysroot > > > ] + > > > + 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 > > > + wic ls : > > > + wic ls : > > > + wic ls : --native-sysroot > > > + > > > +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 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 > > > + > > > + . 2017-05-11 10:54 > > > + .. 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/from the vfat or ext* partition > > > + > > > + usage: wic cp [--native-sysroot ] > > > + > > > + source/destination image in format :[] > > > + > > > + This command copies files or directories either > > > + - from local to vfat or ext* partitions of partitioned image > > > + - from vfat or ext* partitions of partitioned image to local > > > + > > > + See 'wic help cp' for more detailed instructions. > > > + > > > +""" > > > + > > > +wic_cp_help = """ > > > + > > > +NAME > > > + wic cp - copy files and directories to/from the vfat or ext* > > > partitions + > > > +SYNOPSIS > > > + wic cp : > > > + wic cp : > > > + wic cp : > > > + wic cp : --native-sysroot > > > + > > > +DESCRIPTION > > > + This command copies files or directories either > > > + - from local to vfat or ext* partitions of partitioned image > > > + - from vfat or ext* partitions of partitioned image to local > > > + > > > + 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 2017-05-24 18:15 > > > + loader 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 > > > + > > > + . 2017-05-24 18:15 > > > + .. 2017-05-24 18:15 > > > + boot 2017-05-24 18:15 > > > + test 2017-05-24 21:27 > > > + 4 files 0 bytes > > > + 15 675 392 bytes free > > > + > > > + The third form of the command copies file or directory from the > > > specified directory > > > + on the partition to local: > > > + $ wic cp > > > tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/vmlinuz > > > test + > > > + 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 : [--native-sysroot ] > > > + > > > + 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 : > > > + wic rm : --native-sysroot > > > + wic rm -r : > > > + > > > +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. > > > + > > > + The -r option is used to remove directories and their contents > > > + recursively,this only applies to ext* partition. > > > +""" > > > + > > > +wic_write_usage = """ > > > + > > > + Write image to a device > > > + > > > + usage: wic write [--expand [rules]] > > > [--native-sysroot ] + > > > + 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 > > > + wic write --expand auto > > > + wic write --expand 1:100M,2:300M > > > + wic write --native-sysroot > > > + > > > +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 > > > + :[,:...] 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 > > > @@ -308,7 +536,8 @@ DESCRIPTION > > > > > > 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. > > > + or 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 > > > @@ -346,6 +575,10 @@ DESCRIPTION > > > 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 > > > @@ -632,8 +865,11 @@ DESCRIPTION > > > Partitions with a 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. > > > + --ondrive, --ondisk, --use-uuid or --use-label partition > > > options must > > > + be used for each partition that specifies a mountpoint. Note > > > that with > > > + --use-{uuid,label} and non-root , including swap, > > > the mount > > > + program must understand the PARTUUID or LABEL syntax. This > > > currently > > > + excludes the busybox versions of these applications. > > > > > > > > > The following are supported 'part' options: > > > @@ -687,6 +923,8 @@ DESCRIPTION > > > apply to partitions created using '--source rootfs' (see > > > --source above). Valid values are: > > > > > > + vfat > > > + msdos > > > ext2 > > > ext3 > > > ext4 > > > @@ -706,6 +944,14 @@ DESCRIPTION > > > label is already in use by another > > > filesystem, a new label is created for the partition. > > > > > > + --use-label: This option is specific to wic. It makes wic > > > to use the > > > + label in /etc/fstab to specify a partition. If > > > the > > > + --use-label and --use-uuid are used at the > > > same time, > > > + we prefer the uuid because it is less likely > > > to cause > > > + name confliction. We don't support using this > > > parameter > > > + on the root partition since it requires an > > > initramfs to > > > + parse this value and we do not currently > > > support that. + > > > --active: Marks the partition as active. > > > > > > --align (in KBytes): This option is specific to wic and says > > > @@ -719,11 +965,31 @@ DESCRIPTION > > > bootloaders. > > > > > > --exclude-path: This option is specific to wic. It excludes > > > the given > > > - absolute path from the resulting image. If > > > the path > > > + 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. > > > > > > + --include-path: This option is specific to wic. It adds the > > > contents > > > + of the given path or a rootfs to the > > > resulting image. > > > + The option contains two fields, the origin > > > and the > > > + destination. When the origin is a rootfs, > > > it follows > > > + the same logic as the rootfs-dir argument > > > and the > > > + permissions and owners are kept. When the > > > origin is a > > > + path, it is relative to the directory in > > > which wic is > > > + running not the rootfs itself so use of an > > > absolute > > > + path is recommended, and the owner and > > > group is set to > > > + root:root. If no destination is given it is > > > + automatically set to the root of the > > > rootfs. This > > > + option only has an effect with the rootfs > > > source > > > + plugin. > > > + > > > + --change-directory: This option is specific to wic. It > > > changes to the > > > + given directory before copying the > > > files. This > > > + option is useful when we want to split > > > a rootfs in > > > + multiple partitions and we want to keep > > > the right > > > + permissions and usernames in all the > > > partitions. + > > > --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 > > > @@ -738,6 +1004,8 @@ DESCRIPTION > > > 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: > > > @@ -752,10 +1020,21 @@ DESCRIPTION > > > 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 > > > @@ -793,3 +1072,67 @@ DESCRIPTION > > > .wks files. > > > > > > """ > > > + > > > +wic_help_help = """ > > > +NAME > > > + wic help - display a help topic > > > + > > > +DESCRIPTION > > > + Specify a help topic to display it. Topics are shown above. > > > +""" > > > + > > > + > > > +wic_help = """ > > > +Creates a customized OpenEmbedded image. > > > + > > > +Usage: wic [--version] > > > + wic help [COMMAND or TOPIC] > > > + wic COMMAND [ARGS] > > > + > > > + usage 1: Returns the current version of Wic > > > + usage 2: Returns detailed help for a COMMAND or TOPIC > > > + usage 3: Executes COMMAND > > > + > > > + > > > +COMMAND: > > > + > > > + list - List available canned images and source plugins > > > + ls - List contents of partitioned image or partition > > > + rm - Remove files or directories from the vfat or ext* > > > partitions > > > + help - Show help for a wic COMMAND or TOPIC > > > + write - Write an image to a device > > > + cp - Copy files and directories to the vfat or ext* > > > partitions > > > + create - Create a new OpenEmbedded image > > > + > > > + > > > +TOPIC: > > > + overview - Presents an overall overview of Wic > > > + plugins - Presents an overview and API for Wic plugins > > > + kickstart - Presents a Wic kicstart file reference > > > + > > > + > > > +Examples: > > > + > > > + $ wic --version > > > + > > > + Returns the current version of Wic > > > + > > > + > > > + $ wic help cp > > > + > > > + Returns the SYNOPSIS and DESCRIPTION for the Wic "cp" command. > > > + > > > + > > > + $ wic list images > > > + > > > + Returns the list of canned images (i.e. *.wks files located in > > > + the /scripts/lib/wic/canned-wks directory. > > > + > > > + > > > + $ wic create mkefidisk -e core-image-minimal > > > + > > > + Creates an EFI disk image from artifacts used in a previous > > > + core-image-minimal build in standard BitBake locations > > > + (e.g. Cooked Mode). > > > + > > > +""" > > > diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py > > > index a039300..3453d9c 100644 > > > --- a/scripts/lib/wic/ksparser.py > > > +++ b/scripts/lib/wic/ksparser.py > > > @@ -1,21 +1,8 @@ > > > -#!/usr/bin/env python -tt > > > -# ex:ts=4:sw=4:sts=4:et > > > -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- > > > +#!/usr/bin/env python3 > > > # > > > # 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. +# SPDX-License-Identifier: GPL-2.0-only > > > # > > > # DESCRIPTION > > > # This module provides parser for kickstart format > > > @@ -28,14 +15,30 @@ > > > import os > > > import shlex > > > import logging > > > +import re > > > > > > from argparse import ArgumentParser, ArgumentError, ArgumentTypeError > > > > > > from wic.engine import find_canned > > > from wic.partition import Partition > > > +from wic.misc import get_bitbake_var > > > > > > logger = logging.getLogger('wic') > > > > > > +__expand_var_regexp__ = re.compile(r"\${[^{}@\n\t :]+}") > > > + > > > +def expand_line(line): > > > + while True: > > > + m = __expand_var_regexp__.search(line) > > > + if not m: > > > + return line > > > + key = m.group()[2:-1] > > > + val = get_bitbake_var(key) > > > + if val is None: > > > + logger.warning("cannot expand variable %s" % key) > > > + return line > > > + line = line[:m.start()] + val + line[m.end():] > > > + > > > class KickStartError(Exception): > > > """Custom exception.""" > > > pass > > > @@ -48,26 +51,31 @@ class KickStartParser(ArgumentParser): > > > def error(self, message): > > > raise ArgumentError(None, message) > > > > > > -def sizetype(arg): > > > - """ > > > - Custom type for ArgumentParser > > > - Converts size string in [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) > > > +def sizetype(default): > > > + def f(arg): > > > + """ > > > + Custom type for ArgumentParser > > > + Converts size string in [K|k|M|G] format into the > > > integer value > > > + """ > > > + try: > > > + suffix = default > > > + size = int(arg) > > > + except ValueError: > > > + try: > > > + suffix = arg[-1:] > > > + size = int(arg[:-1]) > > > + except ValueError: > > > + 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 > > > + if suffix == "k" or suffix == "K": > > > + return size > > > + if suffix == "M": > > > + return size * 1024 > > > + if suffix == "G": > > > + return size * 1024 * 1024 > > > > > > - raise ArgumentTypeError("Invalid size: %r" % arg) > > > + raise ArgumentTypeError("Invalid size: %r" % arg) > > > + return f > > > > > > def overheadtype(arg): > > > """ > > > @@ -114,7 +122,7 @@ def systemidtype(arg): > > > return arg > > > > > > class KickStart(): > > > - """"Kickstart parser implementation.""" > > > + """Kickstart parser implementation.""" > > > > > > DEFAULT_EXTRA_SPACE = 10*1024 > > > DEFAULT_OVERHEAD_FACTOR > > = 1.3 > > > @@ -133,30 +141,41 @@ class KickStart(): > > > part.add_argument('mountpoint', nargs='?') > > > part.add_argument('--active', action='store_true') > > > part.add_argument('--align', type=int) > > > + part.add_argument('--offset', type=sizetype("K")) > > > part.add_argument('--exclude-path', nargs='+') > > > - part.add_argument("--extra-space", type=sizetype) > > > + part.add_argument('--include-path', nargs='+', > > > action='append') > > > + part.add_argument('--change-directory') > > > + part.add_argument("--extra-space", type=sizetype("M")) > > > part.add_argument('--fsoptions', dest='fsopts') > > > - part.add_argument('--fstype') > > > + 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('--use-label', action='store_true') > > > 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') > > > + part.add_argument('--type', default='primary', > > > + choices = ('primary', 'logical')) > > > > > > # --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) > > > + sizeexcl.add_argument('--size', type=sizetype("M"), > > > default=0) > > > + sizeexcl.add_argument('--fixed-size', type=sizetype("M"), > > > 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') > > > @@ -184,6 +203,7 @@ class KickStart(): > > > line = line.strip() > > > lineno += 1 > > > if line and line[0] != '#': > > > + line = expand_line(line) > > > try: > > > line_args = shlex.split(line) > > > parsed = parser.parse_args(line_args) > > > @@ -191,6 +211,20 @@ class KickStart(): > > > raise KickStartError('%s:%d: %s' % \ > > > (confpath, lineno, err)) > > > if line.startswith('part'): > > > + # SquashFS does not support filesystem UUID > > > + if parsed.fstype == 'squashfs': > > > + if parsed.fsuuid: > > > + err = "%s:%d: SquashFS does not > > > support UUID" \ > > > + % (confpath, lineno) > > > + raise KickStartError(err) > > > + if parsed.label: > > > + err = "%s:%d: SquashFS does not > > > support LABEL" \ > > > + % (confpath, lineno) > > > + raise KickStartError(err) > > > + if parsed.use_label and not parsed.label: > > > + err = "%s:%d: Must set the label with > > > --label" \ > > > + % (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 @@ -219,6 +253,11 @@ class KickStart(): > > > elif line.startswith('bootloader'): > > > if not self.bootloader: > > > self.bootloader = parsed > > > + # Concatenate the strings set in APPEND > > > + append_var = get_bitbake_var("APPEND") > > > + if append_var: > > > + self.bootloader.append = ' > > > '.join(filter(None, \ > > > + > > > (self.bootloader.append, append_var))) else: > > > err = "%s:%d: more than one bootloader > > > specified" \ % (confpath, lineno) > > > diff --git a/scripts/lib/wic/utils/misc.py b/scripts/lib/wic/misc.py > > > similarity index 70% > > > rename from scripts/lib/wic/utils/misc.py > > > rename to scripts/lib/wic/misc.py > > > index c941112..91975ba 100644 > > > --- a/scripts/lib/wic/utils/misc.py > > > +++ b/scripts/lib/wic/misc.py > > > @@ -1,21 +1,7 @@ > > > -# 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. +# SPDX-License-Identifier: GPL-2.0-only > > > # > > > # DESCRIPTION > > > # This module provides a place to collect various wic-related utils > > > @@ -29,12 +15,12 @@ > > > import logging > > > import os > > > import re > > > +import subprocess > > > > > > from collections import defaultdict > > > from distutils import spawn > > > > > > from wic import WicError > > > -from wic.utils import runner > > > > > > logger = logging.getLogger('wic') > > > > > > @@ -43,6 +29,9 @@ NATIVE_RECIPES = {"bmaptool": "bmap-tools", > > > "grub-mkimage": "grub-efi", > > > "isohybrid": "syslinux", > > > "mcopy" > : > "mtools", > > > + "mdel" : "mtools", > > > + "mdeltree" : --000000000000dead7205ae8d811e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Sat, 5 Sep 2020 at 2:30 PM, Henning Schild <henning.schild@siemens.com> w= rote:
I assume if i took that commi= t and copied it over i would end up with

100% the same patch, right?=

Yes. This patch = is just copying the wic from the oe core. Although, we have one other separ= ate patch (P9)which is cherry picked from oe core over the top of this copy= based commit.

Thanks,
Vijai Kumar K



On Thu, 3 Sep 2020 00:26:15 +0530

Vijai Kumar K <Vijaiku= mar_Kanagarajan@mentor.com> wrote:



> Update to the= latest wic from OE-core.

>

> OE-core Revision: 532ae1= 27c52c9f7b1d2e4ca5cbca91881d23a2ac

>

> Signed-off-by: = Vijai Kumar K <Vijaikumar_Kanagarajan@mentor.com>

> ---
=
>=C2=A0 scripts/lib/scriptpath.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 32 ++

>=C2=A0 sc= ripts/lib/wic/__init__.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0|=C2=A0 14 +-

>=C2=A0 scripts/lib/wic/canned-= wks/common.wks.inc=C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A02 +-

>=C2=A0 = .../directdisk-bootloader-config.cfg=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A08 +-

>=C2=A0 .../lib/wic/canned-wks/efi-bootdisk.wks.i= n=C2=A0 =C2=A0 |=C2=A0 =C2=A03 +

>=C2=A0 scripts/lib/wic/cann= ed-wks/mkhybridiso.wks=C2=A0 =C2=A0 |=C2=A0 =C2=A02 +-

>=C2=A0 sc= ripts/lib/wic/canned-wks/qemuriscv.wks=C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A03 = +

>=C2=A0 .../lib/wic/canned-wks/qemux86-directdisk.wks |=C2=A0 = =C2=A02 +-

>=C2=A0 .../lib/wic/canned-wks/sdimage-bootpart.wks=C2= =A0 =C2=A0|=C2=A0 =C2=A04 +-

>=C2=A0 .../lib/wic/canned-wks/syste= md-bootdisk.wks=C2=A0 =C2=A0|=C2=A0 =C2=A04 +-

>=C2=A0 scripts/li= b/wic/engine.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0| 421 +++++++++++++++-

>=C2=A0 scripts/lib/wic/f= ilemap.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 | 170 ++++---

>=C2=A0 scripts/lib/wic/help.py=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| 401 = ++++++++++++++--

>=C2=A0 scripts/lib/wic/ksparser.py=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| 115 +++--

= >=C2=A0 scripts/lib/wic/{utils =3D> }/misc.py=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0|=C2=A0 99 ++--

>=C2=A0 scripts/lib/wic/partitio= n.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 | 234 ++= ++-----

>=C2=A0 scripts/lib/wic/pluginbase.py=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 36 +-

>=C2=A0 s= cripts/lib/wic/plugins/imager/direct.py=C2=A0 =C2=A0 =C2=A0 | 175 ++++---
>=C2=A0 .../wic/plugins/source/bootimg-biosplusefi.py | 213 ++++++= +++

>=C2=A0 scripts/lib/wic/plugins/source/bootimg-efi.py | 111 += ++--

>=C2=A0 .../wic/plugins/source/bootimg-partition.py=C2=A0 = =C2=A0| 153 ++++--

>=C2=A0 .../lib/wic/plugins/source/bootimg-pcb= ios.py=C2=A0 |=C2=A0 91 ++--

>=C2=A0 scripts/lib/wic/plugins/sour= ce/fsimage.py=C2=A0 =C2=A0 =C2=A0|=C2=A0 56 ---

>=C2=A0 .../wic/p= lugins/source/isoimage-isohybrid.py=C2=A0 | 185 +++----

>=C2=A0 s= cripts/lib/wic/plugins/source/rawcopy.py=C2=A0 =C2=A0 =C2=A0|=C2=A0 44 +-
>=C2=A0 scripts/lib/wic/plugins/source/rootfs.py=C2=A0 =C2=A0 =C2= =A0 | 159 ++++--

>=C2=A0 scripts/lib/wic/utils/__init__.py=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A00

>=C2=A0 = scripts/lib/wic/utils/runner.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0| 114 -----

>=C2=A0 scripts/wic=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| 452

> +++++++++++++----- 29 file= s changed, 2283 insertions(+), 1020

> deletions(-) create mode 10= 0644 scripts/lib/scriptpath.py

>=C2=A0 create mode 100644 scripts= /lib/wic/canned-wks/efi-bootdisk.wks.in

>=C2=A0 create mode = 100644 scripts/lib/wic/canned-wks/qemuriscv.wks

>=C2=A0 rename sc= ripts/lib/wic/{utils =3D> }/misc.py (70%)

>=C2=A0 create mode = 100644

> scripts/lib/wic/plugins/source/bootimg-biosplusefi.py de= lete mode

> 100644 scripts/lib/wic/plugins/source/fsimage.py dele= te mode 100644

> scripts/lib/wic/utils/__init__.py delete mode 10= 0644

> scripts/lib/wic/utils/runner.py

>

> d= iff --git a/scripts/lib/scriptpath.py b/scripts/lib/scriptpath.py

&g= t; new file mode 100644

> index 0000000..f32326d

> --- = /dev/null

> +++ b/scripts/lib/scriptpath.py

> @@ -0,0 += 1,32 @@

> +# Path utility functions for OE python scripts

= > +#

> +# Copyright (C) 2012-2014 Intel Corporation

>= ; +# Copyright (C) 2011 Mentor Graphics Corporation

> +#

&= gt; +# SPDX-License-Identifier: GPL-2.0-only

> +#

> +
> +import sys

> +import os

> +import os.path
> +

> +def add_oe_lib_path():

> +=C2=A0 =C2=A0= basepath =3D os.path.abspath(os.path.dirname(__file__) + '/../..')=

> +=C2=A0 =C2=A0 newpath =3D basepath + '/meta/lib'
<= br>> +=C2=A0 =C2=A0 sys.path.insert(0, newpath)

> +

>= ; +def add_bitbake_lib_path():

> +=C2=A0 =C2=A0 basepath =3D os.p= ath.abspath(os.path.dirname(__file__) + '/../..')

> +=C2= =A0 =C2=A0 bitbakepath =3D None

> +=C2=A0 =C2=A0 if os.path.exist= s(basepath + '/bitbake/lib/bb'):

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 bitbakepath =3D basepath + '/bitbake'

> +=C2=A0 = =C2=A0 else:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # look for bitbake/bi= n dir in PATH

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for pth in os.enviro= n['PATH'].split(':'):

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 if os.path.exists(os.path.join(pth, '../lib/bb'))= :

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bitb= akepath =3D os.path.abspath(os.path.join(pth,

> '..'))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break
> +

> +=C2=A0 =C2=A0 if bitbakepath:

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 sys.path.insert(0, bitbakepath + '/lib')
> +=C2=A0 =C2=A0 return bitbakepath

> diff --git a/scripts/l= ib/wic/__init__.py b/scripts/lib/wic/__init__.py

> index 85876b1.= .8556793 100644

> --- a/scripts/lib/wic/__init__.py

> += ++ b/scripts/lib/wic/__init__.py

> @@ -1,20 +1,10 @@

> = -#!/usr/bin/env python -tt

> +#!/usr/bin/env python3

>= =C2=A0 #

>=C2=A0 # Copyright (c) 2007 Red Hat, Inc.

>= =C2=A0 # Copyright (c) 2011 Intel, Inc.

>=C2=A0 #

> -# = This program is free software; you can redistribute it and/or

> m= odify it -# under the terms of the GNU General Public License as

>= ; published by the Free -# Software Foundation; version 2 of the License
> +# SPDX-License-Identifier: GPL-2.0-only

>=C2=A0 #
<= br>> -# 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.=C2= =A0 See the GNU

> General Public License -# for more details.
=
> -#

> -# You should have received a copy of the GNU Gener= al 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.

>=C2=A0 class WicEr= ror(Exception):

>=C2=A0 =C2=A0 =C2=A0 pass

> diff --git= a/scripts/lib/wic/canned-wks/common.wks.inc

> b/scripts/lib/wic/= canned-wks/common.wks.inc index 5cf2fd1..89880b4

> 100644 --- a/s= cripts/lib/wic/canned-wks/common.wks.inc

> +++ b/scripts/lib/wic/= canned-wks/common.wks.inc

> @@ -1,3 +1,3 @@

>=C2=A0 # T= his file is included into 3 canned wks files from this directory

>= ;=C2=A0 part /boot --source bootimg-pcbios --ondisk sda --label boot
> --active --align 1024 -part / --source rootfs --ondisk sda

>= ; --fstype=3Dext4 --label platform --align 1024 +part / --source rootfs
=
> --use-uuid --fstype=3Dext4 --label platform --align 1024 diff --gi= t

> a/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg=

> b/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg = index

> d5a07d2..c58e74a 100644 ---

> a/scripts/lib/wic= /canned-wks/directdisk-bootloader-config.cfg +++

> b/scripts/lib/= wic/canned-wks/directdisk-bootloader-config.cfg @@

> -12,16 +12,1= 6 @@ DEFAULT Graphics console boot LABEL Graphics console

> boot = KERNEL /vmlinuz

> -APPEND label=3Dboot root=3D/dev/sda2 rootwait<= br>
> +APPEND label=3Dboot rootwait

>=C2=A0

>=C2= =A0 LABEL Serial console boot

>=C2=A0 KERNEL /vmlinuz

>= -APPEND label=3Dboot root=3D/dev/sda2 rootwait console=3DttyS0,115200
<= br>> +APPEND label=3Dboot rootwait console=3DttyS0,115200

>=C2= =A0

>=C2=A0 LABEL Graphics console install

>=C2=A0 KER= NEL /vmlinuz

> -APPEND label=3Dinstall root=3D/dev/sda2 rootwait<= br>
> +APPEND label=3Dinstall rootwait

>=C2=A0

>= =C2=A0 LABEL Serial console install

>=C2=A0 KERNEL /vmlinuz
> -APPEND label=3Dinstall root=3D/dev/sda2 rootwait console=3DttyS0,11= 5200

> +APPEND label=3Dinstall rootwait console=3DttyS0,115200
> diff --git a/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in<= br>
> b/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in new file = mode 100644

> index 0000000..7300e65

> --- /dev/null
> +++ b/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in

= > @@ -0,0 +1,3 @@

> +bootloader --ptable gpt

> +part= /boot --source rootfs --rootfs-dir=3D${IMAGE_ROOTFS}/boot

> --fs= type=3Dvfat --label boot --active --align 1024 --use-uuid

> --ove= rhead-factor 1.0 +part / --source rootfs --fstype=3Dext4 --label

>= ; root --align 1024 --exclude-path boot/ diff --git

> a/scripts/l= ib/wic/canned-wks/mkhybridiso.wks

> b/scripts/lib/wic/canned-wks/= mkhybridiso.wks index 9d34e9b..48c5ac4

> 100644 --- a/scripts/lib= /wic/canned-wks/mkhybridiso.wks +++

> b/scripts/lib/wic/canned-wk= s/mkhybridiso.wks @@ -2,6 +2,6 @@ #

> long-description: Creates a= n EFI and legacy bootable hybrid ISO image

> # which can be used = on optical media as well as USB media.

> -part /boot --source is= oimage-isohybrid

> --sourceparams=3D"loader=3Dgrub-efi,image= _name=3DHYBRID_ISO_IMG" --ondisk

> cd --label HYBRIDISO --fs= type=3Dext4 +part /boot --source

> isoimage-isohybrid

>= --sourceparams=3D"loader=3Dgrub-efi,image_name=3DHYBRID_ISO_IMG"= --ondisk

> cd --label HYBRIDISO bootloader=C2=A0 --timeout=3D15= =C2=A0 --append=3D"" diff --git

> a/scripts/lib/wic/can= ned-wks/qemuriscv.wks

> b/scripts/lib/wic/canned-wks/qemuriscv.wk= s new file mode 100644 index

> 0000000..12c68b7 --- /dev/null +++=

> b/scripts/lib/wic/canned-wks/qemuriscv.wks @@ -0,0 +1,3 @@
=
> +# short-description: Create qcow2 image for RISC-V QEMU machines<= br>
> +

> +part / --source rootfs --fstype=3Dext4 --label r= oot --align 4096

> --size 5G diff --git

> a/scripts/lib= /wic/canned-wks/qemux86-directdisk.wks

> b/scripts/lib/wic/canned= -wks/qemux86-directdisk.wks index

> a6518a0..22b4521 100644 ---
> a/scripts/lib/wic/canned-wks/qemux86-directdisk.wks +++

&= gt; b/scripts/lib/wic/canned-wks/qemux86-directdisk.wks @@ -4,5 +4,5 @@
>=C2=A0 include common.wks.inc

>=C2=A0

> -boot= loader=C2=A0 --timeout=3D0=C2=A0 --append=3D"vga=3D0

> uvesa= fb.mode_option=3D640x480-32 root=3D/dev/vda2 rw mem=3D256M

> ip= =3D192.168.7.2::192.168.7.1:255.255.255.0 oprofile.timer=3D1
> rootfstype=3Dext4 " +bootloader=C2=A0 --timeout=3D0=C2=A0 -= -append=3D"rw

> oprofile.timer=3D1 rootfstype=3Dext4 " = diff --git

> a/scripts/lib/wic/canned-wks/sdimage-bootpart.wks
> b/scripts/lib/wic/canned-wks/sdimage-bootpart.wks index

&g= t; 7ffd632..63bc4da 100644 ---

> a/scripts/lib/wic/canned-wks/sdi= mage-bootpart.wks +++

> b/scripts/lib/wic/canned-wks/sdimage-boot= part.wks @@ -2,5 +2,5 @@ #

> long-description: Creates a partitio= ned SD card image. Boot files #

> are located in the first vfat p= artition. -part /boot --source

> bootimg-partition --ondisk mmcbl= k --fstype=3Dvfat --label boot --active

> --align 4 --size 16 -pa= rt / --source rootfs --ondisk mmcblk

> --fstype=3Dext4 --label ro= ot --align 4 +part /boot --source

> bootimg-partition --ondisk mm= cblk0 --fstype=3Dvfat --label boot

> --active --align 4 --size 16= +part / --source rootfs --ondisk mmcblk0

> --fstype=3Dext4 --lab= el root --align 4 diff --git

> a/scripts/lib/wic/canned-wks/syste= md-bootdisk.wks

> b/scripts/lib/wic/canned-wks/systemd-bootdisk.w= ks index

> 4bd9d6a..95d7b97 100644 ---

> a/scripts/lib/= wic/canned-wks/systemd-bootdisk.wks +++

> b/scripts/lib/wic/canne= d-wks/systemd-bootdisk.wks @@ -2,10 +2,10 @@ #

> long-description= : Creates a partitioned EFI disk image that the user

> # can dire= ctly dd to boot media. The selected bootloader is

> systemd-boot.= -part /boot --source bootimg-efi

> --sourceparams=3D"loader= =3Dsystemd-boot" --ondisk sda --label msdos

> --active --ali= gn 1024 +part /boot --source bootimg-efi

> --sourceparams=3D"= ;loader=3Dsystemd-boot" --ondisk sda --label msdos

> --activ= e --align 1024 --use-uuid part / --source rootfs --ondisk sda

> -= -fstype=3Dext4 --label platform --align 1024 --use-uuid -part swap

&= gt; --ondisk sda --size 44 --label swap1 --fstype=3Dswap +part swap

= > --ondisk sda --size 44 --label swap1 --fstype=3Dswap --use-uuid
> bootloader --ptable gpt --timeout=3D5 --append=3D"rootwait
> rootfstype=3Dext4 console=3DttyS0,115200 console=3Dtty0" diff -= -git

> a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py in= dex

> f59821f..018815b 100644 --- a/scripts/lib/wic/engine.py +++=

> b/scripts/lib/wic/engine.py @@ -1,21 +1,7 @@ -# ex:ts=3D4:sw= =3D4:sts=3D4:et

> -# -*- tab-width: 4; c-basic-offset: 4; indent-= tabs-mode: nil -*-

>=C2=A0 #

>=C2=A0 # Copyright (c) 20= 13, Intel Corporation.

> -# All rights reserved.

>=C2= =A0 #

> -# 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 th= e Free Software Foundation.

> -#

> -# This program is d= istributed in the hope that it will be useful,

> -# but WITHOUT A= NY WARRANTY; without even the implied warranty of

> -# MERCHANTAB= ILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2=A0 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. +# SPDX-License-Identifier: GPL-2.0-only

>=C2= =A0 #

>=C2=A0 # DESCRIPTION

>=C2=A0

> @@ -30= ,10 +16,18 @@

>=C2=A0

>=C2=A0 import logging

&g= t;=C2=A0 import os

> +import tempfile

> +import json
> +import subprocess

> +import re

> +

&g= t; +from collections import namedtuple, OrderedDict

> +from distu= tils.spawn import find_executable

>=C2=A0

>=C2=A0 from= wic import WicError

> +from wic.filemap import sparse_copy
>=C2=A0 from wic.pluginbase import PluginMgr

> -from wic.uti= ls.misc import get_bitbake_var

> +from wic.misc import get_bitbak= e_var, exec_cmd

>=C2=A0

>=C2=A0 logger =3D logging.get= Logger('wic')

>=C2=A0

> @@ -82,7 +76,8 @@ def = find_canned_image(scripts_path, wks_file):

>=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 for fname in files:

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if fname.endswith("~&= quot;) or fname.endswith("#"):

>=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue

>= ; -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if fname.endswit= h(".wks") and wks_file + ".wks" =3D=3D

> fnam= e:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if = ((fname.endswith(".wks") and wks_file + ".wks" =3D=3D
> fname) or \

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(fname.endswith(".wks.in") and wks_file +<= br>
> ".wks.in" =3D=3D fname)): fullpath =3D os.path.join(canned_wk= s_dir, fname)

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 return fullpath

>=C2=A0 =C2=A0 =C2=A0= return None

> @@ -99,7 +94,7 @@ def list_canned_images(scripts_p= ath):

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for fname= in files:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 if fname.endswith("~") or fname.endswith("#"= ):

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 continue

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 if fname.endswith(".wks"):

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if fname.endswith(&quo= t;.wks") or

> fname.endswith(".wks.in"): fullpath =3D os.p= ath.join(canned_wks_dir,

> fname) with open(fullpath) as wks:
=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 for line in wks:

> @@ -108,7 +103,7 @@ d= ef list_canned_images(scripts_path):

>=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 if idx !=3D -1:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 desc =3D line[idx +

> len("short-description:"):].s= trip() break

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 basename =3D os.path.splitext(fname)[0]

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 basen= ame =3D fname.split('.')[0]

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 print("=C2=A0 %s\t\t%= s" % (basename.ljust(30), desc))

>=C2=A0

>=C2=A0 =

> @@ -184,7 +179,7 @@ def wic_create(wks_file, rootfs_dir, booti= mg_dir,

> kernel_dir, if not os.path.exists(options.outdir):
<= br>>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 os.makedirs(options.outdir)
>=C2=A0

> -=C2=A0 =C2=A0 pname =3D 'direct'

= > +=C2=A0 =C2=A0 pname =3D options.imager

>=C2=A0 =C2=A0 =C2= =A0 plugin_class =3D PluginMgr.get_plugins('imager').get(pname)
=
>=C2=A0 =C2=A0 =C2=A0 if not plugin_class:

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 raise WicError('Unknown plugin: %s' % pname)
> @@ -201,17 +196,18 @@ def wic_list(args, scripts_path):

&= gt;=C2=A0 =C2=A0 =C2=A0 """

>=C2=A0 =C2=A0 =C2=A0 = Print the list of images or source plugins.

>=C2=A0 =C2=A0 =C2=A0= """

> -=C2=A0 =C2=A0 if len(args) < 1:

= > +=C2=A0 =C2=A0 if args.list_type is None:

>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 return False

>=C2=A0

> -=C2=A0 =C2= =A0 if args =3D=3D ["images"]:

> +=C2=A0 =C2=A0 if args= .list_type =3D=3D "images":

> +

>=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 list_canned_images(scripts_path)

>=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 return True

> -=C2=A0 =C2=A0 elif ar= gs =3D=3D ["source-plugins"]:

> +=C2=A0 =C2=A0 elif arg= s.list_type =3D=3D "source-plugins":

>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 list_source_plugins()

>=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return True

> -=C2=A0 =C2=A0 elif len(args) =3D=3D 2 a= nd args[1] =3D=3D "help":

> -=C2=A0 =C2=A0 =C2=A0 =C2= =A0 wks_file =3D args[0]

> +=C2=A0 =C2=A0 elif len(args.help_for)= =3D=3D 1 and args.help_for[0] =3D=3D 'help':

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 wks_file =3D args.list_type

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 fullpath =3D find_canned_image(scripts_path, wks_file)=

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if not fullpath:

>= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise WicError("No im= age named %s found, exiting. "

> @@ -224,6 +220,381 @@ def w= ic_list(args, scripts_path):

>=C2=A0

>=C2=A0 =C2=A0 = =C2=A0 return False

>=C2=A0

> +

> +class Dis= k:

> +=C2=A0 =C2=A0 def __init__(self, imagepath, native_sysroot,= fstypes=3D('fat',

> 'ext')):

> +=C2=A0= =C2=A0 =C2=A0 =C2=A0 self.imagepath =3D imagepath

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 self.native_sysroot =3D native_sysroot

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 self.fstypes =3D fstypes

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 self._partitions =3D None

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 self._partimages =3D {}

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0= self._lsector_size =3D None

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.= _psector_size =3D None

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._ptabl= e_format =3D None

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # = find parted

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # read paths from $PAT= H environment variable

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # if it fai= ls, use hardcoded paths

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 pathlist = =3D "/bin:/usr/bin:/usr/sbin:/sbin/"

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 try:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 s= elf.paths =3D os.environ['PATH'] + ":" + pathlist

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 except KeyError:

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.paths =3D pathlist

> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if native_sysroot:

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for path in pathlist.split(':'):=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.= paths =3D "%s%s:%s" % (native_sysroot, path,

> self.pat= hs) +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.parted =3D find_executa= ble("parted", self.paths)

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 if not self.parted:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 raise WicError("Can't find executable parted")

>= ; +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.partitions =3D self.get_p= artitions()

> +

> +=C2=A0 =C2=A0 def __del__(self):
=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for path in self._partimages.values()= :

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 os.unlink(path)
> +

> +=C2=A0 =C2=A0 def get_partitions(self):

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if self._partitions is None:

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._partitions =3D OrderedDict(= )

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D exec_cmd(&= quot;%s -sm %s unit B print" % (self.parted,

> self.imagepat= h))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 parttype =3D nam= edtuple("Part", "pnum start end size

> fstype"= ;)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 splitted =3D out.= splitlines()

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # skip = over possible errors in exec_cmd output

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 try:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 idx =3Dsplitted.index("BYT;")

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 except ValueError:

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise WicError(&quo= t;Error getting partition information

> from %s" % (self.par= ted))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lsector_size, = psector_size, self._ptable_format =3D

> splitted[idx + 1].split(&= quot;:")[3:6]

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 s= elf._lsector_size =3D int(lsector_size)

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 self._psector_size =3D int(psector_size)

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for line in splitted[idx + 2:]:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pnum, s= tart, end, size, fstype =3D line.split(':')[:5]

> +=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 partition =3D parttype(in= t(pnum), int(start[:-1]),

> int(end[:-1]),

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int(size[:-1]), fstype)=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.= _partitions[pnum] =3D partition

> +

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 return self._partitions

> +

> +=C2=A0 =C2= =A0 def __getattr__(self, name):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 &= quot;""Get path to the executable in a lazy way."""= ;

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if name in ("mdir", &q= uot;mcopy", "mdel", "mdeltree", "sfdisk"= ,

> "e2fsck",

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "resize2fs", "mksw= ap", "mkdosfs",

> "debugfs","blkid&= quot;):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 aname =3D &q= uot;_%s" % name

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= if aname not in self.__dict__:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 setattr(self, aname, find_executable(name,
<= br>> self.paths))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 if aname not in self.__dict__ or

> self.__dict__[a= name] is None:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 raise WicError("Can't find executable
=
> '{}'".format(name))

> +=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 return self.__dict__[aname]

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 return self.__dict__[name]

> +

> +=C2= =A0 =C2=A0 def _get_part_image(self, pnum):

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 if pnum not in self.partitions:

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 raise WicError("Partition %s is not in the im= age" % pnum)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 part =3D self.pa= rtitions[pnum]

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # check if fstype i= s supported

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for fstype in self.fst= ypes:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if part.fstype= .startswith(fstype):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 break

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 else:

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise WicError("Not su= pported fstype:

> {}".format(part.fstype))

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 if pnum not in self._partimages:

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tmpf =3D tempfile.NamedTemporaryFile= (prefix=3D"wic-part")

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 dst_fname =3D tmpf.name

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 tmpf.close()

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 sparse_copy(self.imagepath, dst_fname, skip=3Dpart.start,

>= ; length=3Dpart.size)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 self._partimages[pnum] =3D dst_fname

> +

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 return self._partimages[pnum]

> +

>= ; +=C2=A0 =C2=A0 def _put_part_image(self, pnum):

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 """Put partition image into partitioned im= age."""

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 sparse_copy= (self._partimages[pnum], self.imagepath,

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 seek=3Dself.partitions[pnu= m].start)

> +

> +=C2=A0 =C2=A0 def dir(self, pnum, path= ):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if pnum not in self.partitions:=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise WicError(&quo= t;Partition %s is not in the image" % pnum)

> +

> = +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.partitions[pnum].fstype.startswith(= 9;ext'):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return = exec_cmd("{} {} -R 'ls -l

> {}'".format(self.de= bugfs,

> +

> self._get_part_image(pnum),

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0path),

> a= s_shell=3DTrue)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 else: # fat
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return exec_cmd("{} -= i {} ::{}".format(self.mdir,

> +

> self._get_part_= image(pnum),

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0path))

&g= t; +

> +=C2=A0 =C2=A0 def copy(self, src, dest):

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 """Copy partition image into wic im= age."""

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 pnum =3D=C2= =A0 dest.part if isinstance(src, str) else src.part

> +

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.partitions[pnum].fstype.startswith(= 'ext'):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if i= sinstance(src, str):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 cmd =3D "printf 'cd {}\nwrite {} {}\n' | {} -w = {}".\

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 format(os.path.dirname(dest.path), src,

= > os.path.basename(src),

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.= debugfs,

> self._get_part_image(pnum))

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 else: # copy from wic

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # run both dump and rdump to = support both files and

> directory

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D "printf 'cd {}\ndum= p /{} {}\nrdump /{} {}\n' |

> {} {}".\

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 f= ormat(os.path.dirname(src.path), src.path,

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0dest, src.path, dest, self.debugfs,

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0self._get_part_image(pnum))

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 else: # fat

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 if isinstance(src, str):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D "{} -i {} -snop {} ::{}".format(= self.mcopy,

> +

> self._get_part_image(pnum),

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 src, dest.path)

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 else:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D "{} -i {} -snop ::{} {}".form= at(self.mcopy,

> +

> self._get_part_image(pnum),
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 src.path, dest)

> +

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 exec_cmd(cmd, as_shell=3DTrue)

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._put_part_image(pnum)

> +
> +=C2=A0 =C2=A0 def remove_ext(self, pnum, path, recursive):

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 """

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 Remove files/dirs and their contents from the partition.<= br>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 This only applies to ext* partitio= n.

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 """

> = +=C2=A0 =C2=A0 =C2=A0 =C2=A0 abs_path =3D re.sub('\/\/+', '/= 9;, path)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D "{} {} -wR = 'rm \"{}\"'".format(self.debugfs,

> +
<= br>> self._get_part_image(pnum),

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 abs_path)

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D exec_cmd(cmd , as_shell=3DTrue)
=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 for line in out.splitlines():

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if line.startswith("rm= :"):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 if "file is a directory" in line:

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if recursive:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 # loop through content and delete them one

> by= one if

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # flaged with -r

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 subd= irs =3D iter(self.dir(pnum,

> abs_path).splitlines())

>= +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 next(subdirs)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for subdir in subdirs:
=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dir =3D subdir.split(':')[1].spl= it(" ",

> 1)[1]

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 i= f not dir =3D=3D "." and not dir =3D=3D "..":

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.remove_ext(pnum, "%s/%s= " %

> (abs_path, dir), recursive) +

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 rmdir_out =3D e= xec_cmd("{} {} -wR 'rmdir

> \"{}\"'".= format(self.debugfs,

> +

> self._get_part_image(pnum),<= br>
> +

> abs_path.rstrip('/'))

> +=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 , as_shell=3DTrue)

> +

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for r= mdir_line in rmdir_out.splitlines():

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if "direct= ory not empty" in rmdir_line:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 rais= e WicError("Could not complete

> operation: \n%s \n"
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 "use -r to remove

> non-empty directory&qu= ot; % rmdir_line)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if rmdir_line.startswith("rm= dir:"):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise WicError("Could= not complete

> operation: \n%s "

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "\n= %s" % (str(line),

> rmdir_line)) +

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else:

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise WicError(= "Could not complete operation:

> \n%s "

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "\nUnable to remo= ve %s" %

> (str(line), abs_path)) +

> +=C2=A0 =C2= =A0 def remove(self, pnum, path, recursive):

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 """Remove files/dirs from the partition."&qu= ot;"

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 partimg =3D self._get_pa= rt_image(pnum)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if self.partitions[= pnum].fstype.startswith('ext'):

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 self.remove_ext(pnum, path, recursive)

> +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 else: # fat

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D "{} -i {} ::{}".format(se= lf.mdel, partimg, path)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 try:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 exec_cmd(cmd)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ex= cept WicError as err:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 if "not found" in str(err) or "non empty&q= uot; in

> str(err):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # mdel outputs 'File ... not fou= nd' or

> 'directory .. non empty"

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # try to= use mdeltree as path could be a

> directory

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D &quo= t;{} -i {} ::{}".format(self.mdeltree,

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0partimg, path)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 exec_cmd(cmd)

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else:

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise err

&= gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._put_part_image(pnum)

> +
> +=C2=A0 =C2=A0 def write(self, target, expand):

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 """Write disk image to the media or= file."""

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 def write= _sfdisk_script(outf, parts):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 for key, val in parts['partitiontable'].items():

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if key in (&q= uot;partitions", "device", "firstlba",

>= "lastlba"):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if key =3D=3D "id":

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ke= y =3D "label-id"

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 outf.write("{}: {}\n".format(key, val))
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 outf.write("\n"= ;)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for part in parts= ['partitiontable']['partitions']:

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line =3D ''

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for name in (&#= 39;attrs', 'name', 'size', 'type',

> = 'uuid'):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 if name =3D=3D 'size' and part['type&#= 39;] =3D=3D 'f':

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # don't write size for= extended partition

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 val =3D part.ge= t(name)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 if val:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line +=3D '{}=3D{}, &#= 39;.format(name, val)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 if line:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line =3D line[:-2] # strip ', '<= br>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if par= t.get('bootable'):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line +=3D ' ,bootable'

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 outf.write(&quo= t;{}\n".format(line))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 outf.flush()

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = def read_ptable(path):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 out =3D exec_cmd("{} -J {}".format(self.sfdisk, path))
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return json.loads(out)
=
> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 def write_ptable(parts,= target):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 with tempf= ile.NamedTemporaryFile(prefix=3D"wic-sfdisk-",

> mode= =3D'w') as outf:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 write_sfdisk_script(outf, parts)

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D "{} --no-rere= ad {} < {} ".format(self.sfdisk,

> target, outf.name)

&= gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 exec_cmd(cmd, = as_shell=3DTrue)

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if = expand is None:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 spar= se_copy(self.imagepath, target)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 el= se:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # copy first sec= tors that may contain bootloader

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 sparse_copy(self.imagepath, target, length=3D2048 *

&g= t; self._lsector_size) +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 # copy source partition table to the target

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 parts =3D read_ptable(self.imagepath)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 write_ptable(parts, targe= t)

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # g= et size of unpartitioned space

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 free =3D None

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 for line in exec_cmd("{} -F {}".format(self.sfdisk,
> target)).splitlines():

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 if line.startswith("Unpartitioned space "= ;) and

> line.endswith("sectors"):

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 free =3D int= (line.split()[-2])

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 # Align free space to a 2048 sector boundary.
> YOCTO #12840.

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 free =3D free - (free % 2048)

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if free is None:

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise WicError(&quo= t;Can't get size of unpartitioned

> space") +

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # calculate expanded partition= s sizes

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sizes =3D {}=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 num_auto_resize =3D= 0

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for num, part in<= br>
> enumerate(parts['partitiontable']['partitions']= , 1):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = if num in expand:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 if expand[num] !=3D 0: # don't resize parti= tion if

> size is set to 0

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sectors =3D exp= and[num] // self._lsector_size

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 free -=3D sectors - pa= rt['size']

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part['size'] =3D sectors<= br>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 sizes[num] =3D sectors

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif part['type'] !=3D '= f':

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 sizes[num] =3D -1

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 num_auto_resize +=3D 1
> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for num, par= t in

> enumerate(parts['partitiontable']['partitions&= #39;], 1):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 if sizes.get(num) =3D=3D -1:

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part['size'] +=3D fre= e // num_auto_resize

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 # write resized partition table to the target

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 write_ptable(parts, target)
> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # read resi= zed partition table

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = parts =3D read_ptable(target)

> +

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 # copy partitions content

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for num, part in

> enumerate(part= s['partitiontable']['partitions'], 1):

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pnum =3D str(num)

&= gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fstype =3D sel= f.partitions[pnum].fstype

> +

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # copy unchanged partition

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if part['size&#= 39;] =3D=3D self.partitions[pnum].size //

> self._lsector_size:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 = logger.info("copying unchanged partition

> {}".form= at(pnum))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 sparse_copy(self._get_part_image(pnum), target,

&g= t; seek=3Dpart['start'] * self._lsector_size)

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue
=
> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 # resize or re-create partitions

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if fstype.startswith('ext') or
> fstype.startswith('fat') or \

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fstype.startswith(&= #39;linux-swap'):

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 partfname =3D None

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 wi= th

> tempfile.NamedTemporaryFile(prefix=3D"wic-part{}-"= .format(pnum)) as

> partf:

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 partfname =3D <= a href=3D"http://partf.name" rel=3D"noreferrer" target=3D"_blank">partf.nam= e

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 if fstype.startswith('ext'):

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 logger.info("resizing ext partition

> {}".fo= rmat(pnum))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 partimg =3D self._get_part_image(pnum)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 sparse_copy(partimg, partfname)

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 exec_cmd("{} -pf {}".format(self.e2fsck,

> partfnam= e))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 exec_cmd("{} {} {}s".format(\

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0self.resize2fs, partfname,=

> part['size']))

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif fstype.startswith('f= at'):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 logger.info("copying content of the fat
> partition {}".format(pnum))

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 with
=
> tempfile.TemporaryDirectory(prefix=3D'wic-fatdir-') as tmp= dir:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # copy content to the temporary d= irectory

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D "{} -snompi {} := :

> {}".format(self.mcopy,

> +

> self._g= et_part_image(pnum),

> +

> tmpdir)

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 exec_cmd(cmd)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # cre= ate new msdos partition

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 label =3D part.= get("name")

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 label_str =3D &= quot;-n {}".format(label) if

> label else '' +
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd =3D "{} {} -C {}

> {}&qu= ot;.format(self.mkdosfs, label_str, partfname,

> +

> pa= rt['size'])

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 exec_cmd(cmd)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # copy content from the temporary

&g= t; directory to the new partition

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cmd = =3D "{} -snompi {} {}/*

> ::".format(self.mcopy, partfn= ame, tmpdir)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 exec_cmd(cmd, as_shell=3DT= rue)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 elif fstype.startswith('linux-swap'):

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 logger.info("creating swap partition

> {}".form= at(pnum))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 label =3D part.get("name")
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 label_str =3D "-L {}".format(label) if label
> else ''

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 out =3D exec_cmd("{} = --probe

> {}".format(self.blkid, self._get_part_image(pnum))= )

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 uuid =3D

> out[out.index("UUID=3D\&= quot;")+6:out.index("UUID=3D\"")+42]

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 uuid_str =3D "-U {}".format(uuid) if uuid else

>= ''

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 with open(partfname, 'w') as spa= rse:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 os.ftruncate(sparse.fileno(),
=
> part['size'] * self._lsector_size)

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 e= xec_cmd("{} {} {} {}".format(self.mkswap,

> label_str, = uuid_str, partfname))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sparse_copy(partfname, target,

> = seek=3Dpart['start'] * self._lsector_size)

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 os.unlink(partf= name)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = elif part['type'] !=3D 'f':

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 logger.warning("s= kipping partition {}:

> unsupported fstype {}".format(pnum, = fstype)) +

> +def wic_ls(args, native_sysroot):

> +=C2= =A0 =C2=A0 """List contents of partitioned image or vfat par= tition."""

> +=C2=A0 =C2=A0 disk =3D Disk(args.pat= h.image, native_sysroot)

> +=C2=A0 =C2=A0 if not args.path.part:<= br>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if disk.partitions:

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 print('Num=C2=A0 =C2=A0 =C2= =A0Start=C2=A0 =C2=A0 =C2=A0 =C2=A0 End=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 S= ize

> Fstype')

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 for part in disk.partitions.values():

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 print("{:2d}=C2=A0 {:12d} {= :12d} {:12d}=C2=A0 {}".format(\

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.pnu= m, part.start, part.end,

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.size, part.fst= ype))

> +=C2=A0 =C2=A0 else:

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 path =3D args.path.path or '/'

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 print(disk.dir(args.path.part, path))

> +

&g= t; +def wic_cp(args, native_sysroot):

> +=C2=A0 =C2=A0 "&quo= t;"

> +=C2=A0 =C2=A0 Copy file or directory to/from the vfat= /ext partition of

> +=C2=A0 =C2=A0 partitioned image.

>= +=C2=A0 =C2=A0 """

> +=C2=A0 =C2=A0 if isinstance= (args.dest, str):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 disk =3D Disk(ar= gs.src.image, native_sysroot)

> +=C2=A0 =C2=A0 else:

> = +=C2=A0 =C2=A0 =C2=A0 =C2=A0 disk =3D Disk(args.dest.image, native_sysroot)=

> +=C2=A0 =C2=A0 disk.copy(args.src, args.dest)

> +
> +

> +def wic_rm(args, native_sysroot):

> +=C2= =A0 =C2=A0 """

> +=C2=A0 =C2=A0 Remove files or di= rectories from the vfat partition of

> +=C2=A0 =C2=A0 partitioned= image.

> +=C2=A0 =C2=A0 """

> +=C2=A0 = =C2=A0 disk =3D Disk(args.path.image, native_sysroot)

> +=C2=A0 = =C2=A0 disk.remove(args.path.part, args.path.path,

> args.recursi= ve_delete) +

> +def wic_write(args, native_sysroot):

> = +=C2=A0 =C2=A0 """

> +=C2=A0 =C2=A0 Write image to= a target device.

> +=C2=A0 =C2=A0 """

>= +=C2=A0 =C2=A0 disk =3D Disk(args.image, native_sysroot, ('fat', &= #39;ext',

> 'linux-swap'))

> +=C2=A0 =C2=A0= disk.write(args.target, args.expand)

> +

>=C2=A0 def f= ind_canned(scripts_path, file_name):

>=C2=A0 =C2=A0 =C2=A0 "= ""

>=C2=A0 =C2=A0 =C2=A0 Find a file either by its path= or by name in the canned files

> dir. diff --git a/scripts/lib/w= ic/filemap.py

> b/scripts/lib/wic/filemap.py index 080668e..4d9da= 28 100644

> --- a/scripts/lib/wic/filemap.py

> +++ b/sc= ripts/lib/wic/filemap.py

> @@ -1,13 +1,8 @@

> +#
>=C2=A0 # Copyright (c) 2012 Intel, Inc.

>=C2=A0 #

>= ; -# This program is free software; you can redistribute it and/or

&= gt; modify -# it under the terms of the GNU General Public License,

= > version 2, -# as published by the Free Software Foundation.

>= ; +# SPDX-License-Identifier: GPL-2.0-only

>=C2=A0 #

> = -# This program is distributed in the hope that it will be useful, but
<= br>> -# WITHOUT ANY WARRANTY; without even the implied warranty of
> -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU<= br>
> -# General Public License for more details.

>=C2=A0 <= br>
>=C2=A0 """

>=C2=A0 This module implemen= ts python implements a way to get file block.

> Two methods @@ -2= 2,6 +17,7 @@ and returns an instance of the class.

>=C2=A0 #=C2= =A0 =C2=A0* Too many instance attributes (R0902)

>=C2=A0 # pylint= : disable=3DR0902

>=C2=A0

> +import errno

>= =C2=A0 import os

>=C2=A0 import struct

>=C2=A0 import a= rray

> @@ -34,14 +30,23 @@ def get_block_size(file_obj):

&= gt;=C2=A0 =C2=A0 =C2=A0 Returns block size for file object 'file_obj= 9;. Errors are

> indicated by the 'IOError' exception.
>=C2=A0 =C2=A0 =C2=A0 """

> -

> = -=C2=A0 =C2=A0 from fcntl import ioctl

> -=C2=A0 =C2=A0 import st= ruct

> -

>=C2=A0 =C2=A0 =C2=A0 # Get the block size of = the host file-system for the image file

> by calling # the FIGETB= SZ ioctl (number 2).

> -=C2=A0 =C2=A0 binary_data =3D ioctl(file_= obj, 2, struct.pack('I', 0))

> -=C2=A0 =C2=A0 return stru= ct.unpack('I', binary_data)[0]

> +=C2=A0 =C2=A0 try:
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 binary_data =3D fcntl.ioctl(file_obj, = 2, struct.pack('I', 0))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 bs= ize =3D struct.unpack('I', binary_data)[0]

> +=C2=A0 =C2= =A0 except OSError:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 bsize =3D None=

> +

> +=C2=A0 =C2=A0 # If ioctl causes OSError or give= bsize to zero failback to

> os.fstat

> +=C2=A0 =C2=A0 = if not bsize:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 import os

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 stat =3D os.fstat(file_obj.fileno())

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if hasattr(stat, 'st_blksize'):
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bsize =3D stat.st_blk= size

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 else:

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise IOError("Unable to determine blo= ck size")

> +=C2=A0 =C2=A0 return bsize

>=C2=A0
>=C2=A0 class ErrorNotSupp(Exception):

>=C2=A0 =C2=A0 = =C2=A0 """

> @@ -137,15 +142,6 @@ class _FilemapBa= se(object):

>=C2=A0

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 raise Error("the method is not implemented")

>=C2= =A0

> -=C2=A0 =C2=A0 def block_is_unmapped(self, block): # pylin= t: disable=3DW0613,R0201

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 "&qu= ot;"

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 This method has has to b= e implemented by child classes. It

> returns

> -=C2=A0 = =C2=A0 =C2=A0 =C2=A0 'True' if block number 'block' of the = image file is not

> mapped (hole)

> -=C2=A0 =C2=A0 =C2= =A0 =C2=A0 and 'False' otherwise.

> -=C2=A0 =C2=A0 =C2=A0= =C2=A0 """

> -

> -=C2=A0 =C2=A0 =C2=A0 = =C2=A0 raise Error("the method is not implemented")

> -=

>=C2=A0 =C2=A0 =C2=A0 def get_mapped_ranges(self, start, count):= # pylint:

> disable=3DW0613,R0201 """

>= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 This method has has to be implemented by= child classes. This

> is a @@ -159,15 +155,6 @@ class _FilemapBa= se(object):

>=C2=A0

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 raise Error("the method is not implemented")

>=C2= =A0

> -=C2=A0 =C2=A0 def get_unmapped_ranges(self, start, count)= : # pylint:

> disable=3DW0613,R0201

> -=C2=A0 =C2=A0 = =C2=A0 =C2=A0 """

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 T= his method has has to be implemented by child classes. Just

> lik= e

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 'get_mapped_ranges()', b= ut yields unmapped block ranges

> instead

> -=C2=A0 =C2= =A0 =C2=A0 =C2=A0 (holes).

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 "&= quot;"

> -

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise Er= ror("the method is not implemented")

> -

>=C2= =A0

>=C2=A0 # The 'SEEK_HOLE' and 'SEEK_DATA' op= tions of the file seek system

> call _SEEK_DATA =3D 3

>= @@ -185,9 +172,9 @@ def _lseek(file_obj, offset, whence):

>=C2= =A0 =C2=A0 =C2=A0 except OSError as err:

>=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 # The 'lseek' system call returns the ENXIO if there = is no

> data or # hole starting from the specified offset.
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 if err.errno =3D=3D os.errno.ENXIO:
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if err.errno =3D=3D errno.ENXIO:
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1

>= ; -=C2=A0 =C2=A0 =C2=A0 =C2=A0 elif err.errno =3D=3D os.errno.EINVAL:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 elif err.errno =3D=3D errno.EINVAL:
=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise ErrorNotSupp= ("the kernel or file-system does not

> support " "= \"SEEK_HOLE\" and \"SEEK_DATA\"")

>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else:

> @@ -228,7 +215,7 @@ class= FilemapSeek(_FilemapBase):

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 t= ry:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tmp_obj =3D= tempfile.TemporaryFile("w+", dir=3Ddirectory)

>=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 except IOError as err:

> -=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise ErrorNotSupp("cannot create a te= mporary in \"%s\":

> %s"

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise ErrorNotSupp("cannot create a te= mporary in \"%s\":

> %s" \ % (directory, err))
=
>=C2=A0

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 try:

&= gt; @@ -260,15 +247,10 @@ class FilemapSeek(_FilemapBase):

>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 % (block, result))

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 return result

>=C2=A0

> -=C2=A0 =C2=A0 def block_i= s_unmapped(self, block):

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 "&qu= ot;"Refer the '_FilemapBase' class for the documentation."= ;""

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 return not self.bloc= k_is_mapped(block)

> -

>=C2=A0 =C2=A0 =C2=A0 def _get_r= anges(self, start, count, whence1, whence2):

>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 """

> -=C2=A0 =C2=A0 =C2=A0 =C2= =A0 This function implements 'get_mapped_ranges()' and

> = -=C2=A0 =C2=A0 =C2=A0 =C2=A0 'get_unmapped_ranges()' depending on w= hat is passed in the

> 'whence1'

> -=C2=A0 =C2= =A0 =C2=A0 =C2=A0 and 'whence2' arguments.

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 This function implements 'get_mapped_ranges()' de= pending

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 on what is passed in the &= #39;whence1' and 'whence2' arguments.

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 """

>=C2=A0

>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 assert whence1 !=3D whence2

> @@ = -298,12 +280,6 @@ class FilemapSeek(_FilemapBase):

>=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 % (start, count, start + count - 1))

>=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 return self._get_ranges(start, count, _SEEK_DATA, _SEEK_HOLE)=

>=C2=A0

> -=C2=A0 =C2=A0 def get_unmapped_ranges(self= , start, count):

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 """= ;Refer the '_FilemapBase' class for the documentation.""&= quot;

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._log.debug("Filema= pSeek: get_unmapped_ranges(%d,

> %d(%d))"

> -=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 % (start, count, start + count - 1))

> -=C2=A0 =C2=A0 =C2= =A0 =C2=A0 return self._get_ranges(start, count, _SEEK_HOLE, _SEEK_DATA)
> -

>=C2=A0

>=C2=A0 # Below goes the FIEMAP io= ctl implementation, which is not very

> readable # because it dea= ls with the rather complex FIEMAP ioctl. To

> understand the @@ -= 390,12 +366,12 @@ class

> FilemapFiemap(_FilemapBase): except IOE= rror as err:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # = Note, the FIEMAP ioctl is supported by the Linux

> kernel startin= g # from version 2.6.28 (year 2008).

> -=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 if err.errno =3D=3D os.errno.EOPNOTSUPP:

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if err.errno =3D=3D errno.EOPNOTSUPP= :

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= errstr =3D "FilemapFiemap: the FIEMAP ioctl is not

> suppor= ted " \ "by the file-system"

>=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._log.debug(errstr)

&= gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise Err= orNotSupp(errstr)

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if= err.errno =3D=3D os.errno.ENOTTY:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 if err.errno =3D=3D errno.ENOTTY:

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 errstr =3D "FilemapFi= emap: the FIEMAP ioctl is not

> supported " \ "by the k= ernel"

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 self._log.debug(errstr)

> @@ -417,10 +393,6 @@ class F= ilemapFiemap(_FilemapBase):

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 % (block, result))<= br>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return result

>=C2= =A0

> -=C2=A0 =C2=A0 def block_is_unmapped(self, block):

= > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 """Refer the '_Filemap= Base' class for the documentation."""

> -=C2= =A0 =C2=A0 =C2=A0 =C2=A0 return not self.block_is_mapped(block)

>= -

>=C2=A0 =C2=A0 =C2=A0 def _unpack_fiemap_extent(self, index):<= br>
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 """

>= ;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Unpack a 'struct fiemap_extent'= structure object number

> 'index' from @@ -497,23 +469,2= 8 @@ class FilemapFiemap(_FilemapBase):

>=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 % (first= _prev, last_prev))

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 yield (fir= st_prev, last_prev)

>=C2=A0

> -=C2=A0 =C2=A0 def get_u= nmapped_ranges(self, start, count):

> +class FilemapNobmap(_Filem= apBase):

> +=C2=A0 =C2=A0 """

> +=C2=A0 = =C2=A0 This class is used when both the 'SEEK_DATA/HOLE' and FIEMAP= are

> not

> +=C2=A0 =C2=A0 supported by the filesystem= or kernel.

> +=C2=A0 =C2=A0 """

> +
=
> +=C2=A0 =C2=A0 def __init__(self, image, log=3DNone):

>= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 """Refer the '_Filema= pBase' class for the documentation."""

> -=C2= =A0 =C2=A0 =C2=A0 =C2=A0 self._log.debug("FilemapFiemap: get_unmapped_= ranges(%d,

> %d(%d))"

> -=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 % (start, count= , start + count - 1))

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 hole_first = =3D start

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 for first, last in self.= _do_get_mapped_ranges(start, count):

> -=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 if first > hole_first:

> -=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._log.debug("FilemapFiemap:= yielding range (%d,

> %d)"

> -=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 % (hole_first, first - 1))

> -=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 yield (hole_first, first - 1)
=
>=C2=A0

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hole= _first =3D last + 1

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 # Call the bas= e class constructor first

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 _Filemap= Base.__init__(self, image, log)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 se= lf._log.debug("FilemapNobmap: initializing")

>=C2=A0
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 if hole_first < start + count:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self._log.debug("= ;FilemapFiemap: yielding range (%d, %d)"

> -=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 % (hole_first, start + count - 1))

> -=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 yield (hole_first, start + count - 1)

&g= t; +=C2=A0 =C2=A0 def block_is_mapped(self, block):

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 """Refer the '_FilemapBase' class = for the documentation."""

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 return True

> +

> +=C2=A0 =C2=A0 def get_mapped_= ranges(self, start, count):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 "= ""Refer the '_FilemapBase' class for the documentation.&q= uot;""

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 self._log.debug(&= quot;FilemapNobmap: get_mapped_ranges(%d,

> %d(%d))"

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 % (start, count, start + count - 1))

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 yield (start, start + count -1)

>=C2=A0
>=C2=A0 def filemap(image, log=3DNone):

>=C2=A0 =C2=A0 =C2=A0= """

> @@ -528,26 +505,56 @@ def filemap(image, lo= g=3DNone):

>=C2=A0 =C2=A0 =C2=A0 try:

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 return FilemapFiemap(image, log)

>=C2=A0 =C2= =A0 =C2=A0 except ErrorNotSupp:

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 re= turn FilemapSeek(image, log)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 try:<= br>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return FilemapSeek(i= mage, log)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 except ErrorNotSupp:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return FilemapNobmap(i= mage, log)

>=C2=A0

> -def sparse_copy(src_fname, dst_f= name, offset=3D0, skip=3D0):

> -=C2=A0 =C2=A0 """E= fficiently copy sparse file to or into another file."""
<= br>> -=C2=A0 =C2=A0 fmap =3D filemap(src_fname)

> +def sparse_= copy(src_fname, dst_fname, skip=3D0, seek=3D0,

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 length=3D0, api=3DNone):

&= gt; +=C2=A0 =C2=A0 """

> +=C2=A0 =C2=A0 Efficientl= y copy sparse file to or into another file.

> +

> +=C2= =A0 =C2=A0 src_fname: path to source file

> +=C2=A0 =C2=A0 dst_fname: path to destination file

> +=C2=A0 =C2= =A0 skip: skip N bytes at thestart of src

> +=C2=A0 =C2=A0 seek: = seek N bytes from the start of dst

> +=C2=A0 =C2=A0 length: read = N bytes from src and write them to dst

> +=C2=A0 =C2=A0 api: File= mapFiemap or FilemapSeek object

> +=C2=A0 =C2=A0 ""&quo= t;

> +=C2=A0 =C2=A0 if not api:

> +=C2=A0 =C2=A0 =C2=A0= =C2=A0 api =3D filemap

> +=C2=A0 =C2=A0 fmap =3D api(src_fname)<= br>
>=C2=A0 =C2=A0 =C2=A0 try:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 dst_file =3D open(dst_fname, 'r+b')

>=C2=A0 =C2= =A0 =C2=A0 except IOError:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ds= t_file =3D open(dst_fname, 'wb')

> -=C2=A0 =C2=A0 =C2=A0 = =C2=A0 dst_file.truncate(os.path.getsize(src_fname))

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 if length:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 dst_size =3D length + seek

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 else:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst_siz= e =3D os.path.getsize(src_fname) + seek - skip

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 dst_file.truncate(dst_size)

>=C2=A0

> += =C2=A0 =C2=A0 written =3D 0

>=C2=A0 =C2=A0 =C2=A0 for first, last= in fmap.get_mapped_ranges(0, fmap.blocks_cnt):

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 start =3D first * fmap.block_size

>=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 end =3D (last + 1) * fmap.block_size

>= ;=C2=A0

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if skip >=3D end:
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 continue

> +
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if start < skip < end:
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fmap._f_image.seek(sk= ip, os.SEEK_SET)

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 else:

>= -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fmap._f_image.seek(start, os.SE= EK_SET)

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 dst_file.seek(offset + sta= rt, os.SEEK_SET)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sta= rt =3D skip

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 fmap._f_= image.seek(start, os.SEEK_SET)

> +

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 written +=3D start - skip - written

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 if length and written >=3D length:

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst_file.seek(seek + length, os.SEEK_SET)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst_file.close()
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return

> +
=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 dst_file.seek(seek + start - skip, os= .SEEK_SET)

>=C2=A0

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= chunk_size =3D 1024 * 1024

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 t= o_read =3D end - start

> @@ -556,7 +563,14 @@ def sparse_copy(src= _fname, dst_fname, offset=3D0,

> skip=3D0): while read < to_re= ad:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if read + c= hunk_size > to_read:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 chunk_size =3D to_read - read

> -=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 chunk =3D fmap._f_image.read(chunk_size)=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 size =3D chunk_size=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if length and writt= en + size > length:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 size =3D length - written

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 chunk =3D fmap._f_image.read(size)

>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst_file.write(chunk)

= > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 read +=3D chunk_size
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 read +=3D size

>= +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 written +=3D size

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if written =3D=3D length:

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dst_file.clos= e()

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 re= turn

>=C2=A0 =C2=A0 =C2=A0 dst_file.close()

> diff --gi= t a/scripts/lib/wic/help.py b/scripts/lib/wic/help.py

> index 148= da89..bd3a2b9 100644

> --- a/scripts/lib/wic/help.py

> = +++ b/scripts/lib/wic/help.py

> @@ -1,21 +1,6 @@

> -# e= x:ts=3D4:sw=3D4:sts=3D4:et

> -# -*- tab-width: 4; c-basic-offset:= 4; indent-tabs-mode: nil -*-

> -#

>=C2=A0 # 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 L= icense

> version 2 as -# published by the Free Software Foundatio= n.

>=C2=A0 #

> -# This program is distributed in the ho= pe that it will be useful,

> -# but WITHOUT ANY WARRANTY; without= even the implied warranty of

> -# MERCHANTABILITY or FITNESS FOR= A PARTICULAR PURPOSE.=C2=A0 See the

> -# GNU General Public Lice= nse for more details.

> -#

> -# You should have receive= d a copy of the GNU General Public License

> along -# with this p= rogram; if not, write to the Free Software

> Foundation, Inc., -#= 51 Franklin Street, Fifth Floor, Boston, MA

> 02110-1301 USA. +#= SPDX-License-Identifier: GPL-2.0-only

>=C2=A0 #

>=C2= =A0 # DESCRIPTION

>=C2=A0 # This module implements some basic hel= p invocation functions along

> @@ -56,7 +41,7 @@ def wic_help(arg= s, usage_str, subcommands):

>=C2=A0 =C2=A0 =C2=A0 ""&qu= ot;

>=C2=A0 =C2=A0 =C2=A0 Subcommand help dispatcher.

>= =C2=A0 =C2=A0 =C2=A0 """

> -=C2=A0 =C2=A0 if len(a= rgs) =3D=3D 1 or not display_help(args[1], subcommands):

> +=C2= =A0 =C2=A0 if args.help_topic =3D=3D None or not display_help(args.help_top= ic,

> subcommands): print(usage_str)

>=C2=A0

&g= t;=C2=A0

> @@ -82,19 +67,20 @@ def invoke_subcommand(args, parse= r,

> main_command_usage, subcommands): Dispatch to subcommand han= dler

> borrowed from combo-layer. Should use argparse, but has to= work in

> 2.6. """

> -=C2=A0 =C2=A0 if = not args:

> +=C2=A0 =C2=A0 if not args.command:

>=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 logger.error("No subcommand specified, ex= iting")

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 parser.print_hel= p()

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 1

> -=C2= =A0 =C2=A0 elif args[0] =3D=3D "help":

> +=C2=A0 =C2=A0= elif args.command =3D=3D "help":

>=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 wic_help(args, main_command_usage, subcommands)

> = -=C2=A0 =C2=A0 elif args[0] not in subcommands:

> -=C2=A0 =C2=A0 = =C2=A0 =C2=A0 logger.error("Unsupported subcommand %s, exiting\n"= , args[0])

> +=C2=A0 =C2=A0 elif args.command not in subcommands:=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 logger.error("Unsupported su= bcommand %s, exiting\n",

> args.command) parser.print_help()=

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return 1

>=C2=A0 = =C2=A0 =C2=A0 else:

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 usage =3D subc= ommands.get(args[0], subcommand_error)[1]

> -=C2=A0 =C2=A0 =C2=A0= =C2=A0 subcommands.get(args[0], subcommand_error)[0](args[1:],

>= usage)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 subcmd =3D subcommands.get= (args.command, subcommand_error)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 u= sage =3D subcmd[1]

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 subcmd[0](args,= usage)

>=C2=A0

>=C2=A0

>=C2=A0 ##

&= gt; @@ -130,10 +116,10 @@ wic_create_usage =3D """

&g= t;=C2=A0 =C2=A0Create a new OpenEmbedded image

>=C2=A0

&g= t;=C2=A0 =C2=A0usage: wic create <wks file or image name> [-o <DIR= NAME> | --outdir

> <DIRNAME>]

> -=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 [-i <JSON PROPERTY FILE> | --infile <= JSON PROPERTY_FILE>]

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 [-e | --image-name] [-s, --skip-build-check] [-D,

> --= debug] [-r, --rootfs-dir] [-b, --bootimg-dir]

>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 [-k, --kernel-dir] [-n, --native-sysroot] [= -f,

> --build-rootfs]

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 [-c, --compress-with] [-m, --bmap]

>=C2=A0

= >=C2=A0 =C2=A0This command creates an OpenEmbedded image based on the &#= 39;OE

> kickstart commands' found in the <wks file>.
> @@ -154,7 +140,7 @@ SYNOPSIS

>=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 [-e | --image-name] [-s, --skip-build-check] [-D, --debug]
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 [-r, --rootfs-dir] [-b, --bootimg-= dir]

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 [-k, --kernel-dir] [-n, = --native-sysroot] [-f,

> --build-rootfs]

> -=C2=A0 =C2= =A0 =C2=A0 =C2=A0 [-c, --compress-with] [-m, --bmap]

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 [-c, --compress-with] [-m, --bmap] [--no-fstab-update]=

>=C2=A0

>=C2=A0 DESCRIPTION

>=C2=A0 =C2=A0 = =C2=A0 This command creates an OpenEmbedded image based on the 'OE
<= br>> @@ -226,6 +212,11 @@ DESCRIPTION

>=C2=A0

>=C2= =A0 =C2=A0 =C2=A0 The -m option is used to produce .bmap file for the image= . This

> file can be used to flash image using bmaptool utility.<= br>
> +

> +=C2=A0 =C2=A0 The --no-fstab-update option is us= ed to doesn't change fstab

> file. When

> +=C2=A0 = =C2=A0 using this option the final fstab file will be same that in

&= gt; rootfs and

> +=C2=A0 =C2=A0 wic doesn't update file, e.g = adding a new mount point. User can

> control

> +=C2=A0 = =C2=A0 the fstab file content in base-files recipe.

>=C2=A0 "= ;""

>=C2=A0

>=C2=A0 wic_list_usage =3D "= ;""

> @@ -283,6 +274,243 @@ DESCRIPTION

>=C2= =A0 =C2=A0 =C2=A0 details.

>=C2=A0 """

>= =C2=A0

> +wic_ls_usage =3D """

> +
<= br>> + List content of a partitioned image

> +

> + u= sage: wic ls <image>[:<partition>[<path>]] [--native-sysr= oot

> <path>] +

> + This command=C2=A0 outputs ei= ther list of image partitions or directory

> contents

>= + of vfat and ext* partitions.

> +

> + See 'wic he= lp ls' for more detailed instructions.

> +

> +"= ;""

> +

> +wic_ls_help =3D """=

> +

> +NAME

> +=C2=A0 =C2=A0 wic ls - List c= ontents of partitioned image or partition

> +

> +SYNOPS= IS

> +=C2=A0 =C2=A0 wic ls <image>

> +=C2=A0 =C2= =A0 wic ls <image>:<vfat or ext* partition>

> +=C2=A0= =C2=A0 wic ls <image>:<vfat or ext* partition><path>
=
> +=C2=A0 =C2=A0 wic ls <image>:<vfat or ext* partition>= <path> --native-sysroot

> <path> +

> +DESCR= IPTION

> +=C2=A0 =C2=A0 This command lists either partitions of t= he image or directory

> contents

> +=C2=A0 =C2=A0 of vf= at or ext* partitions.

> +

> +=C2=A0 =C2=A0 The first f= orm it lists partitions of the image.

> +=C2=A0 =C2=A0 For exampl= e:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ wic ls

> tmp/deploy= /images/qemux86-64/core-image-minimal-qemux86-64.wic

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 Num=C2=A0 =C2=A0 =C2=A0Start=C2=A0 =C2=A0 =C2=A0 =C2= =A0 End=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Size=C2=A0 =C2=A0 =C2=A0 Fstype
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 1=C2=A0 =C2=A0 =C2=A0 =C2=A0 104857= 6=C2=A0 =C2=A0 =C2=A024438783=C2=A0 =C2=A0 =C2=A023390208=C2=A0 fat16
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 2=C2=A0 =C2=A0 =C2=A0 =C2=A025165824=C2= =A0 =C2=A0 =C2=A050315263=C2=A0 =C2=A0 =C2=A025149440=C2=A0 ext4

>= ; +

> +=C2=A0 =C2=A0 Second and third form list directory content= of the partition:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ wic ls
> tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Volume in drive : is boot

> = +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Volume Serial Number is 2DF2-5F02
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Directory for ::/

> +

&= gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 efi=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <= DIR>=C2=A0 =C2=A0 =C2=A02017-05-11=C2=A0 10:54

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 startup=C2=A0 nsh=C2=A0 =C2=A0 =C2=A0 =C2=A0 26 2017-05-1= 1=C2=A0 10:54

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 vmlinuz=C2=A0 =C2=A0= =C2=A0 =C2=A0 6922288 2017-05-11=C2=A0 10:54

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 3 files=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A06 922 314 bytes

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A015 818 752 bytes free

> +

> +

&= gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ wic ls

> tmp/deploy/images/qem= ux86-64/core-image-minimal-qemux86-64.wic:1/EFI/boot/

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 Volume in drive : is boot

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0Volume Serial Number is 2DF2-5F02

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 Directory for ::/EFI/boot

> +

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 .=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <= DIR>=C2=A0 =C2=A0 =C2=A02017-05-11=C2=A0 10:54

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 ..=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<DIR>=C2= =A0 =C2=A0 =C2=A02017-05-11=C2=A0 10:54

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 grub=C2=A0 =C2=A0 =C2=A0cfg=C2=A0 =C2=A0 =C2=A0 =C2=A0679 2017-05-11= =C2=A0 10:54

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 bootx64=C2=A0 efi=C2= =A0 =C2=A0 571392 2017-05-11=C2=A0 10:54

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 4 files=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0572 071 bytes

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A015 818 752 bytes free

> +

> +=C2=A0 =C2=A0= The -n option is used to specify the path to the native sysroot

>= ; +=C2=A0 =C2=A0 containing the tools(parted and mtools) to use.

>= ; +

> +"""

> +

> +wic_cp_usage= =3D """

> +

> + Copy files and director= ies to/from the vfat or ext* partition

> +

> + usage: w= ic cp <src> <dest> [--native-sysroot <path>]

> = +

> + source/destination image in format <image>:<partit= ion>[<path>]

> +

> + This command copies files= or directories either

> +=C2=A0 - from local to vfat or ext* par= titions of partitioned image

> +=C2=A0 - from vfat or ext* partit= ions of partitioned image to local

> +

> + See 'wic= help cp' for more detailed instructions.

> +

> +&q= uot;""

> +

> +wic_cp_help =3D ""&qu= ot;

> +

> +NAME

> +=C2=A0 =C2=A0 wic cp - cop= y files and directories to/from the vfat or ext*

> partitions +
> +SYNOPSIS

> +=C2=A0 =C2=A0 wic cp <src> <dest= >:<partition>

> +=C2=A0 =C2=A0 wic cp <src>:<pa= rtition> <dest>

> +=C2=A0 =C2=A0 wic cp <src> <= dest-image>:<partition><path>

> +=C2=A0 =C2=A0 wic= cp <src> <dest-image>:<partition><path> --native-s= ysroot

> <path> +

> +DESCRIPTION

> +=C2= =A0 =C2=A0 This command copies files or directories either

> +=C2= =A0 =C2=A0 =C2=A0 - from local to vfat or ext* partitions of partitioned im= age

> +=C2=A0 =C2=A0 =C2=A0 - from vfat or ext* partitions of par= titioned image to local

> +

> +=C2=A0 =C2=A0 The first = form of it copies file or directory to the root

> directory of
> +=C2=A0 =C2=A0 the partition:

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 $ wic cp test.wks

> tmp/deploy/images/qemux86-64/core-imag= e-minimal-qemux86-64.wic:1

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ wic l= s

> tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wi= c:1

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Volume in drive : is boot
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Volume Serial Number is DB4C-FD4= C

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Directory for ::/

> +<= br>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 efi=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 <DIR>=C2=A0 =C2=A0 =C2=A02017-05-24=C2=A0 18:15

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 loader=C2=A0 =C2=A0 =C2=A0 =C2=A0<DIR>=C2=A0= =C2=A0 =C2=A02017-05-24=C2=A0 18:15

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 startup=C2=A0 nsh=C2=A0 =C2=A0 =C2=A0 =C2=A0 26 2017-05-24=C2=A0 18:15<= br>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 vmlinuz=C2=A0 =C2=A0 =C2=A0 =C2=A0= 6926384 2017-05-24=C2=A0 18:15

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 te= st=C2=A0 =C2=A0 =C2=A0wks=C2=A0 =C2=A0 =C2=A0 =C2=A0628 2017-05-24=C2=A0 21= :22

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 5 = files=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A06 927 038 bytes

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A015 677 440 bytes free

&= gt; +

> +=C2=A0 =C2=A0 The second form of the command copies file= or directory to the

> specified directory

> +=C2=A0 = =C2=A0 on the partition:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0$ wic cp t= est

> tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.= wic:1/efi/

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0$ wic ls

> tmp= /deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/efi/

&= gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0Volume in drive : is boot

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 Volume Serial Number is DB4C-FD4C

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0Directory for ::/efi

> +

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0.=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <DIR&= gt;=C2=A0 =C2=A0 =C2=A02017-05-24=C2=A0 18:15

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0..=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<DIR>=C2=A0 = =C2=A0 =C2=A02017-05-24=C2=A0 18:15

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0boot=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<DIR>=C2=A0 =C2=A0 =C2=A0201= 7-05-24=C2=A0 18:15

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0test=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0<DIR>=C2=A0 =C2=A0 =C2=A02017-05-24=C2=A0 21:= 27

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A04 fi= les=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00 b= ytes

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 15 675 392 bytes fr= ee

> +

> +=C2=A0 =C2=A0 The third form of the command c= opies file or directory from the

> specified directory

>= ; +=C2=A0 =C2=A0 on the partition to local:

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0$ wic cp

> tmp/deploy/images/qemux86-64/core-image-mini= mal-qemux86-64.wic:1/vmlinuz

> test +

> +=C2=A0 =C2=A0 = The -n option is used to specify the path to the native sysroot

>= +=C2=A0 =C2=A0 containing the tools(parted and mtools) to use.

>= +"""

> +

> +wic_rm_usage =3D "&quo= t;"

> +

> + Remove files or directories from the v= fat or ext* partitions

> +

> + usage: wic rm <image&= gt;:<partition><path> [--native-sysroot <path>]

&g= t; +

> + This command=C2=A0 removes files or directories from the= vfat or ext*

> partitions of

> + the partitioned image= .

> +

> + See 'wic help rm' for more detailed i= nstructions.

> +

> +"""

> +
> +wic_rm_help =3D """

> +

> +NA= ME

> +=C2=A0 =C2=A0 wic rm - remove files or directories from the= vfat or ext*

> partitions +

> +SYNOPSIS

> += =C2=A0 =C2=A0 wic rm <src> <image>:<partition><path>= ;

> +=C2=A0 =C2=A0 wic rm <src> <image>:<partition= ><path> --native-sysroot <path>

> +=C2=A0 =C2=A0 w= ic rm -r <image>:<partition><path>

> +

&= gt; +DESCRIPTION

> +=C2=A0 =C2=A0 This command removes files or d= irectories from the vfat or ext*

> partition of the

> += =C2=A0 =C2=A0 partitioned image:

> +

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 $ wic ls

> ./tmp/deploy/images/qemux86-64/core-imag= e-minimal-qemux86-64.wic:1

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Volume = in drive : is boot

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Volume Se= rial Number is 11D0-DE21

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Directory= for ::/

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 libcom32 c3= 2=C2=A0 =C2=A0 186500 2017-06-02=C2=A0 15:15

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 libutil=C2=A0 c32=C2=A0 =C2=A0 =C2=A024148 2017-06-02=C2=A0 15:1= 5

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 syslinux cfg=C2=A0 =C2=A0 =C2=A0= =C2=A0209 2017-06-02=C2=A0 15:15

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = vesamenu c32=C2=A0 =C2=A0 =C2=A027104 2017-06-02=C2=A0 15:15

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 vmlinuz=C2=A0 =C2=A0 =C2=A0 =C2=A0 6926384 2017= -06-02=C2=A0 15:15

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 5 files=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A07 164 345 byt= es

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A016 582 656 bytes= free

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ wic rm
> ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/l= ibutil.c32

> +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ wic ls<= br>
> ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wi= c:1

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Volume in drive : is boot
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Volume Serial Number is 11D0-DE2= 1

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Directory for ::/

> +<= br>
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 libcom32 c32=C2=A0 =C2=A0 186500 2= 017-06-02=C2=A0 15:15

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 syslinux cfg= =C2=A0 =C2=A0 =C2=A0 =C2=A0209 2017-06-02=C2=A0 15:15

> +=C2=A0 = =C2=A0 =C2=A0 =C2=A0 vesamenu c32=C2=A0 =C2=A0 =C2=A027104 2017-06-02=C2=A0= 15:15

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 vmlinuz=C2=A0 =C2=A0 =C2=A0= =C2=A0 6926384 2017-06-02=C2=A0 15:15

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 4 files=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A07 140 197 bytes

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A016 607 232 bytes free

> +

> +=C2=A0 =C2=A0 Th= e -n option is used to specify the path to the native sysroot

> += =C2=A0 =C2=A0 containing the tools(parted and mtools) to use.

> +=

> +=C2=A0 =C2=A0 The -r option is used to remove directories and= their contents

> +=C2=A0 =C2=A0 recursively,this only applies to= ext* partition.

> +"""

> +

> = +wic_write_usage =3D """

> +

> + Write i= mage to a device

> +

> + usage: wic write <image>= <target device> [--expand [rules]]

> [--native-sysroot <= ;path>] +

> + This command writes partitioned image to a targe= t device (USB

> stick, SD card etc). +

> + See 'wic= help write' for more detailed instructions.

> +

> = +"""

> +

> +wic_write_help =3D "&qu= ot;"

> +

> +NAME

> +=C2=A0 =C2=A0 wic wr= ite - write an image to a device

> +

> +SYNOPSIS
> +=C2=A0 =C2=A0 wic write <image> <target>

> += =C2=A0 =C2=A0 wic write <image> <target> --expand auto

&= gt; +=C2=A0 =C2=A0 wic write <image> <target> --expand 1:100M,2= :300M

> +=C2=A0 =C2=A0 wic write <image> <target> --n= ative-sysroot <path>

> +

> +DESCRIPTION

&g= t; +=C2=A0 =C2=A0 This command writes an image to a target device (USB stic= k, SD

> card etc) +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 $ wi= c write

> ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux= 86-64.wic

> /dev/sdb +

> +=C2=A0 =C2=A0 The --expand op= tion is used to resize image partitions.

> +=C2=A0 =C2=A0 --expan= d auto expands partitions to occupy all free space

> available on= the target device.

> +=C2=A0 =C2=A0 It's also possible to sp= ecify expansion rules in a format

> +=C2=A0 =C2=A0 <partition&= gt;:<size>[,<partition>:<size>...] for one or more
> partitions.

> +=C2=A0 =C2=A0 Specifying size 0 will keep pa= rtition unmodified.

> +=C2=A0 =C2=A0 Note: Resizing boot partitio= n can result in non-bootable image

> for non-EFI images. It is
> +=C2=A0 =C2=A0 recommended to use size 0 for boot partition to ke= ep image

> bootable. +

> +=C2=A0 =C2=A0 The --native-sy= sroot option is used to specify the path to the

> native sysroot<= br>
> +=C2=A0 =C2=A0 containing the tools(parted, resize2fs) to use.<= br>
> +"""

> +

>=C2=A0 wic_plugins= _help =3D """

>=C2=A0

>=C2=A0 NAME
<= br>> @@ -308,7 +536,8 @@ DESCRIPTION

>=C2=A0

>=C2= =A0 =C2=A0 =C2=A0 Source plugins can also be implemented and added by exter= nal

>=C2=A0 =C2=A0 =C2=A0 layers - any plugins found in a scripts= /lib/wic/plugins/source/

> -=C2=A0 =C2=A0 directory in an externa= l layer will also be made available.

> +=C2=A0 =C2=A0 or lib/wic/= plugins/source/ directory in an external layer will

> +=C2=A0 =C2= =A0 also be made available.

>=C2=A0

>=C2=A0 =C2=A0 =C2= =A0 When the wic implementation needs to invoke a partition-specific
>=C2=A0 =C2=A0 =C2=A0 implementation, it looks for the plugin that has = the same name as

> @@ -346,6 +575,10 @@ DESCRIPTION

>= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 partition. In other words, it = 9;prepares' the final

> partition image which will be incorpo= rated into the disk image.

>=C2=A0

> +=C2=A0 =C2=A0 = =C2=A0 do_post_partition()

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = Called after the partition is created. It is useful to add

> post=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 operations e.g. signing th= e partition.

> +

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 do_config= ure_partition()

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Called= before do_prepare_partition(), typically used to

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 create custom configuration files for a partiti= on, for

> @@ -632,8 +865,11 @@ DESCRIPTION

>=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0Partitions with a <mountpoint> specified will= be

> automatically mounted. This is achieved by wic adding entri= es to the

> fstab during image generation. In order for a valid f= stab to be

> generated one of the

> -=C2=A0 =C2=A0 =C2= =A0 =C2=A0--ondrive, --ondisk or --use-uuid partition options must be
> used for

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0each partition that= specifies a mountpoint.

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0--ondrive,= --ondisk, --use-uuid or --use-label partition

> options must
=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0be used for each partition that specif= ies a mountpoint.=C2=A0 Note

> that with

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0--use-{uuid,label} and non-root <mountpoint>, includ= ing swap,

> the mount

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0pro= gram must understand the PARTUUID or LABEL syntax.=C2=A0 This

> c= urrently

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0excludes the busybox versi= ons of these applications.

>=C2=A0

>=C2=A0

>= ;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The following are supported 'part= 9; options:

> @@ -687,6 +923,8 @@ DESCRIPTION

>=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0apply to partitions created using = '--source rootfs' (see

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0--source above).=C2=A0 Valid values are:

>=C2=A0=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0vfat

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0msdos

>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ext2

>=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ext3

>=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ext4

> @@ -706,6 +94= 4,14 @@ DESCRIPTION

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 label is already in use by= another

> filesystem, a new label is created for the partition.<= br>
>=C2=A0

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--use-lab= el: This option is specific to wic. It makes wic

> to use the
=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 label in /etc/fstab to specify a partition. If

> th= e

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 --use-label and --use-uuid are used at the

> sa= me time,

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 we prefer the uuid because it is less likely
> to cause

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 name confliction. We don't support usin= g this

> parameter

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 on the root partition since i= t requires an

> initramfs to

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 parse this value an= d we do not currently

> support that. +

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0--active: Marks the partition as active.

= >=C2=A0

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--align (in= KBytes): This option is specific to wic and says

> @@ -719,11 +9= 65,31 @@ DESCRIPTION

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bootloaders.

>=C2=A0
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--exclude-path: This opti= on is specific to wic. It excludes

> the given

> -=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0absolute path from the resulting image. If

> the pat= h

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0relative path from the resulting image. If
> the path ends with a slash, only the content of the directory
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0is omitted, not the directory itself. This
> option only has an effect with the rootfs source plugin.

= >=C2=A0

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--include-path: = This option is specific to wic. It adds the

> contents

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0of the given path or a rootfs to the

> result= ing image.

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The option contains two fields, th= e origin

> and the

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0destination. Whe= n the origin is a rootfs,

> it follows

> +=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0the same logic as the rootfs-dir argument

> and the

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0permissions and owners are kept. When the

> o= rigin is a

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0path, it is relative to the direct= ory in

> which wic is

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0running not t= he rootfs itself so use of an

> absolute

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0path is recommended, and the owner and

> group is set to
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0root:root. If no destination is given it is
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0automatically set to the root of the

> ro= otfs. This

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0option only has an effect with the= rootfs

> source

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0plugin.

> = +

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--change-directory: This o= ption is specific to wic. It

> changes to the

> +=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0given directory before copying the

> file= s. This

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0option is useful when w= e want to split

> a rootfs in

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0multiple partitions and we want to keep

> the right
=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0permissions and usernames in all t= he

> partitions. +

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0--extra-space: This option is specific to wic. It adds extra

&= gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 space after the space filled by the content

>= ;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 of the partition. The final size can go

> @@ -7= 38,6 +1004,8 @@ DESCRIPTION

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 This = option cannot be used with

> --fixed-size option.

>=C2= =A0

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--part-name: This optio= n is specific to wic. It specifies

> name for GPT partitions. +
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--part-type: This option= is specific to wic. It specifies

> partition type GUID for GPT p= artitions.

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 List of partition type GUIDS can be found h= ere:

> @@ -752,10 +1020,21 @@ DESCRIPTION

>=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0in bootloader co= nfiguration before running wic. In

> this case .wks file can be g= enerated or modified to set preconfigured

> parition UUID using t= his option.

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--fsuuid: This = option is specific to wic. It specifies

> filesystem UUID.
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0It's useful if preconfigured filesystem UUID is

> added to= kernel command line

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0in bootloader configuration before running wic.=

> In this case .wks file can

> +=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0be generated or modified to= set preconfigured

> filesystem UUID using this option. +

= >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--system-id: This option is sp= ecific to wic. It specifies

> partition system id. It's usefu= l for the harware that requires

> non-default partition system id= s. The parameter in one byte long hex

> number either with 0x pre= fix or without it.

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0--mkfs-e= xtraopts: This option specifies extra options to

> pass to mkfs u= tility.

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NOTE, that wic uses default op= tions for

> some filesystems, for example

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0'-S 512' for mkfs.fat or '-F -i 8192' for
<= br>> mkfs.ext. Those options will

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0no= t take effect when --mkfs-extraopts is

> used. This should be tak= en into

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0account when using --mkfs-extr= aopts.

> +

>=C2=A0 =C2=A0 =C2=A0 * bootloader

&g= t;=C2=A0

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 This command allows the us= er to specify various bootloader

> @@ -793,3 +1072,67 @@ DESCRIPT= ION

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 .wks files.

>=C2=A0
>=C2=A0 """

> +

> +wic_help_hel= p =3D """

> +NAME

> +=C2=A0 =C2=A0 wic h= elp - display a help topic

> +

> +DESCRIPTION

&g= t; +=C2=A0 =C2=A0 Specify a help topic to display it. Topics are shown abov= e.

> +"""

> +

> +

> = +wic_help =3D """

> +Creates a customized OpenEmbe= dded image.

> +

> +Usage:=C2=A0 wic [--version]

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 wic help [COMMAND or TOPIC]

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 wic COMMAND [ARGS]

> +

> += =C2=A0 =C2=A0 usage 1: Returns the current version of Wic

> +=C2= =A0 =C2=A0 usage 2: Returns detailed help for a COMMAND or TOPIC

>= ; +=C2=A0 =C2=A0 usage 3: Executes COMMAND

> +

> +
<= br>> +COMMAND:

> +

> +=C2=A0 =C2=A0 list=C2=A0 =C2= =A0-=C2=A0 =C2=A0List available canned images and source plugins

>= ; +=C2=A0 =C2=A0 ls=C2=A0 =C2=A0 =C2=A0-=C2=A0 =C2=A0List contents of parti= tioned image or partition

> +=C2=A0 =C2=A0 rm=C2=A0 =C2=A0 =C2=A0= -=C2=A0 =C2=A0Remove files or directories from the vfat or ext*

>= partitions

> +=C2=A0 =C2=A0 help=C2=A0 =C2=A0-=C2=A0 =C2=A0Show = help for a wic COMMAND or TOPIC

> +=C2=A0 =C2=A0 write=C2=A0 -=C2= =A0 =C2=A0Write an image to a device

> +=C2=A0 =C2=A0 cp=C2=A0 = =C2=A0 =C2=A0-=C2=A0 =C2=A0Copy files and directories to the vfat or ext*
> partitions

> +=C2=A0 =C2=A0 create -=C2=A0 =C2=A0Creat= e a new OpenEmbedded image

> +

> +

> +TOPIC:<= br>
> +=C2=A0 =C2=A0 overview=C2=A0 - Presents an overall overview of= Wic

> +=C2=A0 =C2=A0 plugins=C2=A0 =C2=A0- Presents an overview = and API for Wic plugins

> +=C2=A0 =C2=A0 kickstart - Presents a W= ic kicstart file reference

> +

> +

> +Example= s:

> +

> +=C2=A0 =C2=A0 $ wic --version

> +
> +=C2=A0 =C2=A0 Returns the current version of Wic

> +<= br>
> +

> +=C2=A0 =C2=A0 $ wic help cp

> +
> +=C2=A0 =C2=A0 Returns the SYNOPSIS and DESCRIPTION for the Wic "= ;cp" command.

> +

> +

> +=C2=A0 =C2=A0 $= wic list images

> +

> +=C2=A0 =C2=A0 Returns the list = of canned images (i.e. *.wks files located in

> +=C2=A0 =C2=A0 th= e /scripts/lib/wic/canned-wks directory.

> +

> +
> +=C2=A0 =C2=A0 $ wic create mkefidisk -e core-image-minimal

&g= t; +

> +=C2=A0 =C2=A0 Creates an EFI disk image from artifacts us= ed in a previous

> +=C2=A0 =C2=A0 core-image-minimal build in sta= ndard BitBake locations

> +=C2=A0 =C2=A0 (e.g. Cooked Mode).
<= br>> +

> +"""

> diff --git a/scripts/= lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py

> index a039300= ..3453d9c 100644

> --- a/scripts/lib/wic/ksparser.py

> = +++ b/scripts/lib/wic/ksparser.py

> @@ -1,21 +1,8 @@

> = -#!/usr/bin/env python -tt

> -# ex:ts=3D4:sw=3D4:sts=3D4:et
> -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
> +#!/usr/bin/env python3

>=C2=A0 #

>=C2=A0 # C= opyright (c) 2016 Intel, Inc.

>=C2=A0 #

> -# This progr= am is free software; you can redistribute it and/or

> modify it -= # under the terms of the GNU General Public License as

> publishe= d by the Free -# Software Foundation; version 2 of the License

> = -#

> -# This program is distributed in the hope that it will be u= seful, but

> -# WITHOUT ANY WARRANTY; without even the implied wa= rranty of

> MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOS= E.=C2=A0 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, writ= e to the Free Software

> Foundation, Inc., 59 -# Temple Place - S= uite 330, Boston, MA

> 02111-1307, USA. +# SPDX-License-Identifie= r: GPL-2.0-only

>=C2=A0 #

>=C2=A0 # DESCRIPTION

= >=C2=A0 # This module provides parser for kickstart format

> @= @ -28,14 +15,30 @@

>=C2=A0 import os

>=C2=A0 import shl= ex

>=C2=A0 import logging

> +import re

>=C2= =A0

>=C2=A0 from argparse import ArgumentParser, ArgumentError, = ArgumentTypeError

>=C2=A0

>=C2=A0 from wic.engine impo= rt find_canned

>=C2=A0 from wic.partition import Partition
> +from wic.misc import get_bitbake_var

>=C2=A0

>= =C2=A0 logger =3D logging.getLogger('wic')

>=C2=A0
> +__expand_var_regexp__ =3D re.compile(r"\${[^{}@\n\t :]+}"= )

> +

> +def expand_line(line):

> +=C2=A0 =C2= =A0 while True:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 m =3D __expand_var= _regexp__.search(line)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if not m:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return line

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 key =3D m.group()[2:-1]

> +=C2=A0= =C2=A0 =C2=A0 =C2=A0 val =3D get_bitbake_var(key)

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 if val is None:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 logger.warning("cannot expand variable %s" % key)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return line

&g= t; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 line =3D line[:m.start()] + val + line[m.en= d():]

> +

>=C2=A0 class KickStartError(Exception):
<= br>>=C2=A0 =C2=A0 =C2=A0 """Custom exception.""= "

>=C2=A0 =C2=A0 =C2=A0 pass

> @@ -48,26 +51,31 @@= class KickStartParser(ArgumentParser):

>=C2=A0 =C2=A0 =C2=A0 def= error(self, message):

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise = ArgumentError(None, message)

>=C2=A0

> -def sizetype(a= rg):

> -=C2=A0 =C2=A0 """

> -=C2=A0 =C2= =A0 Custom type for ArgumentParser

> -=C2=A0 =C2=A0 Converts size= string in <num>[K|k|M|G] format into the integer

> value
> -=C2=A0 =C2=A0 """

> -=C2=A0 =C2=A0 if = arg.isdigit():

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 return int(arg) * 1= 024

> -

> -=C2=A0 =C2=A0 if not arg[:-1].isdigit():
=
> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 raise ArgumentTypeError("Invalid= size: %r" % arg)

> +def sizetype(default):

> +=C2= =A0 =C2=A0 def f(arg):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 ""= ;"

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Custom type for ArgumentPa= rser

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 Converts size string in <n= um>[K|k|M|G] format into the

> integer value

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 """

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 try:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 suff= ix =3D default

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 size = =3D int(arg)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 except ValueError:
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 try:

> +=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 suffix =3D arg[-1:]
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 size =3D= int(arg[:-1])

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 excep= t ValueError:

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 raise ArgumentTypeError("Invalid size: %r" % arg)

= >=C2=A0

> -=C2=A0 =C2=A0 size =3D int(arg[:-1])

> -= =C2=A0 =C2=A0 if arg.endswith("k") or arg.endswith("K")= :

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 return size

> -=C2=A0 = =C2=A0 if arg.endswith("M"):

> -=C2=A0 =C2=A0 =C2=A0 = =C2=A0 return size * 1024

> -=C2=A0 =C2=A0 if arg.endswith("= G"):

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 return size * 1024 * 102= 4

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if suffix =3D=3D "k" o= r suffix =3D=3D "K":

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return size

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if suffix = =3D=3D "M":

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 return size * 1024

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 if suffix = =3D=3D "G":

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 return size * 1024 * 1024

>=C2=A0

> -=C2=A0 =C2=A0= raise ArgumentTypeError("Invalid size: %r" % arg)

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise ArgumentTypeError("Invalid size: %r&= quot; % arg)

> +=C2=A0 =C2=A0 return f

>=C2=A0

= >=C2=A0 def overheadtype(arg):

>=C2=A0 =C2=A0 =C2=A0 "&qu= ot;"

> @@ -114,7 +122,7 @@ def systemidtype(arg):

>= ;=C2=A0 =C2=A0 =C2=A0 return arg

>=C2=A0

>=C2=A0 class= KickStart():

> -=C2=A0 =C2=A0 """"Kickstart = parser implementation."""

> +=C2=A0 =C2=A0 "&= quot;"Kickstart parser implementation."""

>= =C2=A0

>=C2=A0 =C2=A0 =C2=A0 DEFAULT_EXTRA_SPACE =3D 10*1024
=
>=C2=A0 =C2=A0 =C2=A0 DEFAULT_OVERHEAD_FACTOR =3D 1.3

> @@ -133,30 +141,41 @@ class KickStart():

>= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('mountpoint', = nargs=3D'?')

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add= _argument('--active', action=3D'store_true')

>=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('--align', type= =3Dint)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('--o= ffset', type=3Dsizetype("K"))

>=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 part.add_argument('--exclude-path', nargs=3D'+&#= 39;)

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument("--ext= ra-space", type=3Dsizetype)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 p= art.add_argument('--include-path', nargs=3D'+',

>= action=3D'append')

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 part.a= dd_argument('--change-directory')

> +=C2=A0 =C2=A0 =C2=A0= =C2=A0 part.add_argument("--extra-space", type=3Dsizetype("= M"))

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument(&= #39;--fsoptions', dest=3D'fsopts')

> -=C2=A0 =C2=A0 = =C2=A0 =C2=A0 part.add_argument('--fstype')

> +=C2=A0 =C2= =A0 =C2=A0 =C2=A0 part.add_argument('--fstype', default=3D'vfat= ',

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 choices=3D('ext2', 'ext3= 9;, 'ext4', 'btrfs',

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0'squashfs', 'vfat', 'msdos&#= 39;,

> 'swap'))

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = part.add_argument('--mkfs-extraopts', default=3D'')

= >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('--label')=

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('--use-labe= l', action=3D'store_true')

>=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 part.add_argument('--no-table', action=3D'store_true= ')

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('= ;--ondisk', '--ondrive', dest=3D'disk',

> def= ault=3D'sda') part.add_argument("--overhead-factor",
<= br>> type=3Doverheadtype)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 part.= add_argument('--part-name')

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 part.add_argument('--part-type')

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 part.add_argument('--rootfs-dir')

> = +=C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('--type', default=3D= 'primary',

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 choices =3D ('primary', 'logical'))

&g= t;=C2=A0

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # --size and --fixe= d-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, # ----e= xtra-space/--overhead-factor are handled later

>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 sizeexcl =3D part.add_mutually_exclusive_group()

&= gt; -=C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeexcl.add_argument('--size', ty= pe=3Dsizetype, default=3D0)

> -=C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeex= cl.add_argument('--fixed-size', type=3Dsizetype,

> defaul= t=3D0)

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeexcl.add_argument('= --size', type=3Dsizetype("M"),

> default=3D0)
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 sizeexcl.add_argument('--fixed-size= ', type=3Dsizetype("M"),

> default=3D0)

>= ;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('--source')
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argument('--sourc= eparams')

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argume= nt('--system-id', type=3Dsystemidtype)

>=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 part.add_argument('--use-uuid', action=3D'sto= re_true')

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argume= nt('--uuid')

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 part.add_argu= ment('--fsuuid')

>=C2=A0

>=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 bootloader =3D subparsers.add_parser('bootloader')
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bootloader.add_argument('-= -append')

> @@ -184,6 +203,7 @@ class KickStart():

>= ;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line =3D li= ne.strip()

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 lineno +=3D 1

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 if line and line[0] !=3D '#':

> = +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line= =3D expand_line(line)

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 try:

>=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line_= args =3D shlex.split(line)

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 parsed =3D parser.p= arse_args(line_args)

> @@ -191,6 +211,20 @@ class KickStart():
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 raise KickStartError('%s:%d: %s' % \
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0(confpath, lineno, err))

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if line.star= tswith('part'):

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # SquashFS does not support f= ilesystem UUID

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if parsed.fstype =3D=3D 'squashf= s':

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if parsed.fsuuid:

>= +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 err =3D "%s:%d: SquashFS does n= ot

> support UUID" \

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0% (confpath, lineno)

> += =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise KickStartError(err)

>= ; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 if parsed.label:

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 err =3D "%s:%d: SquashFS does not

> sup= port LABEL" \

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0% (confpath, lineno)

> +=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 raise KickStartError(err)

> +=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if pa= rsed.use_label and not parsed.label:

> +=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 e= rr =3D "%s:%d: Must set the label with

> --label" \
=
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 % (confpath, lineno= )

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 raise KickStartError(err)

>= ;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 # using ArgumentParser one cannot easily

> tell= if option # was passed as argument, if said option has a default

&g= t;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 # value; --overhead-factor/--extra-space

> cann= ot be used @@ -219,6 +253,11 @@ class KickStart():

>=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 elif line.s= tartswith('bootloader'):

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if not self.boo= tloader:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.bootloader =3D parse= d

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 # Concatenate the strings set in APP= END

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 append_var =3D get_bitbake_var(&q= uot;APPEND")

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if append_var:
<= br>> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 self.bootloader.append =3D &#= 39;

> '.join(filter(None, \

> +

> (self.b= ootloader.append, append_var))) else:

>=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 err =3D "%s:%d: more than one bootloader

> specified&= quot; \ % (confpath, lineno)

> diff --git a/scripts/lib/wic/utils= /misc.py b/scripts/lib/wic/misc.py

> similarity index 70%

= > rename from scripts/lib/wic/utils/misc.py

> rename to script= s/lib/wic/misc.py

> index c941112..91975ba 100644

> ---= a/scripts/lib/wic/utils/misc.py

> +++ b/scripts/lib/wic/misc.py<= br>
> @@ -1,21 +1,7 @@

> -# ex:ts=3D4:sw=3D4:sts=3D4:et
=
> -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-<= br>
>=C2=A0 #

>=C2=A0 # Copyright (c) 2013, Intel Corporati= on.

> -# All rights reserved.

>=C2=A0 #

> -# = This program is free software; you can redistribute it and/or

> m= odify -# it under the terms of the GNU General Public License

> v= ersion 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 warrant= y of

> -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.=C2= =A0 See the

> -# GNU General Public License for more details.
=
> -#

> -# You should have received a copy of the GNU Gener= al Public License

> along -# with this program; if not, write to = the Free Software

> Foundation, Inc., -# 51 Franklin Street, Fift= h Floor, Boston, MA

> 02110-1301 USA. +# SPDX-License-Identifier:= GPL-2.0-only

>=C2=A0 #

>=C2=A0 # DESCRIPTION

&g= t;=C2=A0 # This module provides a place to collect various wic-related util= s

> @@ -29,12 +15,12 @@

>=C2=A0 import logging

&= gt;=C2=A0 import os

>=C2=A0 import re

> +import subproc= ess

>=C2=A0

>=C2=A0 from collections import defaultdic= t

>=C2=A0 from distutils import spawn

>=C2=A0

&= gt;=C2=A0 from wic import WicError

> -from wic.utils import runne= r

>=C2=A0

>=C2=A0 logger =3D logging.getLogger('wi= c')

>=C2=A0

> @@ -43,6 +29,9 @@ NATIVE_RECIPES =3D= {"bmaptool": "bmap-tools",

>=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "grub-mkimage&= quot;: "grub-efi",

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "isohybrid": "syslinux&qu= ot;,

>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0
"mcopy": "mtools",

= > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "= mdel" : "mtools",

> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "mdeltree" :
--000000000000dead7205ae8d811e--