public inbox for isar-users@googlegroups.com
 help / color / mirror / Atom feed
* [PATCH] wic: Update to the latest revision
@ 2021-06-02  8:37 Anton Mikanovich
  2021-06-02  9:00 ` Jan Kiszka
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Anton Mikanovich @ 2021-06-02  8:37 UTC (permalink / raw)
  To: isar-users; +Cc: Anton Mikanovich

Update to the latest wic from OE-core.

OE-core Revision: b85a09ea450a5e8f49418f4a930805fbb88dc83b

Signed-off-by: Anton Mikanovich <amikan@ilbers.de>
---
 scripts/lib/wic/canned-wks/common.wks.inc     |  2 +-
 scripts/lib/wic/canned-wks/directdisk-gpt.wks |  2 +-
 scripts/lib/wic/canned-wks/mkefidisk.wks      |  2 +-
 scripts/lib/wic/ksparser.py                   | 17 +++++
 scripts/lib/wic/misc.py                       |  8 +-
 scripts/lib/wic/partition.py                  | 74 +++++++++++++------
 scripts/lib/wic/plugins/imager/direct.py      | 61 ++++++++-------
 scripts/lib/wic/plugins/source/bootimg-efi.py |  8 +-
 scripts/lib/wic/plugins/source/empty.py       | 32 ++++++++
 .../wic/plugins/source/isoimage-isohybrid.py  | 14 ++++
 scripts/lib/wic/plugins/source/rootfs.py      | 33 +++++++--
 scripts/wic                                   |  2 +
 12 files changed, 187 insertions(+), 68 deletions(-)
 create mode 100644 scripts/lib/wic/plugins/source/empty.py

diff --git a/scripts/lib/wic/canned-wks/common.wks.inc b/scripts/lib/wic/canned-wks/common.wks.inc
index 89880b4..4fd29fa 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 --use-uuid --fstype=ext4 --label platform --align 1024
+part / --source rootfs --use-uuid --fstype=ext4 --mkfs-extraopts "-T default" --label platform --align 1024
diff --git a/scripts/lib/wic/canned-wks/directdisk-gpt.wks b/scripts/lib/wic/canned-wks/directdisk-gpt.wks
index 8d7d8de..cf16c0c 100644
--- a/scripts/lib/wic/canned-wks/directdisk-gpt.wks
+++ b/scripts/lib/wic/canned-wks/directdisk-gpt.wks
@@ -4,7 +4,7 @@
 
 
 part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024
-part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid
+part / --source rootfs --ondisk sda --fstype=ext4 --mkfs-extraopts "-T default" --label platform --align 1024 --use-uuid
 
 bootloader  --ptable gpt --timeout=0  --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8"
 
diff --git a/scripts/lib/wic/canned-wks/mkefidisk.wks b/scripts/lib/wic/canned-wks/mkefidisk.wks
index 9f534fe..d1878e2 100644
--- a/scripts/lib/wic/canned-wks/mkefidisk.wks
+++ b/scripts/lib/wic/canned-wks/mkefidisk.wks
@@ -4,7 +4,7 @@
 
 part /boot --source bootimg-efi --sourceparams="loader=grub-efi" --ondisk sda --label msdos --active --align 1024
 
-part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid
+part / --source rootfs --ondisk sda --fstype=ext4 --mkfs-extraopts "-T default"  --label platform --align 1024 --use-uuid
 
 part swap --ondisk sda --size 44 --label swap1 --fstype=swap
 
diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py
index 913e328..3eb669d 100644
--- a/scripts/lib/wic/ksparser.py
+++ b/scripts/lib/wic/ksparser.py
@@ -229,6 +229,23 @@ class KickStart():
                                 err = "%s:%d: SquashFS does not support LABEL" \
                                        % (confpath, lineno)
                                 raise KickStartError(err)
+                        if parsed.fstype == 'msdos' or parsed.fstype == 'vfat':
+                            if parsed.fsuuid:
+                                if parsed.fsuuid.upper().startswith('0X'):
+                                    if len(parsed.fsuuid) > 10:
+                                        err = "%s:%d: fsuuid %s given in wks kickstart file " \
+                                              "exceeds the length limit for %s filesystem. " \
+                                              "It should be in the form of a 32 bit hexadecimal" \
+                                              "number (for example, 0xABCD1234)." \
+                                              % (confpath, lineno, parsed.fsuuid, parsed.fstype)
+                                        raise KickStartError(err)
+                                elif len(parsed.fsuuid) > 8:
+                                    err = "%s:%d: fsuuid %s given in wks kickstart file " \
+                                          "exceeds the length limit for %s filesystem. " \
+                                          "It should be in the form of a 32 bit hexadecimal" \
+                                          "number (for example, 0xABCD1234)." \
+                                          % (confpath, lineno, parsed.fsuuid, parsed.fstype)
+                                    raise KickStartError(err)
                         if parsed.use_label and not parsed.label:
                             err = "%s:%d: Must set the label with --label" \
                                   % (confpath, lineno)
diff --git a/scripts/lib/wic/misc.py b/scripts/lib/wic/misc.py
index 4b08d64..57c042c 100644
--- a/scripts/lib/wic/misc.py
+++ b/scripts/lib/wic/misc.py
@@ -26,6 +26,7 @@ logger = logging.getLogger('wic')
 
 # executable -> recipe pairs for exec_native_cmd
 NATIVE_RECIPES = {"bmaptool": "bmap-tools",
+                  "dumpe2fs": "e2fsprogs",
                   "grub-mkimage": "grub-efi",
                   "isohybrid": "syslinux",
                   "mcopy": "mtools",
@@ -138,9 +139,12 @@ def exec_native_cmd(cmd_and_args, native_sysroot, pseudo=""):
     if pseudo:
         cmd_and_args = pseudo + cmd_and_args
 
-    native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin:%s/bin" % \
+    hosttools_dir = get_bitbake_var("HOSTTOOLS_DIR")
+
+    native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin:%s/bin:%s" % \
                    (native_sysroot, native_sysroot,
-                    native_sysroot, native_sysroot)
+                    native_sysroot, native_sysroot,
+                    hosttools_dir)
 
     native_cmd_and_args = "export PATH=%s:$PATH;%s" % \
                    (native_paths, cmd_and_args)
diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py
index 4a5a31e..76d144d 100644
--- a/scripts/lib/wic/partition.py
+++ b/scripts/lib/wic/partition.py
@@ -54,6 +54,9 @@ class Partition():
         self.uuid = args.uuid
         self.fsuuid = args.fsuuid
         self.type = args.type
+        self.updated_fstab_path = None
+        self.has_fstab = False
+        self.update_fstab_in_rootfs = False
 
         self.lineno = lineno
         self.source_file = ""
@@ -118,11 +121,15 @@ class Partition():
         return self.fixed_size if self.fixed_size else self.size
 
     def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir,
-                bootimg_dir, kernel_dir, native_sysroot):
+                bootimg_dir, kernel_dir, native_sysroot, updated_fstab_path):
         """
         Prepare content for individual partitions, depending on
         partition command parameters.
         """
+        self.updated_fstab_path = updated_fstab_path
+        if self.updated_fstab_path and not (self.fstype.startswith("ext") or self.fstype == "msdos"):
+            self.update_fstab_in_rootfs = True
+
         if not self.source:
             if not self.size and not self.fixed_size:
                 raise WicError("The %s partition has a size of zero. Please "
@@ -199,21 +206,33 @@ class Partition():
 
         Currently handles ext2/3/4, btrfs, vfat and squashfs.
         """
+
+        rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label,
+                                         self.lineno, self.fstype)
+        if os.path.isfile(rootfs):
+            os.remove(rootfs)
+
         p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot)
         if (pseudo_dir):
+            # Canonicalize the ignore paths. This corresponds to
+            # calling oe.path.canonicalize(), which is used in bitbake.conf.
+            ignore_paths = [rootfs] + (get_bitbake_var("PSEUDO_IGNORE_PATHS") or "").split(",")
+            canonical_paths = []
+            for path in ignore_paths:
+                if "$" not in path:
+                    trailing_slash = path.endswith("/") and "/" or ""
+                    canonical_paths.append(os.path.realpath(path) + trailing_slash)
+            ignore_paths = ",".join(canonical_paths)
+
             pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix
             pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir
             pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
             pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
+            pseudo += "export PSEUDO_IGNORE_PATHS=%s;" % ignore_paths
             pseudo += "%s " % get_bitbake_var("FAKEROOTCMD")
         else:
             pseudo = None
 
-        rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label,
-                                         self.lineno, self.fstype)
-        if os.path.isfile(rootfs):
-            os.remove(rootfs)
-
         if not self.size and real_rootfs:
             # The rootfs size is not set in .ks file so try to get it
             # from bitbake variable
@@ -235,7 +254,7 @@ class Partition():
 
         prefix = "ext" if self.fstype.startswith("ext") else self.fstype
         method = getattr(self, "prepare_rootfs_" + prefix)
-        method(rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo)
+        method(rootfs, cr_workdir, oe_builddir, rootfs_dir, native_sysroot, pseudo)
         self.source_file = rootfs
 
         # get the rootfs size in the right units for kickstart (kB)
@@ -243,7 +262,7 @@ class Partition():
         out = exec_cmd(du_cmd)
         self.size = int(out.split()[0])
 
-    def prepare_rootfs_ext(self, rootfs, oe_builddir, rootfs_dir,
+    def prepare_rootfs_ext(self, rootfs, cr_workdir, oe_builddir, rootfs_dir,
                            native_sysroot, pseudo):
         """
         Prepare content for an ext2/3/4 rootfs partition.
@@ -267,12 +286,21 @@ class Partition():
             (self.fstype, extraopts, rootfs, label_str, self.fsuuid, rootfs_dir)
         exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
 
+        if self.updated_fstab_path and self.has_fstab:
+            debugfs_script_path = os.path.join(cr_workdir, "debugfs_script")
+            with open(debugfs_script_path, "w") as f:
+                f.write("cd etc\n")
+                f.write("rm fstab\n")
+                f.write("write %s fstab\n" % (self.updated_fstab_path))
+            debugfs_cmd = "debugfs -w -f %s %s" % (debugfs_script_path, rootfs)
+            exec_native_cmd(debugfs_cmd, native_sysroot)
+
         mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs)
         exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
 
         self.check_for_Y2038_problem(rootfs, native_sysroot)
 
-    def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir,
+    def prepare_rootfs_btrfs(self, rootfs, cr_workdir, oe_builddir, rootfs_dir,
                              native_sysroot, pseudo):
         """
         Prepare content for a btrfs rootfs partition.
@@ -295,7 +323,7 @@ class Partition():
              self.mkfs_extraopts, self.fsuuid, rootfs)
         exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
 
-    def prepare_rootfs_msdos(self, rootfs, oe_builddir, rootfs_dir,
+    def prepare_rootfs_msdos(self, rootfs, cr_workdir, oe_builddir, rootfs_dir,
                              native_sysroot, pseudo):
         """
         Prepare content for a msdos/vfat rootfs partition.
@@ -311,8 +339,6 @@ class Partition():
             label_str = "-n %s" % self.label
 
         size_str = ""
-        if self.fstype == 'msdos':
-            size_str = "-F 16" # FAT 16
 
         extraopts = self.mkfs_extraopts or '-S 512'
 
@@ -324,12 +350,16 @@ class Partition():
         mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir)
         exec_native_cmd(mcopy_cmd, native_sysroot)
 
+        if self.updated_fstab_path and self.has_fstab:
+            mcopy_cmd = "mcopy -i %s %s ::/etc/fstab" % (rootfs, self.updated_fstab_path)
+            exec_native_cmd(mcopy_cmd, native_sysroot)
+
         chmod_cmd = "chmod 644 %s" % rootfs
         exec_cmd(chmod_cmd)
 
     prepare_rootfs_vfat = prepare_rootfs_msdos
 
-    def prepare_rootfs_squashfs(self, rootfs, oe_builddir, rootfs_dir,
+    def prepare_rootfs_squashfs(self, rootfs, cr_workdir, oe_builddir, rootfs_dir,
                                 native_sysroot, pseudo):
         """
         Prepare content for a squashfs rootfs partition.
@@ -390,8 +420,6 @@ class Partition():
             label_str = "-n %s" % self.label
 
         size_str = ""
-        if self.fstype == 'msdos':
-            size_str = "-F 16" # FAT 16
 
         extraopts = self.mkfs_extraopts or '-S 512'
 
@@ -432,26 +460,26 @@ class Partition():
             if part.mountpoint:
                 args = [part.fstype, "mounted at %s" % part.mountpoint]
             elif part.label:
-                args = [part.fstype, "labeled %s" % part.label]
+                args = [part.fstype, "labeled '%s'" % part.label]
             elif part.part_name:
-                args = [part.fstype, "in partition %s" % part.part_name]
+                args = [part.fstype, "in partition '%s'" % part.part_name]
             else:
-                args = [part.fstype, ""]
+                args = [part.fstype, "in partition %s" % part.num]
             return err.format(*args)
 
-        ret, out = exec_native_cmd("dumpe2fs %s" % rootfs, native_sysroot)
-
         # ext2 and ext3 are always affected by the Y2038 problem
         if self.fstype in ["ext2", "ext3"]:
             logger.warn(get_err_str(self))
             return
 
+        ret, out = exec_native_cmd("dumpe2fs %s" % rootfs, native_sysroot)
+
         # if ext4 is affected by the Y2038 problem depends on the inode size
-        # Remember: inode size depends on the file system size
         for line in out.splitlines():
             if line.startswith("Inode size:"):
                 size = int(line.split(":")[1].strip())
                 if size < 256:
-                    logger.warn("%s Inodes (of size %d) are too small." % \
+                    logger.warn("%s Inodes (of size %d) are too small." %
                                 (get_err_str(self), size))
-                break
\ No newline at end of file
+                break
+
diff --git a/scripts/lib/wic/plugins/imager/direct.py b/scripts/lib/wic/plugins/imager/direct.py
index 55db826..ea709e8 100644
--- a/scripts/lib/wic/plugins/imager/direct.py
+++ b/scripts/lib/wic/plugins/imager/direct.py
@@ -54,15 +54,16 @@ class DirectPlugin(ImagerPlugin):
         self.native_sysroot = native_sysroot
         self.oe_builddir = oe_builddir
 
+        self.debug = options.debug
         self.outdir = options.outdir
         self.compressor = options.compressor
         self.bmap = options.bmap
         self.no_fstab_update = options.no_fstab_update
-        self.original_fstab = None
+        self.updated_fstab_path = None
 
         self.name = "%s-%s" % (os.path.splitext(os.path.basename(wks_file))[0],
                                strftime("%Y%m%d%H%M"))
-        self.workdir = tempfile.mkdtemp(dir=self.outdir, prefix='tmp.wic.')
+        self.workdir = self.setup_workdir(options.workdir)
         self._image = None
         self.ptable_format = self.ks.bootloader.ptable
         self.parts = self.ks.partitions
@@ -78,6 +79,16 @@ class DirectPlugin(ImagerPlugin):
         self._image = PartitionedImage(image_path, self.ptable_format,
                                        self.parts, self.native_sysroot)
 
+    def setup_workdir(self, workdir):
+        if workdir:
+            if os.path.exists(workdir):
+                raise WicError("Internal workdir '%s' specified in wic arguments already exists!" % (workdir))
+
+            os.makedirs(workdir)
+            return workdir
+        else:
+            return tempfile.mkdtemp(dir=self.outdir, prefix='tmp.wic.')
+
     def do_create(self):
         """
         Plugin entry point.
@@ -90,11 +101,8 @@ class DirectPlugin(ImagerPlugin):
         finally:
             self.cleanup()
 
-    def _write_fstab(self, image_rootfs):
-        """overriden to generate fstab (temporarily) in rootfs. This is called
-        from _create, make sure it doesn't get called from
-        BaseImage.create()
-        """
+    def update_fstab(self, image_rootfs):
+        """Assume partition order same as in wks"""
         if not image_rootfs:
             return
 
@@ -104,18 +112,9 @@ class DirectPlugin(ImagerPlugin):
 
         with open(fstab_path) as fstab:
             fstab_lines = fstab.readlines()
-            self.original_fstab = fstab_lines.copy()
-
-        if self._update_fstab(fstab_lines, self.parts):
-            with open(fstab_path, "w") as fstab:
-                fstab.writelines(fstab_lines)
-        else:
-            self.original_fstab = None
 
-    def _update_fstab(self, fstab_lines, parts):
-        """Assume partition order same as in wks"""
         updated = False
-        for part in parts:
+        for part in self.parts:
             if not part.realnum or not part.mountpoint \
                or part.mountpoint == "/":
                 continue
@@ -144,7 +143,10 @@ class DirectPlugin(ImagerPlugin):
             fstab_lines.append(line)
             updated = True
 
-        return updated
+        if updated:
+            self.updated_fstab_path = os.path.join(self.workdir, "fstab")
+            with open(self.updated_fstab_path, "w") as f:
+                f.writelines(fstab_lines)
 
     def _full_path(self, path, name, extention):
         """ Construct full file path to a file we generate. """
@@ -160,7 +162,7 @@ class DirectPlugin(ImagerPlugin):
         a partitioned image.
         """
         if not self.no_fstab_update:
-            self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
+            self.update_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
 
         for part in self.parts:
             # get rootfs size from bitbake variable if it's not set in .ks file
@@ -273,14 +275,9 @@ class DirectPlugin(ImagerPlugin):
             if os.path.isfile(path):
                 shutil.move(path, os.path.join(self.outdir, fname))
 
-        #Restore original fstab
-        if self.original_fstab:
-            fstab_path = self.rootfs_dir.get("ROOTFS_DIR") + "/etc/fstab"
-            with open(fstab_path, "w") as fstab:
-                fstab.writelines(self.original_fstab)
-
-        # remove work directory
-        shutil.rmtree(self.workdir, ignore_errors=True)
+        # remove work directory when it is not in debugging mode
+        if not self.debug:
+            shutil.rmtree(self.workdir, ignore_errors=True)
 
 # Overhead of the MBR partitioning scheme (just one sector)
 MBR_OVERHEAD = 1
@@ -343,6 +340,13 @@ class PartitionedImage():
                     part.fsuuid = '0x' + str(uuid.uuid4())[:8].upper()
                 else:
                     part.fsuuid = str(uuid.uuid4())
+            else:
+                #make sure the fsuuid for vfat/msdos align with format 0xYYYYYYYY
+                if part.fstype == 'vfat' or part.fstype == 'msdos':
+                    if part.fsuuid.upper().startswith("0X"):
+                        part.fsuuid = '0x' + part.fsuuid.upper()[2:].rjust(8,"0")
+                    else:
+                        part.fsuuid = '0x' + part.fsuuid.upper().rjust(8,"0")
 
     def prepare(self, imager):
         """Prepare an image. Call prepare method of all image partitions."""
@@ -351,7 +355,8 @@ class PartitionedImage():
             # sizes before we can add them and do the layout.
             part.prepare(imager, imager.workdir, imager.oe_builddir,
                          imager.rootfs_dir, imager.bootimg_dir,
-                         imager.kernel_dir, imager.native_sysroot)
+                         imager.kernel_dir, imager.native_sysroot,
+                         imager.updated_fstab_path)
 
             # Converting kB to sectors for parted
             part.size_sec = part.disk_size * 1024 // self.sector_size
diff --git a/scripts/lib/wic/plugins/source/bootimg-efi.py b/scripts/lib/wic/plugins/source/bootimg-efi.py
index 14c1723..cdc7254 100644
--- a/scripts/lib/wic/plugins/source/bootimg-efi.py
+++ b/scripts/lib/wic/plugins/source/bootimg-efi.py
@@ -212,8 +212,8 @@ class BootimgEFIPlugin(SourcePlugin):
         except KeyError:
             raise WicError("bootimg-efi requires a loader, none specified")
 
-        if get_bitbake_var("IMAGE_BOOT_FILES") is None:
-            logger.debug('No boot files defined in IMAGE_BOOT_FILES')
+        if get_bitbake_var("IMAGE_EFI_BOOT_FILES") is None:
+            logger.debug('No boot files defined in IMAGE_EFI_BOOT_FILES')
         else:
             boot_files = None
             for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)):
@@ -222,7 +222,7 @@ class BootimgEFIPlugin(SourcePlugin):
                 else:
                     var = ""
 
-                boot_files = get_bitbake_var("IMAGE_BOOT_FILES" + var)
+                boot_files = get_bitbake_var("IMAGE_EFI_BOOT_FILES" + var)
                 if boot_files:
                     break
 
@@ -292,7 +292,7 @@ class BootimgEFIPlugin(SourcePlugin):
             (staging_kernel_dir, kernel, hdddir, kernel)
         exec_cmd(install_cmd)
 
-        if get_bitbake_var("IMAGE_BOOT_FILES"):
+        if get_bitbake_var("IMAGE_EFI_BOOT_FILES"):
             for src_path, dst_path in cls.install_task:
                 install_cmd = "install -m 0644 -D %s %s" \
                               % (os.path.join(kernel_dir, src_path),
diff --git a/scripts/lib/wic/plugins/source/empty.py b/scripts/lib/wic/plugins/source/empty.py
new file mode 100644
index 0000000..041617d
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/empty.py
@@ -0,0 +1,32 @@
+#
+# SPDX-License-Identifier: MIT
+#
+
+# The empty wic plugin is used to create unformatted empty partitions for wic
+# images.
+# To use it you must pass "empty" as argument for the "--source" parameter in
+# the wks file. For example:
+# part foo --source empty --ondisk sda --size="1024" --align 1024
+
+import logging
+
+from wic.pluginbase import SourcePlugin
+
+logger = logging.getLogger('wic')
+
+class EmptyPartitionPlugin(SourcePlugin):
+    """
+    Populate unformatted empty partition.
+    """
+
+    name = 'empty'
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             rootfs_dir, native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        """
+        return
diff --git a/scripts/lib/wic/plugins/source/isoimage-isohybrid.py b/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
index 11326a2..afc9ea0 100644
--- a/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
+++ b/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
@@ -216,6 +216,18 @@ class IsoImagePlugin(SourcePlugin):
             creator.name = source_params['image_name'].strip()
             logger.debug("The name of the image is: %s", creator.name)
 
+    @staticmethod
+    def _install_payload(source_params, iso_dir):
+        """
+        Copies contents of payload directory (as specified in 'payload_dir' param) into iso_dir
+        """
+
+        if source_params.get('payload_dir'):
+            payload_dir = source_params['payload_dir']
+
+            logger.debug("Payload directory: %s", payload_dir)
+            shutil.copytree(payload_dir, iso_dir, symlinks=True, dirs_exist_ok=True)
+
     @classmethod
     def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
                              oe_builddir, bootimg_dir, kernel_dir,
@@ -228,6 +240,8 @@ class IsoImagePlugin(SourcePlugin):
 
         isodir = "%s/ISO" % cr_workdir
 
+        cls._install_payload(source_params, isodir)
+
         if part.rootfs_dir is None:
             if not 'ROOTFS_DIR' in rootfs_dir:
                 raise WicError("Couldn't find --rootfs-dir, exiting.")
diff --git a/scripts/lib/wic/plugins/source/rootfs.py b/scripts/lib/wic/plugins/source/rootfs.py
index f1db83f..96d940a 100644
--- a/scripts/lib/wic/plugins/source/rootfs.py
+++ b/scripts/lib/wic/plugins/source/rootfs.py
@@ -94,6 +94,7 @@ class RootfsPlugin(SourcePlugin):
                                "it is not a valid path, exiting" % part.rootfs_dir)
 
         part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
+        part.has_fstab = os.path.exists(os.path.join(part.rootfs_dir, "etc/fstab"))
         pseudo_dir = os.path.join(part.rootfs_dir, "../pseudo")
         if not os.path.lexists(pseudo_dir):
             logger.warn("%s folder does not exist. "
@@ -103,9 +104,9 @@ class RootfsPlugin(SourcePlugin):
         new_rootfs = None
         new_pseudo = None
         # Handle excluded paths.
-        if part.exclude_path or part.include_path or part.change_directory:
-            # We need a new rootfs directory we can delete files from. Copy to
-            # workdir.
+        if part.exclude_path or part.include_path or part.change_directory or part.update_fstab_in_rootfs:
+            # We need a new rootfs directory we can safely modify without
+            # interfering with other tasks. Copy to workdir.
             new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs%d" % part.lineno))
 
             if os.path.lexists(new_rootfs):
@@ -199,17 +200,33 @@ class RootfsPlugin(SourcePlugin):
                 if not os.path.lexists(full_path):
                     continue
 
+                if new_pseudo:
+                    pseudo = cls.__get_pseudo(native_sysroot, new_rootfs, new_pseudo)
+                else:
+                    pseudo = None
                 if path.endswith(os.sep):
                     # Delete content only.
                     for entry in os.listdir(full_path):
                         full_entry = os.path.join(full_path, entry)
-                        if os.path.isdir(full_entry) and not os.path.islink(full_entry):
-                            shutil.rmtree(full_entry)
-                        else:
-                            os.remove(full_entry)
+                        rm_cmd = "rm -rf %s" % (full_entry)
+                        exec_native_cmd(rm_cmd, native_sysroot, pseudo)
                 else:
                     # Delete whole directory.
-                    shutil.rmtree(full_path)
+                    rm_cmd = "rm -rf %s" % (full_path)
+                    exec_native_cmd(rm_cmd, native_sysroot, pseudo)
+
+            # Update part.has_fstab here as fstab may have been added or
+            # removed by the above modifications.
+            part.has_fstab = os.path.exists(os.path.join(new_rootfs, "etc/fstab"))
+            if part.update_fstab_in_rootfs and part.has_fstab:
+                fstab_path = os.path.join(new_rootfs, "etc/fstab")
+                # Assume that fstab should always be owned by root with fixed permissions
+                install_cmd = "install -m 0644 %s %s" % (part.updated_fstab_path, fstab_path)
+                if new_pseudo:
+                    pseudo = cls.__get_pseudo(native_sysroot, new_rootfs, new_pseudo)
+                else:
+                    pseudo = None
+                exec_native_cmd(install_cmd, native_sysroot, pseudo)
 
         part.prepare_rootfs(cr_workdir, oe_builddir,
                             new_rootfs or part.rootfs_dir, native_sysroot,
diff --git a/scripts/wic b/scripts/wic
index 24700f3..a741aed 100755
--- a/scripts/wic
+++ b/scripts/wic
@@ -312,6 +312,8 @@ def wic_init_parser_create(subparser):
 
     subparser.add_argument("-o", "--outdir", dest="outdir", default='.',
                       help="name of directory to create image in")
+    subparser.add_argument("-w", "--workdir",
+                      help="temporary workdir to use for intermediate files")
     subparser.add_argument("-e", "--image-name", dest="image_name",
                       help="name of the image to use the artifacts from "
                            "e.g. core-image-sato")
-- 
2.20.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] wic: Update to the latest revision
  2021-06-02  8:37 [PATCH] wic: Update to the latest revision Anton Mikanovich
@ 2021-06-02  9:00 ` Jan Kiszka
  2021-06-02  9:08   ` Anton Mikanovich
  2021-06-08  7:40 ` Henning Schild
  2021-06-08  7:45 ` Henning Schild
  2 siblings, 1 reply; 5+ messages in thread
From: Jan Kiszka @ 2021-06-02  9:00 UTC (permalink / raw)
  To: Anton Mikanovich, isar-users

On 02.06.21 10:37, Anton Mikanovich wrote:
> Update to the latest wic from OE-core.
> 
> OE-core Revision: b85a09ea450a5e8f49418f4a930805fbb88dc83b
> 

Will that resolve any current deviation from OE-Core?

Jan

-- 
Siemens AG, T RDA IOT
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] wic: Update to the latest revision
  2021-06-02  9:00 ` Jan Kiszka
@ 2021-06-02  9:08   ` Anton Mikanovich
  0 siblings, 0 replies; 5+ messages in thread
From: Anton Mikanovich @ 2021-06-02  9:08 UTC (permalink / raw)
  To: Jan Kiszka, isar-users

02.06.2021 12:00, Jan Kiszka wrote:
> Will that resolve any current deviation from OE-Core?
>
> Jan
>
Sure, that's the main motivation of the patch.

-- 
Anton Mikanovich
Promwad Ltd.
External service provider of ilbers GmbH
Maria-Merian-Str. 8
85521 Ottobrunn, Germany
+49 (89) 122 67 24-0
Commercial register Munich, HRB 214197
General Manager: Baurzhan Ismagulov


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] wic: Update to the latest revision
  2021-06-02  8:37 [PATCH] wic: Update to the latest revision Anton Mikanovich
  2021-06-02  9:00 ` Jan Kiszka
@ 2021-06-08  7:40 ` Henning Schild
  2021-06-08  7:45 ` Henning Schild
  2 siblings, 0 replies; 5+ messages in thread
From: Henning Schild @ 2021-06-08  7:40 UTC (permalink / raw)
  To: Anton Mikanovich; +Cc: isar-users, Florian Bezdeka

Please first revert the WIP series from Florian that changed stuff in
there.

And update all the forked plugins as well.
meta/scripts/lib/wic/plugins/source

And also wks files in meta-isar/scripts/lib/wic/canned-wks/ might need
updating.

Henning

Am Wed,  2 Jun 2021 11:37:41 +0300
schrieb Anton Mikanovich <amikan@ilbers.de>:

> Update to the latest wic from OE-core.
> 
> OE-core Revision: b85a09ea450a5e8f49418f4a930805fbb88dc83b
> 
> Signed-off-by: Anton Mikanovich <amikan@ilbers.de>
> ---
>  scripts/lib/wic/canned-wks/common.wks.inc     |  2 +-
>  scripts/lib/wic/canned-wks/directdisk-gpt.wks |  2 +-
>  scripts/lib/wic/canned-wks/mkefidisk.wks      |  2 +-
>  scripts/lib/wic/ksparser.py                   | 17 +++++
>  scripts/lib/wic/misc.py                       |  8 +-
>  scripts/lib/wic/partition.py                  | 74
> +++++++++++++------ scripts/lib/wic/plugins/imager/direct.py      |
> 61 ++++++++------- scripts/lib/wic/plugins/source/bootimg-efi.py |  8
> +- scripts/lib/wic/plugins/source/empty.py       | 32 ++++++++
>  .../wic/plugins/source/isoimage-isohybrid.py  | 14 ++++
>  scripts/lib/wic/plugins/source/rootfs.py      | 33 +++++++--
>  scripts/wic                                   |  2 +
>  12 files changed, 187 insertions(+), 68 deletions(-)
>  create mode 100644 scripts/lib/wic/plugins/source/empty.py
> 
> diff --git a/scripts/lib/wic/canned-wks/common.wks.inc
> b/scripts/lib/wic/canned-wks/common.wks.inc index 89880b4..4fd29fa
> 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 --use-uuid
> --fstype=ext4 --label platform --align 1024 +part / --source rootfs
> --use-uuid --fstype=ext4 --mkfs-extraopts "-T default" --label
> platform --align 1024 diff --git
> a/scripts/lib/wic/canned-wks/directdisk-gpt.wks
> b/scripts/lib/wic/canned-wks/directdisk-gpt.wks index
> 8d7d8de..cf16c0c 100644 ---
> a/scripts/lib/wic/canned-wks/directdisk-gpt.wks +++
> b/scripts/lib/wic/canned-wks/directdisk-gpt.wks @@ -4,7 +4,7 @@ 
>  part /boot --source bootimg-pcbios --ondisk sda --label boot
> --active --align 1024 -part / --source rootfs --ondisk sda
> --fstype=ext4 --label platform --align 1024 --use-uuid +part /
> --source rootfs --ondisk sda --fstype=ext4 --mkfs-extraopts "-T
> default" --label platform --align 1024 --use-uuid bootloader
> --ptable gpt --timeout=0  --append="rootwait rootfstype=ext4
> video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8" diff
> --git a/scripts/lib/wic/canned-wks/mkefidisk.wks
> b/scripts/lib/wic/canned-wks/mkefidisk.wks index 9f534fe..d1878e2
> 100644 --- a/scripts/lib/wic/canned-wks/mkefidisk.wks +++
> b/scripts/lib/wic/canned-wks/mkefidisk.wks @@ -4,7 +4,7 @@
>  
>  part /boot --source bootimg-efi --sourceparams="loader=grub-efi"
> --ondisk sda --label msdos --active --align 1024 
> -part / --source rootfs --ondisk sda --fstype=ext4 --label platform
> --align 1024 --use-uuid +part / --source rootfs --ondisk sda
> --fstype=ext4 --mkfs-extraopts "-T default"  --label platform --align
> 1024 --use-uuid part swap --ondisk sda --size 44 --label swap1
> --fstype=swap 
> diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py
> index 913e328..3eb669d 100644
> --- a/scripts/lib/wic/ksparser.py
> +++ b/scripts/lib/wic/ksparser.py
> @@ -229,6 +229,23 @@ class KickStart():
>                                  err = "%s:%d: SquashFS does not
> support LABEL" \ % (confpath, lineno)
>                                  raise KickStartError(err)
> +                        if parsed.fstype == 'msdos' or parsed.fstype
> == 'vfat':
> +                            if parsed.fsuuid:
> +                                if
> parsed.fsuuid.upper().startswith('0X'):
> +                                    if len(parsed.fsuuid) > 10:
> +                                        err = "%s:%d: fsuuid %s
> given in wks kickstart file " \
> +                                              "exceeds the length
> limit for %s filesystem. " \
> +                                              "It should be in the
> form of a 32 bit hexadecimal" \
> +                                              "number (for example,
> 0xABCD1234)." \
> +                                              % (confpath, lineno,
> parsed.fsuuid, parsed.fstype)
> +                                        raise KickStartError(err)
> +                                elif len(parsed.fsuuid) > 8:
> +                                    err = "%s:%d: fsuuid %s given in
> wks kickstart file " \
> +                                          "exceeds the length limit
> for %s filesystem. " \
> +                                          "It should be in the form
> of a 32 bit hexadecimal" \
> +                                          "number (for example,
> 0xABCD1234)." \
> +                                          % (confpath, lineno,
> parsed.fsuuid, parsed.fstype)
> +                                    raise KickStartError(err)
>                          if parsed.use_label and not parsed.label:
>                              err = "%s:%d: Must set the label with
> --label" \ % (confpath, lineno)
> diff --git a/scripts/lib/wic/misc.py b/scripts/lib/wic/misc.py
> index 4b08d64..57c042c 100644
> --- a/scripts/lib/wic/misc.py
> +++ b/scripts/lib/wic/misc.py
> @@ -26,6 +26,7 @@ logger = logging.getLogger('wic')
>  
>  # executable -> recipe pairs for exec_native_cmd
>  NATIVE_RECIPES = {"bmaptool": "bmap-tools",
> +                  "dumpe2fs": "e2fsprogs",
>                    "grub-mkimage": "grub-efi",
>                    "isohybrid": "syslinux",
>                    "mcopy": "mtools",
> @@ -138,9 +139,12 @@ def exec_native_cmd(cmd_and_args,
> native_sysroot, pseudo=""): if pseudo:
>          cmd_and_args = pseudo + cmd_and_args
>  
> -    native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin:%s/bin" % \
> +    hosttools_dir = get_bitbake_var("HOSTTOOLS_DIR")
> +
> +    native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin:%s/bin:%s" % \
>                     (native_sysroot, native_sysroot,
> -                    native_sysroot, native_sysroot)
> +                    native_sysroot, native_sysroot,
> +                    hosttools_dir)
>  
>      native_cmd_and_args = "export PATH=%s:$PATH;%s" % \
>                     (native_paths, cmd_and_args)
> diff --git a/scripts/lib/wic/partition.py
> b/scripts/lib/wic/partition.py index 4a5a31e..76d144d 100644
> --- a/scripts/lib/wic/partition.py
> +++ b/scripts/lib/wic/partition.py
> @@ -54,6 +54,9 @@ class Partition():
>          self.uuid = args.uuid
>          self.fsuuid = args.fsuuid
>          self.type = args.type
> +        self.updated_fstab_path = None
> +        self.has_fstab = False
> +        self.update_fstab_in_rootfs = False
>  
>          self.lineno = lineno
>          self.source_file = ""
> @@ -118,11 +121,15 @@ class Partition():
>          return self.fixed_size if self.fixed_size else self.size
>  
>      def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir,
> -                bootimg_dir, kernel_dir, native_sysroot):
> +                bootimg_dir, kernel_dir, native_sysroot,
> updated_fstab_path): """
>          Prepare content for individual partitions, depending on
>          partition command parameters.
>          """
> +        self.updated_fstab_path = updated_fstab_path
> +        if self.updated_fstab_path and not
> (self.fstype.startswith("ext") or self.fstype == "msdos"):
> +            self.update_fstab_in_rootfs = True
> +
>          if not self.source:
>              if not self.size and not self.fixed_size:
>                  raise WicError("The %s partition has a size of zero.
> Please " @@ -199,21 +206,33 @@ class Partition():
>  
>          Currently handles ext2/3/4, btrfs, vfat and squashfs.
>          """
> +
> +        rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label,
> +                                         self.lineno, self.fstype)
> +        if os.path.isfile(rootfs):
> +            os.remove(rootfs)
> +
>          p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" %
> native_sysroot) if (pseudo_dir):
> +            # Canonicalize the ignore paths. This corresponds to
> +            # calling oe.path.canonicalize(), which is used in
> bitbake.conf.
> +            ignore_paths = [rootfs] +
> (get_bitbake_var("PSEUDO_IGNORE_PATHS") or "").split(",")
> +            canonical_paths = []
> +            for path in ignore_paths:
> +                if "$" not in path:
> +                    trailing_slash = path.endswith("/") and "/" or ""
> +                    canonical_paths.append(os.path.realpath(path) +
> trailing_slash)
> +            ignore_paths = ",".join(canonical_paths)
> +
>              pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix
>              pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir
>              pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
>              pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
> +            pseudo += "export PSEUDO_IGNORE_PATHS=%s;" % ignore_paths
>              pseudo += "%s " % get_bitbake_var("FAKEROOTCMD")
>          else:
>              pseudo = None
>  
> -        rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label,
> -                                         self.lineno, self.fstype)
> -        if os.path.isfile(rootfs):
> -            os.remove(rootfs)
> -
>          if not self.size and real_rootfs:
>              # The rootfs size is not set in .ks file so try to get it
>              # from bitbake variable
> @@ -235,7 +254,7 @@ class Partition():
>  
>          prefix = "ext" if self.fstype.startswith("ext") else
> self.fstype method = getattr(self, "prepare_rootfs_" + prefix)
> -        method(rootfs, oe_builddir, rootfs_dir, native_sysroot,
> pseudo)
> +        method(rootfs, cr_workdir, oe_builddir, rootfs_dir,
> native_sysroot, pseudo) self.source_file = rootfs
>  
>          # get the rootfs size in the right units for kickstart (kB)
> @@ -243,7 +262,7 @@ class Partition():
>          out = exec_cmd(du_cmd)
>          self.size = int(out.split()[0])
>  
> -    def prepare_rootfs_ext(self, rootfs, oe_builddir, rootfs_dir,
> +    def prepare_rootfs_ext(self, rootfs, cr_workdir, oe_builddir,
> rootfs_dir, native_sysroot, pseudo):
>          """
>          Prepare content for an ext2/3/4 rootfs partition.
> @@ -267,12 +286,21 @@ class Partition():
>              (self.fstype, extraopts, rootfs, label_str, self.fsuuid,
> rootfs_dir) exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
>  
> +        if self.updated_fstab_path and self.has_fstab:
> +            debugfs_script_path = os.path.join(cr_workdir,
> "debugfs_script")
> +            with open(debugfs_script_path, "w") as f:
> +                f.write("cd etc\n")
> +                f.write("rm fstab\n")
> +                f.write("write %s fstab\n" %
> (self.updated_fstab_path))
> +            debugfs_cmd = "debugfs -w -f %s %s" %
> (debugfs_script_path, rootfs)
> +            exec_native_cmd(debugfs_cmd, native_sysroot)
> +
>          mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs)
>          exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
>  
>          self.check_for_Y2038_problem(rootfs, native_sysroot)
>  
> -    def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir,
> +    def prepare_rootfs_btrfs(self, rootfs, cr_workdir, oe_builddir,
> rootfs_dir, native_sysroot, pseudo):
>          """
>          Prepare content for a btrfs rootfs partition.
> @@ -295,7 +323,7 @@ class Partition():
>               self.mkfs_extraopts, self.fsuuid, rootfs)
>          exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
>  
> -    def prepare_rootfs_msdos(self, rootfs, oe_builddir, rootfs_dir,
> +    def prepare_rootfs_msdos(self, rootfs, cr_workdir, oe_builddir,
> rootfs_dir, native_sysroot, pseudo):
>          """
>          Prepare content for a msdos/vfat rootfs partition.
> @@ -311,8 +339,6 @@ class Partition():
>              label_str = "-n %s" % self.label
>  
>          size_str = ""
> -        if self.fstype == 'msdos':
> -            size_str = "-F 16" # FAT 16
>  
>          extraopts = self.mkfs_extraopts or '-S 512'
>  
> @@ -324,12 +350,16 @@ class Partition():
>          mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir)
>          exec_native_cmd(mcopy_cmd, native_sysroot)
>  
> +        if self.updated_fstab_path and self.has_fstab:
> +            mcopy_cmd = "mcopy -i %s %s ::/etc/fstab" % (rootfs,
> self.updated_fstab_path)
> +            exec_native_cmd(mcopy_cmd, native_sysroot)
> +
>          chmod_cmd = "chmod 644 %s" % rootfs
>          exec_cmd(chmod_cmd)
>  
>      prepare_rootfs_vfat = prepare_rootfs_msdos
>  
> -    def prepare_rootfs_squashfs(self, rootfs, oe_builddir,
> rootfs_dir,
> +    def prepare_rootfs_squashfs(self, rootfs, cr_workdir,
> oe_builddir, rootfs_dir, native_sysroot, pseudo):
>          """
>          Prepare content for a squashfs rootfs partition.
> @@ -390,8 +420,6 @@ class Partition():
>              label_str = "-n %s" % self.label
>  
>          size_str = ""
> -        if self.fstype == 'msdos':
> -            size_str = "-F 16" # FAT 16
>  
>          extraopts = self.mkfs_extraopts or '-S 512'
>  
> @@ -432,26 +460,26 @@ class Partition():
>              if part.mountpoint:
>                  args = [part.fstype, "mounted at %s" %
> part.mountpoint] elif part.label:
> -                args = [part.fstype, "labeled %s" % part.label]
> +                args = [part.fstype, "labeled '%s'" % part.label]
>              elif part.part_name:
> -                args = [part.fstype, "in partition %s" %
> part.part_name]
> +                args = [part.fstype, "in partition '%s'" %
> part.part_name] else:
> -                args = [part.fstype, ""]
> +                args = [part.fstype, "in partition %s" % part.num]
>              return err.format(*args)
>  
> -        ret, out = exec_native_cmd("dumpe2fs %s" % rootfs,
> native_sysroot) -
>          # ext2 and ext3 are always affected by the Y2038 problem
>          if self.fstype in ["ext2", "ext3"]:
>              logger.warn(get_err_str(self))
>              return
>  
> +        ret, out = exec_native_cmd("dumpe2fs %s" % rootfs,
> native_sysroot) +
>          # if ext4 is affected by the Y2038 problem depends on the
> inode size
> -        # Remember: inode size depends on the file system size
>          for line in out.splitlines():
>              if line.startswith("Inode size:"):
>                  size = int(line.split(":")[1].strip())
>                  if size < 256:
> -                    logger.warn("%s Inodes (of size %d) are too
> small." % \
> +                    logger.warn("%s Inodes (of size %d) are too
> small." % (get_err_str(self), size))
> -                break
> \ No newline at end of file
> +                break
> +
> diff --git a/scripts/lib/wic/plugins/imager/direct.py
> b/scripts/lib/wic/plugins/imager/direct.py index 55db826..ea709e8
> 100644 --- a/scripts/lib/wic/plugins/imager/direct.py
> +++ b/scripts/lib/wic/plugins/imager/direct.py
> @@ -54,15 +54,16 @@ class DirectPlugin(ImagerPlugin):
>          self.native_sysroot = native_sysroot
>          self.oe_builddir = oe_builddir
>  
> +        self.debug = options.debug
>          self.outdir = options.outdir
>          self.compressor = options.compressor
>          self.bmap = options.bmap
>          self.no_fstab_update = options.no_fstab_update
> -        self.original_fstab = None
> +        self.updated_fstab_path = None
>  
>          self.name = "%s-%s" %
> (os.path.splitext(os.path.basename(wks_file))[0],
> strftime("%Y%m%d%H%M"))
> -        self.workdir = tempfile.mkdtemp(dir=self.outdir,
> prefix='tmp.wic.')
> +        self.workdir = self.setup_workdir(options.workdir)
>          self._image = None
>          self.ptable_format = self.ks.bootloader.ptable
>          self.parts = self.ks.partitions
> @@ -78,6 +79,16 @@ class DirectPlugin(ImagerPlugin):
>          self._image = PartitionedImage(image_path,
> self.ptable_format, self.parts, self.native_sysroot)
>  
> +    def setup_workdir(self, workdir):
> +        if workdir:
> +            if os.path.exists(workdir):
> +                raise WicError("Internal workdir '%s' specified in
> wic arguments already exists!" % (workdir)) +
> +            os.makedirs(workdir)
> +            return workdir
> +        else:
> +            return tempfile.mkdtemp(dir=self.outdir,
> prefix='tmp.wic.') +
>      def do_create(self):
>          """
>          Plugin entry point.
> @@ -90,11 +101,8 @@ class DirectPlugin(ImagerPlugin):
>          finally:
>              self.cleanup()
>  
> -    def _write_fstab(self, image_rootfs):
> -        """overriden to generate fstab (temporarily) in rootfs. This
> is called
> -        from _create, make sure it doesn't get called from
> -        BaseImage.create()
> -        """
> +    def update_fstab(self, image_rootfs):
> +        """Assume partition order same as in wks"""
>          if not image_rootfs:
>              return
>  
> @@ -104,18 +112,9 @@ class DirectPlugin(ImagerPlugin):
>  
>          with open(fstab_path) as fstab:
>              fstab_lines = fstab.readlines()
> -            self.original_fstab = fstab_lines.copy()
> -
> -        if self._update_fstab(fstab_lines, self.parts):
> -            with open(fstab_path, "w") as fstab:
> -                fstab.writelines(fstab_lines)
> -        else:
> -            self.original_fstab = None
>  
> -    def _update_fstab(self, fstab_lines, parts):
> -        """Assume partition order same as in wks"""
>          updated = False
> -        for part in parts:
> +        for part in self.parts:
>              if not part.realnum or not part.mountpoint \
>                 or part.mountpoint == "/":
>                  continue
> @@ -144,7 +143,10 @@ class DirectPlugin(ImagerPlugin):
>              fstab_lines.append(line)
>              updated = True
>  
> -        return updated
> +        if updated:
> +            self.updated_fstab_path = os.path.join(self.workdir,
> "fstab")
> +            with open(self.updated_fstab_path, "w") as f:
> +                f.writelines(fstab_lines)
>  
>      def _full_path(self, path, name, extention):
>          """ Construct full file path to a file we generate. """
> @@ -160,7 +162,7 @@ class DirectPlugin(ImagerPlugin):
>          a partitioned image.
>          """
>          if not self.no_fstab_update:
> -            self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
> +            self.update_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
>  
>          for part in self.parts:
>              # get rootfs size from bitbake variable if it's not set
> in .ks file @@ -273,14 +275,9 @@ class DirectPlugin(ImagerPlugin):
>              if os.path.isfile(path):
>                  shutil.move(path, os.path.join(self.outdir, fname))
>  
> -        #Restore original fstab
> -        if self.original_fstab:
> -            fstab_path = self.rootfs_dir.get("ROOTFS_DIR") +
> "/etc/fstab"
> -            with open(fstab_path, "w") as fstab:
> -                fstab.writelines(self.original_fstab)
> -
> -        # remove work directory
> -        shutil.rmtree(self.workdir, ignore_errors=True)
> +        # remove work directory when it is not in debugging mode
> +        if not self.debug:
> +            shutil.rmtree(self.workdir, ignore_errors=True)
>  
>  # Overhead of the MBR partitioning scheme (just one sector)
>  MBR_OVERHEAD = 1
> @@ -343,6 +340,13 @@ class PartitionedImage():
>                      part.fsuuid = '0x' +
> str(uuid.uuid4())[:8].upper() else:
>                      part.fsuuid = str(uuid.uuid4())
> +            else:
> +                #make sure the fsuuid for vfat/msdos align with
> format 0xYYYYYYYY
> +                if part.fstype == 'vfat' or part.fstype == 'msdos':
> +                    if part.fsuuid.upper().startswith("0X"):
> +                        part.fsuuid = '0x' +
> part.fsuuid.upper()[2:].rjust(8,"0")
> +                    else:
> +                        part.fsuuid = '0x' +
> part.fsuuid.upper().rjust(8,"0") 
>      def prepare(self, imager):
>          """Prepare an image. Call prepare method of all image
> partitions.""" @@ -351,7 +355,8 @@ class PartitionedImage():
>              # sizes before we can add them and do the layout.
>              part.prepare(imager, imager.workdir, imager.oe_builddir,
>                           imager.rootfs_dir, imager.bootimg_dir,
> -                         imager.kernel_dir, imager.native_sysroot)
> +                         imager.kernel_dir, imager.native_sysroot,
> +                         imager.updated_fstab_path)
>  
>              # Converting kB to sectors for parted
>              part.size_sec = part.disk_size * 1024 // self.sector_size
> diff --git a/scripts/lib/wic/plugins/source/bootimg-efi.py
> b/scripts/lib/wic/plugins/source/bootimg-efi.py index
> 14c1723..cdc7254 100644 ---
> a/scripts/lib/wic/plugins/source/bootimg-efi.py +++
> b/scripts/lib/wic/plugins/source/bootimg-efi.py @@ -212,8 +212,8 @@
> class BootimgEFIPlugin(SourcePlugin): except KeyError:
>              raise WicError("bootimg-efi requires a loader, none
> specified") 
> -        if get_bitbake_var("IMAGE_BOOT_FILES") is None:
> -            logger.debug('No boot files defined in IMAGE_BOOT_FILES')
> +        if get_bitbake_var("IMAGE_EFI_BOOT_FILES") is None:
> +            logger.debug('No boot files defined in
> IMAGE_EFI_BOOT_FILES') else:
>              boot_files = None
>              for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s",
> part.label), (None, None)): @@ -222,7 +222,7 @@ class
> BootimgEFIPlugin(SourcePlugin): else:
>                      var = ""
>  
> -                boot_files = get_bitbake_var("IMAGE_BOOT_FILES" +
> var)
> +                boot_files = get_bitbake_var("IMAGE_EFI_BOOT_FILES"
> + var) if boot_files:
>                      break
>  
> @@ -292,7 +292,7 @@ class BootimgEFIPlugin(SourcePlugin):
>              (staging_kernel_dir, kernel, hdddir, kernel)
>          exec_cmd(install_cmd)
>  
> -        if get_bitbake_var("IMAGE_BOOT_FILES"):
> +        if get_bitbake_var("IMAGE_EFI_BOOT_FILES"):
>              for src_path, dst_path in cls.install_task:
>                  install_cmd = "install -m 0644 -D %s %s" \
>                                % (os.path.join(kernel_dir, src_path),
> diff --git a/scripts/lib/wic/plugins/source/empty.py
> b/scripts/lib/wic/plugins/source/empty.py new file mode 100644
> index 0000000..041617d
> --- /dev/null
> +++ b/scripts/lib/wic/plugins/source/empty.py
> @@ -0,0 +1,32 @@
> +#
> +# SPDX-License-Identifier: MIT
> +#
> +
> +# The empty wic plugin is used to create unformatted empty
> partitions for wic +# images.
> +# To use it you must pass "empty" as argument for the "--source"
> parameter in +# the wks file. For example:
> +# part foo --source empty --ondisk sda --size="1024" --align 1024
> +
> +import logging
> +
> +from wic.pluginbase import SourcePlugin
> +
> +logger = logging.getLogger('wic')
> +
> +class EmptyPartitionPlugin(SourcePlugin):
> +    """
> +    Populate unformatted empty partition.
> +    """
> +
> +    name = 'empty'
> +
> +    @classmethod
> +    def do_prepare_partition(cls, part, source_params, cr,
> cr_workdir,
> +                             oe_builddir, bootimg_dir, kernel_dir,
> +                             rootfs_dir, native_sysroot):
> +        """
> +        Called to do the actual content population for a partition
> i.e. it
> +        'prepares' the partition to be incorporated into the image.
> +        """
> +        return
> diff --git a/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
> b/scripts/lib/wic/plugins/source/isoimage-isohybrid.py index
> 11326a2..afc9ea0 100644 ---
> a/scripts/lib/wic/plugins/source/isoimage-isohybrid.py +++
> b/scripts/lib/wic/plugins/source/isoimage-isohybrid.py @@ -216,6
> +216,18 @@ class IsoImagePlugin(SourcePlugin): creator.name =
> source_params['image_name'].strip() logger.debug("The name of the
> image is: %s", creator.name) 
> +    @staticmethod
> +    def _install_payload(source_params, iso_dir):
> +        """
> +        Copies contents of payload directory (as specified in
> 'payload_dir' param) into iso_dir
> +        """
> +
> +        if source_params.get('payload_dir'):
> +            payload_dir = source_params['payload_dir']
> +
> +            logger.debug("Payload directory: %s", payload_dir)
> +            shutil.copytree(payload_dir, iso_dir, symlinks=True,
> dirs_exist_ok=True) +
>      @classmethod
>      def do_prepare_partition(cls, part, source_params, creator,
> cr_workdir, oe_builddir, bootimg_dir, kernel_dir,
> @@ -228,6 +240,8 @@ class IsoImagePlugin(SourcePlugin):
>  
>          isodir = "%s/ISO" % cr_workdir
>  
> +        cls._install_payload(source_params, isodir)
> +
>          if part.rootfs_dir is None:
>              if not 'ROOTFS_DIR' in rootfs_dir:
>                  raise WicError("Couldn't find --rootfs-dir,
> exiting.") diff --git a/scripts/lib/wic/plugins/source/rootfs.py
> b/scripts/lib/wic/plugins/source/rootfs.py index f1db83f..96d940a
> 100644 --- a/scripts/lib/wic/plugins/source/rootfs.py
> +++ b/scripts/lib/wic/plugins/source/rootfs.py
> @@ -94,6 +94,7 @@ class RootfsPlugin(SourcePlugin):
>                                 "it is not a valid path, exiting" %
> part.rootfs_dir) 
>          part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
> +        part.has_fstab =
> os.path.exists(os.path.join(part.rootfs_dir, "etc/fstab")) pseudo_dir
> = os.path.join(part.rootfs_dir, "../pseudo") if not
> os.path.lexists(pseudo_dir): logger.warn("%s folder does not exist. "
> @@ -103,9 +104,9 @@ class RootfsPlugin(SourcePlugin):
>          new_rootfs = None
>          new_pseudo = None
>          # Handle excluded paths.
> -        if part.exclude_path or part.include_path or
> part.change_directory:
> -            # We need a new rootfs directory we can delete files
> from. Copy to
> -            # workdir.
> +        if part.exclude_path or part.include_path or
> part.change_directory or part.update_fstab_in_rootfs:
> +            # We need a new rootfs directory we can safely modify
> without
> +            # interfering with other tasks. Copy to workdir.
>              new_rootfs = os.path.realpath(os.path.join(cr_workdir,
> "rootfs%d" % part.lineno)) 
>              if os.path.lexists(new_rootfs):
> @@ -199,17 +200,33 @@ class RootfsPlugin(SourcePlugin):
>                  if not os.path.lexists(full_path):
>                      continue
>  
> +                if new_pseudo:
> +                    pseudo = cls.__get_pseudo(native_sysroot,
> new_rootfs, new_pseudo)
> +                else:
> +                    pseudo = None
>                  if path.endswith(os.sep):
>                      # Delete content only.
>                      for entry in os.listdir(full_path):
>                          full_entry = os.path.join(full_path, entry)
> -                        if os.path.isdir(full_entry) and not
> os.path.islink(full_entry):
> -                            shutil.rmtree(full_entry)
> -                        else:
> -                            os.remove(full_entry)
> +                        rm_cmd = "rm -rf %s" % (full_entry)
> +                        exec_native_cmd(rm_cmd, native_sysroot,
> pseudo) else:
>                      # Delete whole directory.
> -                    shutil.rmtree(full_path)
> +                    rm_cmd = "rm -rf %s" % (full_path)
> +                    exec_native_cmd(rm_cmd, native_sysroot, pseudo)
> +
> +            # Update part.has_fstab here as fstab may have been
> added or
> +            # removed by the above modifications.
> +            part.has_fstab = os.path.exists(os.path.join(new_rootfs,
> "etc/fstab"))
> +            if part.update_fstab_in_rootfs and part.has_fstab:
> +                fstab_path = os.path.join(new_rootfs, "etc/fstab")
> +                # Assume that fstab should always be owned by root
> with fixed permissions
> +                install_cmd = "install -m 0644 %s %s" %
> (part.updated_fstab_path, fstab_path)
> +                if new_pseudo:
> +                    pseudo = cls.__get_pseudo(native_sysroot,
> new_rootfs, new_pseudo)
> +                else:
> +                    pseudo = None
> +                exec_native_cmd(install_cmd, native_sysroot, pseudo)
>  
>          part.prepare_rootfs(cr_workdir, oe_builddir,
>                              new_rootfs or part.rootfs_dir,
> native_sysroot, diff --git a/scripts/wic b/scripts/wic
> index 24700f3..a741aed 100755
> --- a/scripts/wic
> +++ b/scripts/wic
> @@ -312,6 +312,8 @@ def wic_init_parser_create(subparser):
>  
>      subparser.add_argument("-o", "--outdir", dest="outdir",
> default='.', help="name of directory to create image in")
> +    subparser.add_argument("-w", "--workdir",
> +                      help="temporary workdir to use for
> intermediate files") subparser.add_argument("-e", "--image-name",
> dest="image_name", help="name of the image to use the artifacts from "
>                             "e.g. core-image-sato")


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] wic: Update to the latest revision
  2021-06-02  8:37 [PATCH] wic: Update to the latest revision Anton Mikanovich
  2021-06-02  9:00 ` Jan Kiszka
  2021-06-08  7:40 ` Henning Schild
@ 2021-06-08  7:45 ` Henning Schild
  2 siblings, 0 replies; 5+ messages in thread
From: Henning Schild @ 2021-06-08  7:45 UTC (permalink / raw)
  To: Anton Mikanovich; +Cc: isar-users

Am Wed,  2 Jun 2021 11:37:41 +0300
schrieb Anton Mikanovich <amikan@ilbers.de>:

> Update to the latest wic from OE-core.
> 
> OE-core Revision: b85a09ea450a5e8f49418f4a930805fbb88dc83b
> 
> Signed-off-by: Anton Mikanovich <amikan@ilbers.de>
> ---
>  scripts/lib/wic/canned-wks/common.wks.inc     |  2 +-
>  scripts/lib/wic/canned-wks/directdisk-gpt.wks |  2 +-
>  scripts/lib/wic/canned-wks/mkefidisk.wks      |  2 +-
>  scripts/lib/wic/ksparser.py                   | 17 +++++
>  scripts/lib/wic/misc.py                       |  8 +-
>  scripts/lib/wic/partition.py                  | 74
> +++++++++++++------ scripts/lib/wic/plugins/imager/direct.py      |
> 61 ++++++++------- scripts/lib/wic/plugins/source/bootimg-efi.py |  8
> +- scripts/lib/wic/plugins/source/empty.py       | 32 ++++++++
>  .../wic/plugins/source/isoimage-isohybrid.py  | 14 ++++
>  scripts/lib/wic/plugins/source/rootfs.py      | 33 +++++++--
>  scripts/wic                                   |  2 +
>  12 files changed, 187 insertions(+), 68 deletions(-)
>  create mode 100644 scripts/lib/wic/plugins/source/empty.py
> 
> diff --git a/scripts/lib/wic/canned-wks/common.wks.inc
> b/scripts/lib/wic/canned-wks/common.wks.inc index 89880b4..4fd29fa
> 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 --use-uuid
> --fstype=ext4 --label platform --align 1024 +part / --source rootfs
> --use-uuid --fstype=ext4 --mkfs-extraopts "-T default" --label
> platform --align 1024 diff --git
> a/scripts/lib/wic/canned-wks/directdisk-gpt.wks
> b/scripts/lib/wic/canned-wks/directdisk-gpt.wks index
> 8d7d8de..cf16c0c 100644 ---
> a/scripts/lib/wic/canned-wks/directdisk-gpt.wks +++
> b/scripts/lib/wic/canned-wks/directdisk-gpt.wks @@ -4,7 +4,7 @@ 
>  part /boot --source bootimg-pcbios --ondisk sda --label boot
> --active --align 1024 -part / --source rootfs --ondisk sda
> --fstype=ext4 --label platform --align 1024 --use-uuid +part /
> --source rootfs --ondisk sda --fstype=ext4 --mkfs-extraopts "-T
> default" --label platform --align 1024 --use-uuid bootloader
> --ptable gpt --timeout=0  --append="rootwait rootfstype=ext4
> video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8" diff
> --git a/scripts/lib/wic/canned-wks/mkefidisk.wks
> b/scripts/lib/wic/canned-wks/mkefidisk.wks index 9f534fe..d1878e2
> 100644 --- a/scripts/lib/wic/canned-wks/mkefidisk.wks +++
> b/scripts/lib/wic/canned-wks/mkefidisk.wks @@ -4,7 +4,7 @@
>  
>  part /boot --source bootimg-efi --sourceparams="loader=grub-efi"
> --ondisk sda --label msdos --active --align 1024 
> -part / --source rootfs --ondisk sda --fstype=ext4 --label platform
> --align 1024 --use-uuid +part / --source rootfs --ondisk sda
> --fstype=ext4 --mkfs-extraopts "-T default"  --label platform --align
> 1024 --use-uuid part swap --ondisk sda --size 44 --label swap1
> --fstype=swap 
> diff --git a/scripts/lib/wic/ksparser.py b/scripts/lib/wic/ksparser.py
> index 913e328..3eb669d 100644
> --- a/scripts/lib/wic/ksparser.py
> +++ b/scripts/lib/wic/ksparser.py
> @@ -229,6 +229,23 @@ class KickStart():
>                                  err = "%s:%d: SquashFS does not
> support LABEL" \ % (confpath, lineno)
>                                  raise KickStartError(err)
> +                        if parsed.fstype == 'msdos' or parsed.fstype
> == 'vfat':
> +                            if parsed.fsuuid:
> +                                if
> parsed.fsuuid.upper().startswith('0X'):
> +                                    if len(parsed.fsuuid) > 10:
> +                                        err = "%s:%d: fsuuid %s
> given in wks kickstart file " \
> +                                              "exceeds the length
> limit for %s filesystem. " \
> +                                              "It should be in the
> form of a 32 bit hexadecimal" \
> +                                              "number (for example,
> 0xABCD1234)." \
> +                                              % (confpath, lineno,
> parsed.fsuuid, parsed.fstype)
> +                                        raise KickStartError(err)
> +                                elif len(parsed.fsuuid) > 8:
> +                                    err = "%s:%d: fsuuid %s given in
> wks kickstart file " \
> +                                          "exceeds the length limit
> for %s filesystem. " \
> +                                          "It should be in the form
> of a 32 bit hexadecimal" \
> +                                          "number (for example,
> 0xABCD1234)." \
> +                                          % (confpath, lineno,
> parsed.fsuuid, parsed.fstype)
> +                                    raise KickStartError(err)
>                          if parsed.use_label and not parsed.label:
>                              err = "%s:%d: Must set the label with
> --label" \ % (confpath, lineno)
> diff --git a/scripts/lib/wic/misc.py b/scripts/lib/wic/misc.py
> index 4b08d64..57c042c 100644
> --- a/scripts/lib/wic/misc.py
> +++ b/scripts/lib/wic/misc.py
> @@ -26,6 +26,7 @@ logger = logging.getLogger('wic')
>  
>  # executable -> recipe pairs for exec_native_cmd
>  NATIVE_RECIPES = {"bmaptool": "bmap-tools",
> +                  "dumpe2fs": "e2fsprogs",
>                    "grub-mkimage": "grub-efi",
>                    "isohybrid": "syslinux",
>                    "mcopy": "mtools",
> @@ -138,9 +139,12 @@ def exec_native_cmd(cmd_and_args,
> native_sysroot, pseudo=""): if pseudo:
>          cmd_and_args = pseudo + cmd_and_args
>  
> -    native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin:%s/bin" % \
> +    hosttools_dir = get_bitbake_var("HOSTTOOLS_DIR")
> +
> +    native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin:%s/bin:%s" % \
>                     (native_sysroot, native_sysroot,
> -                    native_sysroot, native_sysroot)
> +                    native_sysroot, native_sysroot,
> +                    hosttools_dir)
>  
>      native_cmd_and_args = "export PATH=%s:$PATH;%s" % \
>                     (native_paths, cmd_and_args)
> diff --git a/scripts/lib/wic/partition.py
> b/scripts/lib/wic/partition.py index 4a5a31e..76d144d 100644
> --- a/scripts/lib/wic/partition.py
> +++ b/scripts/lib/wic/partition.py
> @@ -54,6 +54,9 @@ class Partition():
>          self.uuid = args.uuid
>          self.fsuuid = args.fsuuid
>          self.type = args.type
> +        self.updated_fstab_path = None
> +        self.has_fstab = False
> +        self.update_fstab_in_rootfs = False
>  
>          self.lineno = lineno
>          self.source_file = ""
> @@ -118,11 +121,15 @@ class Partition():
>          return self.fixed_size if self.fixed_size else self.size
>  
>      def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir,
> -                bootimg_dir, kernel_dir, native_sysroot):
> +                bootimg_dir, kernel_dir, native_sysroot,
> updated_fstab_path): """
>          Prepare content for individual partitions, depending on
>          partition command parameters.
>          """
> +        self.updated_fstab_path = updated_fstab_path
> +        if self.updated_fstab_path and not
> (self.fstype.startswith("ext") or self.fstype == "msdos"):
> +            self.update_fstab_in_rootfs = True
> +
>          if not self.source:
>              if not self.size and not self.fixed_size:
>                  raise WicError("The %s partition has a size of zero.
> Please " @@ -199,21 +206,33 @@ class Partition():
>  
>          Currently handles ext2/3/4, btrfs, vfat and squashfs.
>          """
> +
> +        rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label,
> +                                         self.lineno, self.fstype)
> +        if os.path.isfile(rootfs):
> +            os.remove(rootfs)
> +
>          p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" %
> native_sysroot) if (pseudo_dir):
> +            # Canonicalize the ignore paths. This corresponds to
> +            # calling oe.path.canonicalize(), which is used in
> bitbake.conf.
> +            ignore_paths = [rootfs] +
> (get_bitbake_var("PSEUDO_IGNORE_PATHS") or "").split(",")
> +            canonical_paths = []
> +            for path in ignore_paths:
> +                if "$" not in path:
> +                    trailing_slash = path.endswith("/") and "/" or ""
> +                    canonical_paths.append(os.path.realpath(path) +
> trailing_slash)
> +            ignore_paths = ",".join(canonical_paths)
> +
>              pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix
>              pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % pseudo_dir
>              pseudo += "export PSEUDO_PASSWD=%s;" % rootfs_dir
>              pseudo += "export PSEUDO_NOSYMLINKEXP=1;"
> +            pseudo += "export PSEUDO_IGNORE_PATHS=%s;" % ignore_paths
>              pseudo += "%s " % get_bitbake_var("FAKEROOTCMD")
>          else:
>              pseudo = None
>  
> -        rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label,
> -                                         self.lineno, self.fstype)
> -        if os.path.isfile(rootfs):
> -            os.remove(rootfs)
> -
>          if not self.size and real_rootfs:
>              # The rootfs size is not set in .ks file so try to get it
>              # from bitbake variable
> @@ -235,7 +254,7 @@ class Partition():
>  
>          prefix = "ext" if self.fstype.startswith("ext") else
> self.fstype method = getattr(self, "prepare_rootfs_" + prefix)
> -        method(rootfs, oe_builddir, rootfs_dir, native_sysroot,
> pseudo)
> +        method(rootfs, cr_workdir, oe_builddir, rootfs_dir,
> native_sysroot, pseudo) self.source_file = rootfs
>  
>          # get the rootfs size in the right units for kickstart (kB)
> @@ -243,7 +262,7 @@ class Partition():
>          out = exec_cmd(du_cmd)
>          self.size = int(out.split()[0])
>  
> -    def prepare_rootfs_ext(self, rootfs, oe_builddir, rootfs_dir,
> +    def prepare_rootfs_ext(self, rootfs, cr_workdir, oe_builddir,
> rootfs_dir, native_sysroot, pseudo):
>          """
>          Prepare content for an ext2/3/4 rootfs partition.
> @@ -267,12 +286,21 @@ class Partition():
>              (self.fstype, extraopts, rootfs, label_str, self.fsuuid,
> rootfs_dir) exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
>  
> +        if self.updated_fstab_path and self.has_fstab:
> +            debugfs_script_path = os.path.join(cr_workdir,
> "debugfs_script")
> +            with open(debugfs_script_path, "w") as f:
> +                f.write("cd etc\n")
> +                f.write("rm fstab\n")
> +                f.write("write %s fstab\n" %
> (self.updated_fstab_path))
> +            debugfs_cmd = "debugfs -w -f %s %s" %
> (debugfs_script_path, rootfs)
> +            exec_native_cmd(debugfs_cmd, native_sysroot)
> +
>          mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs)
>          exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
>  
>          self.check_for_Y2038_problem(rootfs, native_sysroot)
>  
> -    def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir,
> +    def prepare_rootfs_btrfs(self, rootfs, cr_workdir, oe_builddir,
> rootfs_dir, native_sysroot, pseudo):
>          """
>          Prepare content for a btrfs rootfs partition.
> @@ -295,7 +323,7 @@ class Partition():
>               self.mkfs_extraopts, self.fsuuid, rootfs)
>          exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
>  
> -    def prepare_rootfs_msdos(self, rootfs, oe_builddir, rootfs_dir,
> +    def prepare_rootfs_msdos(self, rootfs, cr_workdir, oe_builddir,
> rootfs_dir, native_sysroot, pseudo):
>          """
>          Prepare content for a msdos/vfat rootfs partition.
> @@ -311,8 +339,6 @@ class Partition():
>              label_str = "-n %s" % self.label
>  
>          size_str = ""
> -        if self.fstype == 'msdos':
> -            size_str = "-F 16" # FAT 16
>  
>          extraopts = self.mkfs_extraopts or '-S 512'
>  
> @@ -324,12 +350,16 @@ class Partition():
>          mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir)
>          exec_native_cmd(mcopy_cmd, native_sysroot)
>  
> +        if self.updated_fstab_path and self.has_fstab:
> +            mcopy_cmd = "mcopy -i %s %s ::/etc/fstab" % (rootfs,
> self.updated_fstab_path)
> +            exec_native_cmd(mcopy_cmd, native_sysroot)
> +
>          chmod_cmd = "chmod 644 %s" % rootfs
>          exec_cmd(chmod_cmd)
>  
>      prepare_rootfs_vfat = prepare_rootfs_msdos
>  
> -    def prepare_rootfs_squashfs(self, rootfs, oe_builddir,
> rootfs_dir,
> +    def prepare_rootfs_squashfs(self, rootfs, cr_workdir,
> oe_builddir, rootfs_dir, native_sysroot, pseudo):
>          """
>          Prepare content for a squashfs rootfs partition.
> @@ -390,8 +420,6 @@ class Partition():
>              label_str = "-n %s" % self.label
>  
>          size_str = ""
> -        if self.fstype == 'msdos':
> -            size_str = "-F 16" # FAT 16
>  
>          extraopts = self.mkfs_extraopts or '-S 512'
>  
> @@ -432,26 +460,26 @@ class Partition():
>              if part.mountpoint:
>                  args = [part.fstype, "mounted at %s" %
> part.mountpoint] elif part.label:
> -                args = [part.fstype, "labeled %s" % part.label]
> +                args = [part.fstype, "labeled '%s'" % part.label]
>              elif part.part_name:
> -                args = [part.fstype, "in partition %s" %
> part.part_name]
> +                args = [part.fstype, "in partition '%s'" %
> part.part_name] else:
> -                args = [part.fstype, ""]
> +                args = [part.fstype, "in partition %s" % part.num]
>              return err.format(*args)
>  
> -        ret, out = exec_native_cmd("dumpe2fs %s" % rootfs,
> native_sysroot) -
>          # ext2 and ext3 are always affected by the Y2038 problem
>          if self.fstype in ["ext2", "ext3"]:
>              logger.warn(get_err_str(self))
>              return
>  
> +        ret, out = exec_native_cmd("dumpe2fs %s" % rootfs,
> native_sysroot) +
>          # if ext4 is affected by the Y2038 problem depends on the
> inode size
> -        # Remember: inode size depends on the file system size
>          for line in out.splitlines():
>              if line.startswith("Inode size:"):
>                  size = int(line.split(":")[1].strip())
>                  if size < 256:
> -                    logger.warn("%s Inodes (of size %d) are too
> small." % \
> +                    logger.warn("%s Inodes (of size %d) are too
> small." % (get_err_str(self), size))
> -                break
> \ No newline at end of file
> +                break
> +
> diff --git a/scripts/lib/wic/plugins/imager/direct.py
> b/scripts/lib/wic/plugins/imager/direct.py index 55db826..ea709e8
> 100644 --- a/scripts/lib/wic/plugins/imager/direct.py
> +++ b/scripts/lib/wic/plugins/imager/direct.py
> @@ -54,15 +54,16 @@ class DirectPlugin(ImagerPlugin):
>          self.native_sysroot = native_sysroot
>          self.oe_builddir = oe_builddir
>  
> +        self.debug = options.debug
>          self.outdir = options.outdir
>          self.compressor = options.compressor
>          self.bmap = options.bmap
>          self.no_fstab_update = options.no_fstab_update
> -        self.original_fstab = None
> +        self.updated_fstab_path = None
>  
>          self.name = "%s-%s" %
> (os.path.splitext(os.path.basename(wks_file))[0],
> strftime("%Y%m%d%H%M"))
> -        self.workdir = tempfile.mkdtemp(dir=self.outdir,
> prefix='tmp.wic.')
> +        self.workdir = self.setup_workdir(options.workdir)
>          self._image = None
>          self.ptable_format = self.ks.bootloader.ptable
>          self.parts = self.ks.partitions
> @@ -78,6 +79,16 @@ class DirectPlugin(ImagerPlugin):
>          self._image = PartitionedImage(image_path,
> self.ptable_format, self.parts, self.native_sysroot)
>  
> +    def setup_workdir(self, workdir):
> +        if workdir:
> +            if os.path.exists(workdir):
> +                raise WicError("Internal workdir '%s' specified in
> wic arguments already exists!" % (workdir)) +
> +            os.makedirs(workdir)
> +            return workdir
> +        else:
> +            return tempfile.mkdtemp(dir=self.outdir,
> prefix='tmp.wic.') +
>      def do_create(self):
>          """
>          Plugin entry point.
> @@ -90,11 +101,8 @@ class DirectPlugin(ImagerPlugin):
>          finally:
>              self.cleanup()
>  
> -    def _write_fstab(self, image_rootfs):
> -        """overriden to generate fstab (temporarily) in rootfs. This
> is called
> -        from _create, make sure it doesn't get called from
> -        BaseImage.create()
> -        """
> +    def update_fstab(self, image_rootfs):
> +        """Assume partition order same as in wks"""
>          if not image_rootfs:
>              return
>  
> @@ -104,18 +112,9 @@ class DirectPlugin(ImagerPlugin):
>  
>          with open(fstab_path) as fstab:
>              fstab_lines = fstab.readlines()
> -            self.original_fstab = fstab_lines.copy()
> -
> -        if self._update_fstab(fstab_lines, self.parts):
> -            with open(fstab_path, "w") as fstab:
> -                fstab.writelines(fstab_lines)
> -        else:
> -            self.original_fstab = None
>  
> -    def _update_fstab(self, fstab_lines, parts):
> -        """Assume partition order same as in wks"""
>          updated = False
> -        for part in parts:
> +        for part in self.parts:
>              if not part.realnum or not part.mountpoint \
>                 or part.mountpoint == "/":
>                  continue
> @@ -144,7 +143,10 @@ class DirectPlugin(ImagerPlugin):
>              fstab_lines.append(line)
>              updated = True
>  
> -        return updated
> +        if updated:
> +            self.updated_fstab_path = os.path.join(self.workdir,
> "fstab")
> +            with open(self.updated_fstab_path, "w") as f:
> +                f.writelines(fstab_lines)
>  
>      def _full_path(self, path, name, extention):
>          """ Construct full file path to a file we generate. """
> @@ -160,7 +162,7 @@ class DirectPlugin(ImagerPlugin):
>          a partitioned image.
>          """
>          if not self.no_fstab_update:
> -            self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
> +            self.update_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
>  
>          for part in self.parts:
>              # get rootfs size from bitbake variable if it's not set
> in .ks file @@ -273,14 +275,9 @@ class DirectPlugin(ImagerPlugin):
>              if os.path.isfile(path):
>                  shutil.move(path, os.path.join(self.outdir, fname))
>  
> -        #Restore original fstab
> -        if self.original_fstab:
> -            fstab_path = self.rootfs_dir.get("ROOTFS_DIR") +
> "/etc/fstab"
> -            with open(fstab_path, "w") as fstab:
> -                fstab.writelines(self.original_fstab)
> -
> -        # remove work directory
> -        shutil.rmtree(self.workdir, ignore_errors=True)
> +        # remove work directory when it is not in debugging mode
> +        if not self.debug:
> +            shutil.rmtree(self.workdir, ignore_errors=True)
>  
>  # Overhead of the MBR partitioning scheme (just one sector)
>  MBR_OVERHEAD = 1
> @@ -343,6 +340,13 @@ class PartitionedImage():
>                      part.fsuuid = '0x' +
> str(uuid.uuid4())[:8].upper() else:
>                      part.fsuuid = str(uuid.uuid4())
> +            else:
> +                #make sure the fsuuid for vfat/msdos align with
> format 0xYYYYYYYY
> +                if part.fstype == 'vfat' or part.fstype == 'msdos':
> +                    if part.fsuuid.upper().startswith("0X"):
> +                        part.fsuuid = '0x' +
> part.fsuuid.upper()[2:].rjust(8,"0")
> +                    else:
> +                        part.fsuuid = '0x' +
> part.fsuuid.upper().rjust(8,"0") 
>      def prepare(self, imager):
>          """Prepare an image. Call prepare method of all image
> partitions.""" @@ -351,7 +355,8 @@ class PartitionedImage():
>              # sizes before we can add them and do the layout.
>              part.prepare(imager, imager.workdir, imager.oe_builddir,
>                           imager.rootfs_dir, imager.bootimg_dir,
> -                         imager.kernel_dir, imager.native_sysroot)
> +                         imager.kernel_dir, imager.native_sysroot,
> +                         imager.updated_fstab_path)
>  
>              # Converting kB to sectors for parted
>              part.size_sec = part.disk_size * 1024 // self.sector_size
> diff --git a/scripts/lib/wic/plugins/source/bootimg-efi.py
> b/scripts/lib/wic/plugins/source/bootimg-efi.py index
> 14c1723..cdc7254 100644 ---
> a/scripts/lib/wic/plugins/source/bootimg-efi.py +++
> b/scripts/lib/wic/plugins/source/bootimg-efi.py @@ -212,8 +212,8 @@
> class BootimgEFIPlugin(SourcePlugin): except KeyError:
>              raise WicError("bootimg-efi requires a loader, none
> specified") 
> -        if get_bitbake_var("IMAGE_BOOT_FILES") is None:
> -            logger.debug('No boot files defined in IMAGE_BOOT_FILES')
> +        if get_bitbake_var("IMAGE_EFI_BOOT_FILES") is None:
> +            logger.debug('No boot files defined in
> IMAGE_EFI_BOOT_FILES') else:
>              boot_files = None
>              for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s",
> part.label), (None, None)): @@ -222,7 +222,7 @@ class
> BootimgEFIPlugin(SourcePlugin): else:
>                      var = ""
>  
> -                boot_files = get_bitbake_var("IMAGE_BOOT_FILES" +
> var)
> +                boot_files = get_bitbake_var("IMAGE_EFI_BOOT_FILES"
> + var) if boot_files:

Should we now use this variable? And put it on the variable list in
meta/classes/wic-img.bbclass? I guess doing the "forked plugin" will
tell.

Henning

>                      break
>  
> @@ -292,7 +292,7 @@ class BootimgEFIPlugin(SourcePlugin):
>              (staging_kernel_dir, kernel, hdddir, kernel)
>          exec_cmd(install_cmd)
>  
> -        if get_bitbake_var("IMAGE_BOOT_FILES"):
> +        if get_bitbake_var("IMAGE_EFI_BOOT_FILES"):
>              for src_path, dst_path in cls.install_task:
>                  install_cmd = "install -m 0644 -D %s %s" \
>                                % (os.path.join(kernel_dir, src_path),
> diff --git a/scripts/lib/wic/plugins/source/empty.py
> b/scripts/lib/wic/plugins/source/empty.py new file mode 100644
> index 0000000..041617d
> --- /dev/null
> +++ b/scripts/lib/wic/plugins/source/empty.py
> @@ -0,0 +1,32 @@
> +#
> +# SPDX-License-Identifier: MIT
> +#
> +
> +# The empty wic plugin is used to create unformatted empty
> partitions for wic +# images.
> +# To use it you must pass "empty" as argument for the "--source"
> parameter in +# the wks file. For example:
> +# part foo --source empty --ondisk sda --size="1024" --align 1024
> +
> +import logging
> +
> +from wic.pluginbase import SourcePlugin
> +
> +logger = logging.getLogger('wic')
> +
> +class EmptyPartitionPlugin(SourcePlugin):
> +    """
> +    Populate unformatted empty partition.
> +    """
> +
> +    name = 'empty'
> +
> +    @classmethod
> +    def do_prepare_partition(cls, part, source_params, cr,
> cr_workdir,
> +                             oe_builddir, bootimg_dir, kernel_dir,
> +                             rootfs_dir, native_sysroot):
> +        """
> +        Called to do the actual content population for a partition
> i.e. it
> +        'prepares' the partition to be incorporated into the image.
> +        """
> +        return
> diff --git a/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
> b/scripts/lib/wic/plugins/source/isoimage-isohybrid.py index
> 11326a2..afc9ea0 100644 ---
> a/scripts/lib/wic/plugins/source/isoimage-isohybrid.py +++
> b/scripts/lib/wic/plugins/source/isoimage-isohybrid.py @@ -216,6
> +216,18 @@ class IsoImagePlugin(SourcePlugin): creator.name =
> source_params['image_name'].strip() logger.debug("The name of the
> image is: %s", creator.name) 
> +    @staticmethod
> +    def _install_payload(source_params, iso_dir):
> +        """
> +        Copies contents of payload directory (as specified in
> 'payload_dir' param) into iso_dir
> +        """
> +
> +        if source_params.get('payload_dir'):
> +            payload_dir = source_params['payload_dir']
> +
> +            logger.debug("Payload directory: %s", payload_dir)
> +            shutil.copytree(payload_dir, iso_dir, symlinks=True,
> dirs_exist_ok=True) +
>      @classmethod
>      def do_prepare_partition(cls, part, source_params, creator,
> cr_workdir, oe_builddir, bootimg_dir, kernel_dir,
> @@ -228,6 +240,8 @@ class IsoImagePlugin(SourcePlugin):
>  
>          isodir = "%s/ISO" % cr_workdir
>  
> +        cls._install_payload(source_params, isodir)
> +
>          if part.rootfs_dir is None:
>              if not 'ROOTFS_DIR' in rootfs_dir:
>                  raise WicError("Couldn't find --rootfs-dir,
> exiting.") diff --git a/scripts/lib/wic/plugins/source/rootfs.py
> b/scripts/lib/wic/plugins/source/rootfs.py index f1db83f..96d940a
> 100644 --- a/scripts/lib/wic/plugins/source/rootfs.py
> +++ b/scripts/lib/wic/plugins/source/rootfs.py
> @@ -94,6 +94,7 @@ class RootfsPlugin(SourcePlugin):
>                                 "it is not a valid path, exiting" %
> part.rootfs_dir) 
>          part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
> +        part.has_fstab =
> os.path.exists(os.path.join(part.rootfs_dir, "etc/fstab")) pseudo_dir
> = os.path.join(part.rootfs_dir, "../pseudo") if not
> os.path.lexists(pseudo_dir): logger.warn("%s folder does not exist. "
> @@ -103,9 +104,9 @@ class RootfsPlugin(SourcePlugin):
>          new_rootfs = None
>          new_pseudo = None
>          # Handle excluded paths.
> -        if part.exclude_path or part.include_path or
> part.change_directory:
> -            # We need a new rootfs directory we can delete files
> from. Copy to
> -            # workdir.
> +        if part.exclude_path or part.include_path or
> part.change_directory or part.update_fstab_in_rootfs:
> +            # We need a new rootfs directory we can safely modify
> without
> +            # interfering with other tasks. Copy to workdir.
>              new_rootfs = os.path.realpath(os.path.join(cr_workdir,
> "rootfs%d" % part.lineno)) 
>              if os.path.lexists(new_rootfs):
> @@ -199,17 +200,33 @@ class RootfsPlugin(SourcePlugin):
>                  if not os.path.lexists(full_path):
>                      continue
>  
> +                if new_pseudo:
> +                    pseudo = cls.__get_pseudo(native_sysroot,
> new_rootfs, new_pseudo)
> +                else:
> +                    pseudo = None
>                  if path.endswith(os.sep):
>                      # Delete content only.
>                      for entry in os.listdir(full_path):
>                          full_entry = os.path.join(full_path, entry)
> -                        if os.path.isdir(full_entry) and not
> os.path.islink(full_entry):
> -                            shutil.rmtree(full_entry)
> -                        else:
> -                            os.remove(full_entry)
> +                        rm_cmd = "rm -rf %s" % (full_entry)
> +                        exec_native_cmd(rm_cmd, native_sysroot,
> pseudo) else:
>                      # Delete whole directory.
> -                    shutil.rmtree(full_path)
> +                    rm_cmd = "rm -rf %s" % (full_path)
> +                    exec_native_cmd(rm_cmd, native_sysroot, pseudo)
> +
> +            # Update part.has_fstab here as fstab may have been
> added or
> +            # removed by the above modifications.
> +            part.has_fstab = os.path.exists(os.path.join(new_rootfs,
> "etc/fstab"))
> +            if part.update_fstab_in_rootfs and part.has_fstab:
> +                fstab_path = os.path.join(new_rootfs, "etc/fstab")
> +                # Assume that fstab should always be owned by root
> with fixed permissions
> +                install_cmd = "install -m 0644 %s %s" %
> (part.updated_fstab_path, fstab_path)
> +                if new_pseudo:
> +                    pseudo = cls.__get_pseudo(native_sysroot,
> new_rootfs, new_pseudo)
> +                else:
> +                    pseudo = None
> +                exec_native_cmd(install_cmd, native_sysroot, pseudo)
>  
>          part.prepare_rootfs(cr_workdir, oe_builddir,
>                              new_rootfs or part.rootfs_dir,
> native_sysroot, diff --git a/scripts/wic b/scripts/wic
> index 24700f3..a741aed 100755
> --- a/scripts/wic
> +++ b/scripts/wic
> @@ -312,6 +312,8 @@ def wic_init_parser_create(subparser):
>  
>      subparser.add_argument("-o", "--outdir", dest="outdir",
> default='.', help="name of directory to create image in")
> +    subparser.add_argument("-w", "--workdir",
> +                      help="temporary workdir to use for
> intermediate files") subparser.add_argument("-e", "--image-name",
> dest="image_name", help="name of the image to use the artifacts from "
>                             "e.g. core-image-sato")


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-06-08  7:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-02  8:37 [PATCH] wic: Update to the latest revision Anton Mikanovich
2021-06-02  9:00 ` Jan Kiszka
2021-06-02  9:08   ` Anton Mikanovich
2021-06-08  7:40 ` Henning Schild
2021-06-08  7:45 ` Henning Schild

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox