[PATCH 0/5] Add iso9660 image support for ISAR

36 views
Skip to first unread message

Felix Moessbauer

unread,
Jan 21, 2025, 5:13:01 AM1/21/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
This series adds support to create hybrid iso9660 images for ISAR
which can be used as live images for booting from USB sticks or
DVDs. Currently, only syslinux and EFI (grub) bootloaders are supported.

Best regards,
Felix Moessbauer

Felix Moessbauer (5):
Import isoimage-isohybrid from oe
wic: add ISAR version of isohybrid-efi plugin
move squashfs imagetype class from CIP to ISAR
add qemuamd64 target for hybrid iso9660 image
add kas menu target for qemuamd64-iso machine

kas/machine/Kconfig | 14 +
kas/machine/qemuamd64-iso.yaml | 7 +
meta-isar/classes/squashfs.bbclass | 48 ++
meta-isar/conf/machine/qemuamd64-iso.conf | 29 +
.../multiconfig/qemuamd64-iso-bookworm.conf | 4 +
.../lib/wic/canned-wks/isohybrid-efi.wks.in | 2 +
meta/classes/image.bbclass | 2 +-
.../plugins/source/isoimage-isohybrid-isar.py | 535 ++++++++++++++++++
8 files changed, 640 insertions(+), 1 deletion(-)
create mode 100644 kas/machine/qemuamd64-iso.yaml
create mode 100644 meta-isar/classes/squashfs.bbclass
create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
create mode 100644 meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py

--
2.39.5

Felix Moessbauer

unread,
Jan 21, 2025, 5:13:02 AM1/21/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
This adds support to generate a hybrid grub-efi + syslinux ISO9660
image. The patch is written in an add-only style to simplify updates of
the upstream plugin.

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
.../plugins/source/isoimage-isohybrid-isar.py | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)

diff --git a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
index afc9ea0f..b46527b8 100644
--- a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
+++ b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
@@ -18,6 +18,12 @@ from wic.engine import get_custom_config
from wic.pluginbase import SourcePlugin
from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var

+# allow plugins to import from isarpluginbase
+if '__file__' in globals():
+ import sys
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/..")
+from isarpluginbase import (isar_get_filenames, isar_populate_boot_cmd)
+
logger = logging.getLogger('wic')

class IsoImagePlugin(SourcePlugin):
@@ -44,6 +50,7 @@ class IsoImagePlugin(SourcePlugin):
"""

name = 'isoimage-isohybrid'
+ name = 'isoimage-isohybrid-isar'

@classmethod
def do_configure_syslinux(cls, creator, cr_workdir):
@@ -71,6 +78,9 @@ class IsoImagePlugin(SourcePlugin):
syslinux_conf += "LABEL boot\n"

kernel = get_bitbake_var("KERNEL_IMAGETYPE")
+ kernel, initrd = isar_get_filenames(
+ get_bitbake_var("IMAGE_ROOTFS"), get_bitbake_var("KERNEL_FILE")
+ )
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
if get_bitbake_var("INITRAMFS_IMAGE"):
kernel = "%s-%s.bin" % \
@@ -80,6 +90,13 @@ class IsoImagePlugin(SourcePlugin):
syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
% bootloader.append

+ # replace initrd with correct one
+ if initrd:
+ syslinux_conf = syslinux_conf.replace(
+ "initrd=/initrd", "initrd=/%s" % initrd)
+ else:
+ raise WicError("Couldn't find initrd, exiting.")
+
logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
cr_workdir)

@@ -125,9 +142,23 @@ class IsoImagePlugin(SourcePlugin):
kernel = "%s-%s.bin" % \
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))

+ kernel, initrd = isar_get_filenames(
+ get_bitbake_var("IMAGE_ROOTFS"), get_bitbake_var("KERNEL_FILE")
+ )
+
+ bootloader.append = bootloader.append or ""
grubefi_conf += "linux /%s rootwait %s\n" \
% (kernel, bootloader.append)
grubefi_conf += "initrd /initrd \n"
+ grubefi_conf = '\n'.join(grubefi_conf.splitlines()[:-1]) + '\n'
+
+ if initrd:
+ initrds = initrd.split(';')
+ grubefi_conf += "initrd"
+ for rd in initrds:
+ grubefi_conf += " /%s" % rd
+ grubefi_conf += "\n"
+
grubefi_conf += "}\n"

if splashline:
@@ -156,12 +187,14 @@ class IsoImagePlugin(SourcePlugin):
raise WicError("Couldn't find IMAGE_BASENAME, exiting.")

image_type = get_bitbake_var("INITRAMFS_FSTYPES")
+ image_type = image_type or "img"
if not image_type:
raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")

machine = os.path.basename(initrd_dir)

pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
+ pattern = '%s/%s-%s-initrd.%s' % (initrd_dir, image_name, machine, image_type)
files = glob.glob(pattern)
if files:
initrd = files[0]
@@ -227,6 +260,12 @@ class IsoImagePlugin(SourcePlugin):

logger.debug("Payload directory: %s", payload_dir)
shutil.copytree(payload_dir, iso_dir, symlinks=True, dirs_exist_ok=True)
+ if source_params.get('payload'):
+ payload = source_params.get('payload')
+
+ logger.debug("Payload: %s", payload)
+ os.mkdir('%s/live' % iso_dir)
+ shutil.copy(payload, '%s/live' % iso_dir)

@classmethod
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
@@ -299,6 +338,7 @@ class IsoImagePlugin(SourcePlugin):

install_cmd = "install -m 0644 %s/%s %s/%s" % \
(kernel_dir, kernel, isodir, kernel)
+ install_cmd = isar_populate_boot_cmd(rootfs_dir, isodir)
exec_cmd(install_cmd)

#Create bootloader for efi boot
@@ -313,19 +353,46 @@ class IsoImagePlugin(SourcePlugin):
# Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
# didn't contains it
target_arch = get_bitbake_var("TARGET_SYS")
+ distro_arch = get_bitbake_var("DISTRO_ARCH")
+ if distro_arch == "amd64":
+ target_arch = "x86_64"
+ else:
+ target_arch = distro_arch
+
if not target_arch:
raise WicError("Coludn't find target architecture")

if re.match("x86_64", target_arch):
+ grub_target = "x86_64-efi"
grub_src_image = "grub-efi-bootx64.efi"
grub_dest_image = "bootx64.efi"
+ grub_modules = "multiboot efi_uga iorw ata "
+ if get_bitbake_var("DISTRO").startswith("ubuntu") and \
+ os.path.exists('/usr/lib/grub/x86_64-efi/linuxefi.mod'):
+ grub_modules += "linuxefi "
elif re.match('i.86', target_arch):
+ grub_target = "i386-efi"
grub_src_image = "grub-efi-bootia32.efi"
grub_dest_image = "bootia32.efi"
+ grub_modules = "multiboot efi_uga iorw ata "
else:
raise WicError("grub-efi is incompatible with target %s" %
target_arch)

+ if not os.path.isfile("%s/%s" \
+ % (target_dir, grub_dest_image)):
+ grub_cmd = "grub-mkimage -p /EFI/BOOT "
+ grub_cmd += "-O %s -o %s/%s " \
+ % (grub_target, target_dir, grub_dest_image)
+ grub_cmd += "part_gpt part_msdos ntfs ntfscomp fat ext2 "
+ grub_cmd += "normal chain boot configfile linux "
+ grub_cmd += "search efi_gop font gfxterm gfxmenu "
+ grub_cmd += "terminal minicmd test loadenv echo help "
+ grub_cmd += "reboot serial terminfo iso9660 loopback tar "
+ grub_cmd += "memdisk ls search_fs_uuid udf btrfs xfs lvm "
+ grub_cmd += "reiserfs regexp " + grub_modules
+ exec_cmd(grub_cmd)
+
grub_target = os.path.join(target_dir, grub_dest_image)
if not os.path.isfile(grub_target):
grub_src = os.path.join(deploy_dir, grub_src_image)
@@ -393,18 +460,23 @@ class IsoImagePlugin(SourcePlugin):
cls.do_configure_syslinux(creator, cr_workdir)

install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
+ # different name in Debian
+ install_cmd = "install -m 444 %s/syslinux/modules/bios/ldlinux.c32 " % syslinux_dir
install_cmd += "%s/isolinux/ldlinux.sys" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/ISOLINUX/')
install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/ISOLINUX/')
install_cmd += "%s/isolinux/isolinux.bin" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/syslinux/modules/bios/')
install_cmd += "%s/isolinux/ldlinux.c32" % isodir
exec_cmd(install_cmd)

@@ -415,6 +487,8 @@ class IsoImagePlugin(SourcePlugin):
efi_img = "efi.img"

mkisofs_cmd = "mkisofs -V %s " % part.label
+ # use xorriso from Debian
+ mkisofs_cmd = "xorriso -as mkisofs -V %s " % part.label
mkisofs_cmd += "-o %s -U " % iso_img
mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
--
2.39.5

Felix Moessbauer

unread,
Jan 21, 2025, 5:13:02 AM1/21/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
OE-core Revision: b85a09ea450a5e8f49418f4a930805fbb88dc83b

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
.../plugins/source/isoimage-isohybrid-isar.py | 461 ++++++++++++++++++
1 file changed, 461 insertions(+)
create mode 100644 meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py

diff --git a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
new file mode 100644
index 00000000..afc9ea0f
--- /dev/null
+++ b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
@@ -0,0 +1,461 @@
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# DESCRIPTION
+# This implements the 'isoimage-isohybrid' source plugin class for 'wic'
+#
+# AUTHORS
+# Mihaly Varga <mihaly.varga (at] ni.com>
+
+import glob
+import logging
+import os
+import re
+import shutil
+
+from wic import WicError
+from wic.engine import get_custom_config
+from wic.pluginbase import SourcePlugin
+from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var
+
+logger = logging.getLogger('wic')
+
+class IsoImagePlugin(SourcePlugin):
+ """
+ Create a bootable ISO image
+
+ This plugin creates a hybrid, legacy and EFI bootable ISO image. The
+ generated image can be used on optical media as well as USB media.
+
+ Legacy boot uses syslinux and EFI boot uses grub or gummiboot (not
+ implemented yet) as bootloader. The plugin creates the directories required
+ by bootloaders and populates them by creating and configuring the
+ bootloader files.
+
+ Example kickstart file:
+ part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\
+ image_name= IsoImage" --ondisk cd --label LIVECD
+ bootloader --timeout=10 --append=" "
+
+ In --sourceparams "loader" specifies the bootloader used for booting in EFI
+ mode, while "image_name" specifies the name of the generated image. In the
+ example above, wic creates an ISO image named IsoImage-cd.direct (default
+ extension added by direct imeger plugin) and a file named IsoImage-cd.iso
+ """
+
+ name = 'isoimage-isohybrid'
+
+ @classmethod
+ def do_configure_syslinux(cls, creator, cr_workdir):
+ """
+ Create loader-specific (syslinux) config
+ """
+ splash = os.path.join(cr_workdir, "ISO/boot/splash.jpg")
+ if os.path.exists(splash):
+ splashline = "menu background splash.jpg"
+ else:
+ splashline = ""
+
+ bootloader = creator.ks.bootloader
+
+ syslinux_conf = ""
+ syslinux_conf += "PROMPT 0\n"
+ syslinux_conf += "TIMEOUT %s \n" % (bootloader.timeout or 10)
+ syslinux_conf += "\n"
+ syslinux_conf += "ALLOWOPTIONS 1\n"
+ syslinux_conf += "SERIAL 0 115200\n"
+ syslinux_conf += "\n"
+ if splashline:
+ syslinux_conf += "%s\n" % splashline
+ syslinux_conf += "DEFAULT boot\n"
+ syslinux_conf += "LABEL boot\n"
+
+ kernel = get_bitbake_var("KERNEL_IMAGETYPE")
+ if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
+ if get_bitbake_var("INITRAMFS_IMAGE"):
+ kernel = "%s-%s.bin" % \
+ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
+
+ syslinux_conf += "KERNEL /" + kernel + "\n"
+ syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
+ % bootloader.append
+
+ logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
+ cr_workdir)
+
+ with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg:
+ cfg.write(syslinux_conf)
+
+ @classmethod
+ def do_configure_grubefi(cls, part, creator, target_dir):
+ """
+ Create loader-specific (grub-efi) config
+ """
+ configfile = creator.ks.bootloader.configfile
+ if configfile:
+ grubefi_conf = get_custom_config(configfile)
+ if grubefi_conf:
+ logger.debug("Using custom configuration file %s for grub.cfg",
+ configfile)
+ else:
+ raise WicError("configfile is specified "
+ "but failed to get it from %s", configfile)
+ else:
+ splash = os.path.join(target_dir, "splash.jpg")
+ if os.path.exists(splash):
+ splashline = "menu background splash.jpg"
+ else:
+ splashline = ""
+
+ bootloader = creator.ks.bootloader
+
+ grubefi_conf = ""
+ grubefi_conf += "serial --unit=0 --speed=115200 --word=8 "
+ grubefi_conf += "--parity=no --stop=1\n"
+ grubefi_conf += "default=boot\n"
+ grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10)
+ grubefi_conf += "\n"
+ grubefi_conf += "search --set=root --label %s " % part.label
+ grubefi_conf += "\n"
+ grubefi_conf += "menuentry 'boot'{\n"
+
+ kernel = get_bitbake_var("KERNEL_IMAGETYPE")
+ if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
+ if get_bitbake_var("INITRAMFS_IMAGE"):
+ kernel = "%s-%s.bin" % \
+ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
+
+ grubefi_conf += "linux /%s rootwait %s\n" \
+ % (kernel, bootloader.append)
+ grubefi_conf += "initrd /initrd \n"
+ grubefi_conf += "}\n"
+
+ if splashline:
+ grubefi_conf += "%s\n" % splashline
+
+ cfg_path = os.path.join(target_dir, "grub.cfg")
+ logger.debug("Writing grubefi config %s", cfg_path)
+
+ with open(cfg_path, "w") as cfg:
+ cfg.write(grubefi_conf)
+
+ @staticmethod
+ def _build_initramfs_path(rootfs_dir, cr_workdir):
+ """
+ Create path for initramfs image
+ """
+
+ initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD")
+ if not initrd:
+ initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+ if not initrd_dir:
+ raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.")
+
+ image_name = get_bitbake_var("IMAGE_BASENAME")
+ if not image_name:
+ raise WicError("Couldn't find IMAGE_BASENAME, exiting.")
+
+ image_type = get_bitbake_var("INITRAMFS_FSTYPES")
+ if not image_type:
+ raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")
+
+ machine = os.path.basename(initrd_dir)
+
+ pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
+ files = glob.glob(pattern)
+ if files:
+ initrd = files[0]
+
+ if not initrd or not os.path.exists(initrd):
+ # Create initrd from rootfs directory
+ initrd = "%s/initrd.cpio.gz" % cr_workdir
+ initrd_dir = "%s/INITRD" % cr_workdir
+ shutil.copytree("%s" % rootfs_dir, \
+ "%s" % initrd_dir, symlinks=True)
+
+ if os.path.isfile("%s/init" % rootfs_dir):
+ shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir)
+ elif os.path.lexists("%s/init" % rootfs_dir):
+ os.symlink(os.readlink("%s/init" % rootfs_dir), \
+ "%s/init" % initrd_dir)
+ elif os.path.isfile("%s/sbin/init" % rootfs_dir):
+ shutil.copy2("%s/sbin/init" % rootfs_dir, \
+ "%s" % initrd_dir)
+ elif os.path.lexists("%s/sbin/init" % rootfs_dir):
+ os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \
+ "%s/init" % initrd_dir)
+ else:
+ raise WicError("Couldn't find or build initrd, exiting.")
+
+ exec_cmd("cd %s && find . | cpio -o -H newc -R root:root >%s/initrd.cpio " \
+ % (initrd_dir, cr_workdir), as_shell=True)
+ exec_cmd("gzip -f -9 %s/initrd.cpio" % cr_workdir, as_shell=True)
+ shutil.rmtree(initrd_dir)
+
+ return initrd
+
+ @classmethod
+ def do_configure_partition(cls, part, source_params, creator, cr_workdir,
+ oe_builddir, bootimg_dir, kernel_dir,
+ native_sysroot):
+ """
+ Called before do_prepare_partition(), creates loader-specific config
+ """
+ isodir = "%s/ISO/" % cr_workdir
+
+ if os.path.exists(isodir):
+ shutil.rmtree(isodir)
+
+ install_cmd = "install -d %s " % isodir
+ exec_cmd(install_cmd)
+
+ # Overwrite the name of the created image
+ logger.debug(source_params)
+ if 'image_name' in source_params and \
+ source_params['image_name'].strip():
+ creator.name = source_params['image_name'].strip()
+ logger.debug("The name of the image is: %s", creator.name)
+
+ @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,
+ rootfs_dir, native_sysroot):
+ """
+ Called to do the actual content population for a partition i.e. it
+ 'prepares' the partition to be incorporated into the image.
+ In this case, prepare content for a bootable ISO image.
+ """
+
+ isodir = "%s/ISO" % cr_workdir
+
+ 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.")
+ rootfs_dir = rootfs_dir['ROOTFS_DIR']
+ else:
+ if part.rootfs_dir in rootfs_dir:
+ rootfs_dir = rootfs_dir[part.rootfs_dir]
+ elif part.rootfs_dir:
+ rootfs_dir = part.rootfs_dir
+ else:
+ raise WicError("Couldn't find --rootfs-dir=%s connection "
+ "or it is not a valid path, exiting." %
+ part.rootfs_dir)
+
+ if not os.path.isdir(rootfs_dir):
+ rootfs_dir = get_bitbake_var("IMAGE_ROOTFS")
+ if not os.path.isdir(rootfs_dir):
+ raise WicError("Couldn't find IMAGE_ROOTFS, exiting.")
+
+ part.rootfs_dir = rootfs_dir
+ deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+ img_iso_dir = get_bitbake_var("ISODIR")
+
+ # Remove the temporary file created by part.prepare_rootfs()
+ if os.path.isfile(part.source_file):
+ os.remove(part.source_file)
+
+ # Support using a different initrd other than default
+ if source_params.get('initrd'):
+ initrd = source_params['initrd']
+ if not deploy_dir:
+ raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+ cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir)
+ exec_cmd(cp_cmd)
+ else:
+ # Prepare initial ramdisk
+ initrd = "%s/initrd" % deploy_dir
+ if not os.path.isfile(initrd):
+ initrd = "%s/initrd" % img_iso_dir
+ if not os.path.isfile(initrd):
+ initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir)
+
+ install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir)
+ exec_cmd(install_cmd)
+
+ # Remove the temporary file created by _build_initramfs_path function
+ if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir):
+ os.remove("%s/initrd.cpio.gz" % cr_workdir)
+
+ kernel = get_bitbake_var("KERNEL_IMAGETYPE")
+ if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
+ if get_bitbake_var("INITRAMFS_IMAGE"):
+ kernel = "%s-%s.bin" % \
+ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
+
+ install_cmd = "install -m 0644 %s/%s %s/%s" % \
+ (kernel_dir, kernel, isodir, kernel)
+ exec_cmd(install_cmd)
+
+ #Create bootloader for efi boot
+ try:
+ target_dir = "%s/EFI/BOOT" % isodir
+ if os.path.exists(target_dir):
+ shutil.rmtree(target_dir)
+
+ os.makedirs(target_dir)
+
+ if source_params['loader'] == 'grub-efi':
+ # Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
+ # didn't contains it
+ target_arch = get_bitbake_var("TARGET_SYS")
+ if not target_arch:
+ raise WicError("Coludn't find target architecture")
+
+ if re.match("x86_64", target_arch):
+ grub_src_image = "grub-efi-bootx64.efi"
+ grub_dest_image = "bootx64.efi"
+ elif re.match('i.86', target_arch):
+ grub_src_image = "grub-efi-bootia32.efi"
+ grub_dest_image = "bootia32.efi"
+ else:
+ raise WicError("grub-efi is incompatible with target %s" %
+ target_arch)
+
+ grub_target = os.path.join(target_dir, grub_dest_image)
+ if not os.path.isfile(grub_target):
+ grub_src = os.path.join(deploy_dir, grub_src_image)
+ if not os.path.exists(grub_src):
+ raise WicError("Grub loader %s is not found in %s. "
+ "Please build grub-efi first" % (grub_src_image, deploy_dir))
+ shutil.copy(grub_src, grub_target)
+
+ if not os.path.isfile(os.path.join(target_dir, "boot.cfg")):
+ cls.do_configure_grubefi(part, creator, target_dir)
+
+ else:
+ raise WicError("unrecognized bootimg-efi loader: %s" %
+ source_params['loader'])
+ except KeyError:
+ raise WicError("bootimg-efi requires a loader, none specified")
+
+ # Create efi.img that contains bootloader files for EFI booting
+ # if ISODIR didn't exist or didn't contains it
+ if os.path.isfile("%s/efi.img" % img_iso_dir):
+ install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \
+ (img_iso_dir, isodir)
+ exec_cmd(install_cmd)
+ else:
+ # Default to 100 blocks of extra space for file system overhead
+ esp_extra_blocks = int(source_params.get('esp_extra_blocks', '100'))
+
+ du_cmd = "du -bks %s/EFI" % isodir
+ out = exec_cmd(du_cmd)
+ blocks = int(out.split()[0])
+ blocks += esp_extra_blocks
+ logger.debug("Added 100 extra blocks to %s to get to %d "
+ "total blocks", part.mountpoint, blocks)
+
+ # dosfs image for EFI boot
+ bootimg = "%s/efi.img" % isodir
+
+ esp_label = source_params.get('esp_label', 'EFIimg')
+
+ dosfs_cmd = 'mkfs.vfat -n \'%s\' -S 512 -C %s %d' \
+ % (esp_label, bootimg, blocks)
+ exec_native_cmd(dosfs_cmd, native_sysroot)
+
+ mmd_cmd = "mmd -i %s ::/EFI" % bootimg
+ exec_native_cmd(mmd_cmd, native_sysroot)
+
+ mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \
+ % (bootimg, isodir)
+ exec_native_cmd(mcopy_cmd, native_sysroot)
+
+ chmod_cmd = "chmod 644 %s" % bootimg
+ exec_cmd(chmod_cmd)
+
+ # Prepare files for legacy boot
+ syslinux_dir = get_bitbake_var("STAGING_DATADIR")
+ if not syslinux_dir:
+ raise WicError("Couldn't find STAGING_DATADIR, exiting.")
+
+ if os.path.exists("%s/isolinux" % isodir):
+ shutil.rmtree("%s/isolinux" % isodir)
+
+ install_cmd = "install -d %s/isolinux" % isodir
+ exec_cmd(install_cmd)
+
+ cls.do_configure_syslinux(creator, cr_workdir)
+
+ install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
+ install_cmd += "%s/isolinux/ldlinux.sys" % isodir
+ exec_cmd(install_cmd)
+
+ install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
+ install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
+ exec_cmd(install_cmd)
+
+ install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
+ install_cmd += "%s/isolinux/isolinux.bin" % isodir
+ exec_cmd(install_cmd)
+
+ install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
+ install_cmd += "%s/isolinux/ldlinux.c32" % isodir
+ exec_cmd(install_cmd)
+
+ #create ISO image
+ iso_img = "%s/tempiso_img.iso" % cr_workdir
+ iso_bootimg = "isolinux/isolinux.bin"
+ iso_bootcat = "isolinux/boot.cat"
+ efi_img = "efi.img"
+
+ mkisofs_cmd = "mkisofs -V %s " % part.label
+ mkisofs_cmd += "-o %s -U " % iso_img
+ mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
+ mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
+ mkisofs_cmd += "-boot-info-table -eltorito-alt-boot "
+ mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img
+ mkisofs_cmd += "-no-emul-boot %s " % isodir
+
+ logger.debug("running command: %s", mkisofs_cmd)
+ exec_native_cmd(mkisofs_cmd, native_sysroot)
+
+ shutil.rmtree(isodir)
+
+ du_cmd = "du -Lbks %s" % iso_img
+ out = exec_cmd(du_cmd)
+ isoimg_size = int(out.split()[0])
+
+ part.size = isoimg_size
+ part.source_file = iso_img
+
+ @classmethod
+ def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
+ bootimg_dir, kernel_dir, native_sysroot):
+ """
+ Called after all partitions have been prepared and assembled into a
+ disk image. In this case, we insert/modify the MBR using isohybrid
+ utility for booting via BIOS from disk storage devices.
+ """
+
+ iso_img = "%s.p1" % disk.path
+ full_path = creator._full_path(workdir, disk_name, "direct")
+ full_path_iso = creator._full_path(workdir, disk_name, "iso")
+
+ isohybrid_cmd = "isohybrid -u %s" % iso_img
+ logger.debug("running command: %s", isohybrid_cmd)
+ exec_native_cmd(isohybrid_cmd, native_sysroot)
+
+ # Replace the image created by direct plugin with the one created by
+ # mkisofs command. This is necessary because the iso image created by
+ # mkisofs has a very specific MBR is system area of the ISO image, and
+ # direct plugin adds and configures an another MBR.
+ logger.debug("Replaceing the image created by direct plugin\n")
+ os.remove(disk.path)
+ shutil.copy2(iso_img, full_path_iso)
+ shutil.copy2(full_path_iso, full_path)
--
2.39.5

Felix Moessbauer

unread,
Jan 21, 2025, 5:13:06 AM1/21/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
As a preparation for live images, we move the squashfs class from
isar-cip-core to ISAR and register it as always included.

ISAR-cip-core revision: 0e85378341fb7b37cf95b1c910ca0260cf4f5cf4

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
meta-isar/classes/squashfs.bbclass | 47 ++++++++++++++++++++++++++++++
meta/classes/image.bbclass | 2 +-
2 files changed, 48 insertions(+), 1 deletion(-)
create mode 100644 meta-isar/classes/squashfs.bbclass

diff --git a/meta-isar/classes/squashfs.bbclass b/meta-isar/classes/squashfs.bbclass
new file mode 100644
index 00000000..9cd7ed3d
--- /dev/null
+++ b/meta-isar/classes/squashfs.bbclass
@@ -0,0 +1,47 @@
+# squashfs image rootfs
+#
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2021-2025
+#
+# SPDX-License-Identifier: MIT
+
+def get_free_mem():
+ try:
+ with open('/proc/meminfo') as meminfo:
+ lines = meminfo.readlines()
+ for line in lines:
+ if line.startswith('MemAvailable:'):
+ return int(line.split()[1]) * 1024
+ except FileNotFoundError:
+ pass
+ return 4*1024*1024*1024 # 4G
+
+IMAGER_INSTALL:squashfs += "squashfs-tools"
+
+SQUASHFS_EXCLUDE_DIRS ?= ""
+SQUASHFS_CONTENT ?= "${PP_ROOTFS}"
+SQUASHFS_CREATION_ARGS ?= ""
+
+SQUASHFS_THREADS ?= "${@oe.utils.cpu_count(at_least=2)}"
+SQUASHFS_MEMLIMIT ?= "${@int(get_free_mem() * 3/4)}"
+SQUASHFS_CREATION_LIMITS = "-mem ${SQUASHFS_MEMLIMIT} -processors ${SQUASHFS_THREADS}"
+
+python __anonymous() {
+ exclude_directories = d.getVar('SQUASHFS_EXCLUDE_DIRS').split()
+ if len(exclude_directories) == 0:
+ return
+ # Use wildcard to exclude only content of the directory.
+ # This allows to use the directory as a mount point.
+ args = " -wildcards"
+ for dir in exclude_directories:
+ args += " -e '{dir}/*' ".format(dir=dir)
+ d.appendVar('SQUASHFS_CREATION_ARGS', args)
+}
+
+IMAGE_CMD:squashfs[depends] = "${PN}:do_transform_template"
+IMAGE_CMD:squashfs[vardepsexclude] += "SQUASHFS_CREATION_LIMITS"
+IMAGE_CMD:squashfs() {
+ ${SUDO_CHROOT} /bin/mksquashfs \
+ '${SQUASHFS_CONTENT}' '${IMAGE_FILE_CHROOT}' \
+ -noappend ${SQUASHFS_CREATION_LIMITS} ${SQUASHFS_CREATION_ARGS}
+}
diff --git a/meta/classes/image.bbclass b/meta/classes/image.bbclass
index db21cc76..49861b75 100644
--- a/meta/classes/image.bbclass
+++ b/meta/classes/image.bbclass
@@ -129,7 +129,7 @@ IMAGE_BASETYPES = "${@get_image_basetypes(d)}"

# image types
IMAGE_CLASSES ??= ""
-IMGCLASSES = "imagetypes imagetypes_wic imagetypes_vm imagetypes_container"
+IMGCLASSES = "imagetypes imagetypes_wic imagetypes_vm imagetypes_container squashfs"
IMGCLASSES += "${IMAGE_CLASSES}"
inherit ${IMGCLASSES}

--
2.39.5

Felix Moessbauer

unread,
Jan 21, 2025, 5:13:07 AM1/21/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
meta-isar/conf/machine/qemuamd64-iso.conf | 29 +++++++++++++++++++
.../multiconfig/qemuamd64-iso-bookworm.conf | 4 +++
.../lib/wic/canned-wks/isohybrid-efi.wks.in | 2 ++
3 files changed, 35 insertions(+)
create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in

diff --git a/meta-isar/conf/machine/qemuamd64-iso.conf b/meta-isar/conf/machine/qemuamd64-iso.conf
new file mode 100644
index 00000000..36cbdf54
--- /dev/null
+++ b/meta-isar/conf/machine/qemuamd64-iso.conf
@@ -0,0 +1,29 @@
+# This software is a part of ISAR.
+# Copyright (C) 2025 Siemens AG
+
+DISTRO_ARCH ?= "amd64"
+
+KERNEL_NAME ?= "amd64"
+
+IMAGE_FSTYPES ?= "wic"
+WKS_FILE ?= "isohybrid-efi.wks.in"
+IMAGER_INSTALL:wic += " \
+ ${GRUB_BOOTLOADER_INSTALL} \
+ ${SYSLINUX_BOOTLOADER_INSTALL} \
+ syslinux-utils \
+ isolinux \
+ xorriso \
+"
+
+IMAGE_PREINSTALL += "live-boot"
+IMAGE_INSTALL:remove = "expand-on-first-boot"
+IMAGE_TYPEDEP:wic += "squashfs"
+SQUASHFS_EXCLUDE_DIRS = "boot"
+
+QEMU_ARCH ?= "x86_64"
+QEMU_MACHINE ?= "q35"
+QEMU_CPU ?= ""
+QEMU_DISK_ARGS ?= "-cdrom ##ROOTFS_IMAGE## -bios /usr/share/ovmf/OVMF.fd"
+
+MACHINE_SERIAL ?= "ttyS0"
+BAUDRATE_TTY ?= "115200"
diff --git a/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf b/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
new file mode 100644
index 00000000..b5cf9c27
--- /dev/null
+++ b/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
@@ -0,0 +1,4 @@
+# This software is a part of ISAR.
+
+MACHINE ?= "qemuamd64-efi-iso"
+DISTRO ?= "debian-bookworm"
diff --git a/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
new file mode 100644
index 00000000..514f756c
--- /dev/null
+++ b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
@@ -0,0 +1,2 @@
+part /boot --source isoimage-isohybrid-isar --sourceparams="loader=grub-efi,payload=${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.squashfs" --ondisk cd --label LIVECD
+bootloader --timeout=10 --append "console=ttyS0,115200 console=tty0 boot=live toram=${IMAGE_FULLNAME}.squashfs"
--
2.39.5

Felix Moessbauer

unread,
Jan 21, 2025, 5:13:07 AM1/21/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
The iso support has been tested with the following distributions:

- Debian: buster, bullseye, bookworm, trixie
- Ubuntu: Focal, Jammy, Noble

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
kas/machine/Kconfig | 14 ++++++++++++++
kas/machine/qemuamd64-iso.yaml | 7 +++++++
2 files changed, 21 insertions(+)
create mode 100644 kas/machine/qemuamd64-iso.yaml

diff --git a/kas/machine/Kconfig b/kas/machine/Kconfig
index 1740bd56..c37a1465 100644
--- a/kas/machine/Kconfig
+++ b/kas/machine/Kconfig
@@ -107,6 +107,19 @@ config MACHINE_QEMU_AMD64_SB
select CODENAME_BULLSEYE
select ARCH_AMD64

+config MACHINE_QEMU_AMD64_ISO
+ bool "qemuamd64-iso"
+ select DISTRO_DEBIAN
+ select CODENAME_BUSTER
+ select CODENAME_BULLSEYE
+ select CODENAME_BOOKWORM
+ select CODENAME_TRIXIE
+ select DISTRO_UBUNTU
+ select CODENAME_FOCAL
+ select CODENAME_JAMMY
+ select CODENAME_NOBLE
+ select ARCH_AMD64
+
config MACHINE_QEMU_AMD64
bool "qemuamd64"
select DISTRO_DEBIAN
@@ -252,6 +265,7 @@ config KAS_INCLUDE_MACHINE
default "kas/machine/phyboard-mira.yaml" if MACHINE_PHYBOARD_MIRA
default "kas/machine/qemuamd64-cip.yaml" if MACHINE_QEMU_AMD64_CIP
default "kas/machine/qemuamd64-sb.yaml" if MACHINE_QEMU_AMD64_SB
+ default "kas/machine/qemuamd64-iso.yaml" if MACHINE_QEMU_AMD64_ISO
default "kas/machine/qemuamd64.yaml" if MACHINE_QEMU_AMD64
default "kas/machine/qemuarm.yaml" if MACHINE_QEMU_ARM
default "kas/machine/qemuarm64.yaml" if MACHINE_QEMU_ARM64
diff --git a/kas/machine/qemuamd64-iso.yaml b/kas/machine/qemuamd64-iso.yaml
new file mode 100644
index 00000000..f58a1217
--- /dev/null
+++ b/kas/machine/qemuamd64-iso.yaml
@@ -0,0 +1,7 @@
+# This software is a part of ISAR.
+# Copyright (C) 2025 Siemens AG
+
+header:
+ version: 14
+
+machine: qemuamd64-iso
--
2.39.5

Jan Kiszka

unread,
Jan 21, 2025, 5:24:15 AM1/21/25
to Felix Moessbauer, isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com
I suspect we still missing a hook-up into the isar test suite, aren't we?

Jan

--
Siemens AG, Foundational Technologies
Linux Expert Center

MOESSBAUER, Felix

unread,
Jan 21, 2025, 6:42:13 AM1/21/25
to isar-...@googlegroups.com, Kiszka, Jan, Bezdeka, Florian, Kowalsky, Clara
Probably yes, but I can't provide that as I'm not familiar with the
testsuite. What we need is a test that builds the target and checks if
systemctl is-system-running reports "running".

Felix

>
> Jan
>

Jan Kiszka

unread,
Jan 21, 2025, 8:18:00 AM1/21/25
to Moessbauer, Felix (FT RPD CED OES-DE), isar-...@googlegroups.com, Bezdeka, Florian (FT RPD CED OES-DE), Kowalsky, Clara (FT RPD CED OES-DE)
Building an iso would be a starting point. Running it in a VM is more
effort as it actually requires you do fiddle with local execution of the
testsuite.

Uladzimir Bely

unread,
Jan 22, 2025, 7:22:31 AM1/22/25
to Felix Moessbauer, isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com
On Tue, 2025-01-21 at 11:12 +0100, 'Felix Moessbauer' via isar-users
wrote:
> Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
> ---
>  meta-isar/conf/machine/qemuamd64-iso.conf     | 29
> +++++++++++++++++++
>  .../multiconfig/qemuamd64-iso-bookworm.conf   |  4 +++
>  .../lib/wic/canned-wks/isohybrid-efi.wks.in   |  2 ++
>  3 files changed, 35 insertions(+)
>  create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
>  create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-
> bookworm.conf
>  create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-
> efi.wks.in
>
> diff --git a/meta-isar/conf/machine/qemuamd64-iso.conf b/meta-
It is worth also adding to `meta-isar/conf/mc.conf`.

> diff --git a/meta-isar/scripts/lib/wic/canned-wks/isohybrid-
> efi.wks.in b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-
> efi.wks.in
> new file mode 100644
> index 00000000..514f756c
> --- /dev/null
> +++ b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
> @@ -0,0 +1,2 @@
> +part /boot --source isoimage-isohybrid-isar --
> sourceparams="loader=grub-
> efi,payload=${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.squashfs" --ondisk
> cd --label LIVECD
> +bootloader --timeout=10 --append "console=ttyS0,115200 console=tty0
> boot=live toram=${IMAGE_FULLNAME}.squashfs"
> --
> 2.39.5
>

--
Best regards,
Uladzimir.



Uladzimir Bely

unread,
Jan 22, 2025, 7:25:15 AM1/22/25
to Felix Moessbauer, isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com
On Tue, 2025-01-21 at 11:12 +0100, 'Felix Moessbauer' via isar-users
wrote:
> The iso support has been tested with the following distributions:
>
> - Debian: buster, bullseye, bookworm, trixie
> - Ubuntu: Focal, Jammy, Noble
>
> Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
> ---
>  kas/machine/Kconfig            | 14 ++++++++++++++
>  kas/machine/qemuamd64-iso.yaml |  7 +++++++
>  2 files changed, 21 insertions(+)
>  create mode 100644 kas/machine/qemuamd64-iso.yaml
>
> diff --git a/kas/machine/Kconfig b/kas/machine/Kconfig
> index 1740bd56..c37a1465 100644
> --- a/kas/machine/Kconfig
> +++ b/kas/machine/Kconfig
> @@ -107,6 +107,19 @@ config MACHINE_QEMU_AMD64_SB
>   select CODENAME_BULLSEYE
>   select ARCH_AMD64
>  
> +config MACHINE_QEMU_AMD64_ISO
> + bool "qemuamd64-iso"
> + select DISTRO_DEBIAN
> + select CODENAME_BUSTER
> + select CODENAME_BULLSEYE
> + select CODENAME_BOOKWORM
> + select CODENAME_TRIXIE

Since only "qemuamd64-iso-bookworm" multiconfig is added (and tested)
we should leave only DISTRO_DEBIAN and CODENAME_BOOKWORM here. If user
wants to build untested combination, they can check an appropriate
option in "Distro selection" sumenu.
--
Best regards,
Uladzimir.



Uladzimir Bely

unread,
Jan 22, 2025, 8:35:06 AM1/22/25
to Felix Moessbauer, isar-...@googlegroups.com
On Tue, 2025-01-21 at 11:12 +0100, 'Felix Moessbauer' via isar-users
wrote:
> Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
> ---
>  meta-isar/conf/machine/qemuamd64-iso.conf     | 29
> +++++++++++++++++++
>  .../multiconfig/qemuamd64-iso-bookworm.conf   |  4 +++
>  .../lib/wic/canned-wks/isohybrid-efi.wks.in   |  2 ++
>  3 files changed, 35 insertions(+)
>  create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
>  create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-
> bookworm.conf
>  create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-
> efi.wks.in
>
> diff --git a/meta-isar/conf/machine/qemuamd64-iso.conf b/meta-
> isar/conf/machine/qemuamd64-iso.conf
This looks like a typo - there is not such machine

> +DISTRO ?= "debian-bookworm"
> diff --git a/meta-isar/scripts/lib/wic/canned-wks/isohybrid-
> efi.wks.in b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-
> efi.wks.in
> new file mode 100644
> index 00000000..514f756c
> --- /dev/null
> +++ b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
> @@ -0,0 +1,2 @@
> +part /boot --source isoimage-isohybrid-isar --
> sourceparams="loader=grub-
> efi,payload=${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.squashfs" --ondisk
> cd --label LIVECD
> +bootloader --timeout=10 --append "console=ttyS0,115200 console=tty0
> boot=live toram=${IMAGE_FULLNAME}.squashfs"
> --
> 2.39.5
>

--
Best regards,
Uladzimir.



Uladzimir Bely

unread,
Jan 22, 2025, 9:11:42 AM1/22/25
to MOESSBAUER, Felix, isar-...@googlegroups.com, Kiszka, Jan, Bezdeka, Florian, Kowalsky, Clara
On Tue, 2025-01-21 at 11:42 +0000, 'MOESSBAUER, Felix' via isar-users
wrote:
I tried to check the image (build with kas) under qemu and it fails for
me. My steps (some of them are definitely worth adding to Isar):

1. Some local modifications:

- Added to "start_vm.py" `amd64-iso` "machine"

- Fixed machine in multiconfig/qemuamd64-iso-bookworm.conf (see my
comments to patch 4)

- Added to kas/isar.yaml:

```
local_conf_header:
bbmulticonfig: |
BBMULTICONFIG += "${MACHINE}-${BASE_DISTRO_CODENAME}"
```

No we can run "start_vm.py" that uses multiconfigs parsing inside.

2. Building the image

Configured `kas-container` menu and run build:
- machine: qemuamd64-iso
- distro: debian
- user `root` enabled


3. Running the image with start_vm.py

# Workaround for bitbake reusing kas' relative paths in
conf/bblayers.conf
ln -s . repo


# Run qemu on the host
. isar-init-build-env
../testsuite/start_vm.py -a amd64-iso -d bookworm -i isar-image-base


After logging in, `systemd is-system-running` shows "starting" that is
changed to "degraded" after a while.



> Felix
>
> >
> > Jan
> >
>

--
Best regards,
Uladzimir.



Uladzimir Bely

unread,
Jan 22, 2025, 10:02:36 AM1/22/25
to MOESSBAUER, Felix, isar-...@googlegroups.com, Kiszka, Jan, Bezdeka, Florian, Kowalsky, Clara
Additionally, this can be running using testsuite. We have SingleTest
that can build (test_single_build) and run (test_single_run) any custom
machine.

To run avocado on host machine, previous fix should be followed by:

- Preparations:

python3 -m venv .venv/
. .venv/bin/activate
python3 -m pip install avocado-framework

- Running signle testcase:

avocado --show=app,test run --max-parallel-tasks=1
testsuite/citest.py:SingleTest.test_single_run -p machine=qemuamd64-iso
-p distro=bookworm -p image=isar-image-ci

This can be also run under kas shell in similar way, but some
additional packages should be installed:

- Preparations:

sudo apt update
sudo apt install qemu-system
sudo apt install python3-venv

python3 -m venv .venv/
. .venv/bin/activate
python3 -m pip install avocado-framework

Running both testcases from SingleTest class:

avocado --show=app,test run --max-parallel-tasks=1
/repo/testsuite/citest.py:SingleTest -p machine=qemuamd64-iso -p
distro=bookworm -p image=isar-image-ci


>
> > Felix
> >
> > >
> > > Jan
> > >
> >
>
> --
> Best regards,
> Uladzimir.
>
>
>

--
Best regards,
Uladzimir.



MOESSBAUER, Felix

unread,
Jan 23, 2025, 2:53:58 AM1/23/25
to ub...@ilbers.de, isar-...@googlegroups.com, Kiszka, Jan, Bezdeka, Florian, Kowalsky, Clara
Hi, I'll add this in the v2 as well.

>
> - Fixed machine in multiconfig/qemuamd64-iso-bookworm.conf (see my
> comments to patch 4)
>
> - Added to kas/isar.yaml:
>
> ```
> local_conf_header:
>   bbmulticonfig: |
>     BBMULTICONFIG += "${MACHINE}-${BASE_DISTRO_CODENAME}"
> ```
>
> No we can run "start_vm.py" that uses multiconfigs parsing inside.
>
> 2. Building the image
>
> Configured `kas-container` menu and run build:
>  - machine: qemuamd64-iso
>  - distro: debian
>  - user `root` enabled
>
>
> 3. Running the image with start_vm.py
>
> # Workaround for bitbake reusing kas' relative paths in
> conf/bblayers.conf
> ln -s . repo
>
>
> # Run qemu on the host
> . isar-init-build-env
> ../testsuite/start_vm.py -a amd64-iso -d bookworm -i isar-image-base
>
>
> After logging in, `systemd is-system-running` shows "starting" that
> is
> changed to "degraded" after a while.

Please do a systemctl list-units --failed and paste the output here.
I tested with the following (manual) qemu cmdline and there it
correctly worked:

qemu-system-x86_64 -m 1G -snapshot -serial mon:stdio \
-netdev user,id=net,hostfwd=tcp:127.0.0.1:22222-:22 \
-cdrom build/tmp/deploy/images/qemuamd64-iso/isar-image-base-
debian-bookworm-qemuamd64-iso.wic \
-cpu host -smp 4 -machine q35,accel=kvm:tcg \
-bios /usr/share/ovmf/OVMF.fd -global ICH9-LPC.noreboot=off \
-device virtio-net-pci,netdev=net -nographic

Best regards,
Felix Moessbauer

>
>
>
> > Felix
> >
> > >
> > > Jan
> > >
> >
>

--
Siemens AG
Linux Expert Center
Friedrich-Ludwig-Bauer-Str. 3
85748 Garching, Germany


MOESSBAUER, Felix

unread,
Jan 23, 2025, 3:49:59 AM1/23/25
to ub...@ilbers.de, isar-...@googlegroups.com, Kiszka, Jan, Bezdeka, Florian, Kowalsky, Clara
This quirk is just needed for the start_vm script, as it checks for
multiconfig target. However, with the build commands from above we do
not build a multiconfig target. If we would, kas would automatically
add this line (with the concrete values instead of vars).

>
> No we can run "start_vm.py" that uses multiconfigs parsing inside.
>
> 2. Building the image
>
> Configured `kas-container` menu and run build:
>  - machine: qemuamd64-iso
>  - distro: debian
>  - user `root` enabled
>
>
> 3. Running the image with start_vm.py
>
> # Workaround for bitbake reusing kas' relative paths in
> conf/bblayers.conf
> ln -s . repo
>
>
> # Run qemu on the host
> . isar-init-build-env
> ../testsuite/start_vm.py -a amd64-iso -d bookworm -i isar-image-base
>
>
> After logging in, `systemd is-system-running` shows "starting" that
> is
> changed to "degraded" after a while.

When building exactly with the commands from above, the boot fails as
neither podman nor docker can run on the live system (as their storage
backend needs a writable, but non overlayfs mountpoint). We could work
around this by backing the storage dirs with a tmpfs, however I don't
think that's worth the effort. As debians live-boot package which
provides the initrd hooks does not support this, we would have to write
and maintain a lot of infrastructure just for this use-case.

The amount of temporary data the system can hold is anyways limited by
the available system memory (RAM).

In the v2, I'll just disable the problematic packages in our KConfig,
if not requested otherwise.

Felix

Felix Moessbauer

unread,
Jan 23, 2025, 4:52:57 AM1/23/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
This series adds support to create hybrid iso9660 images for ISAR
which can be used as live images for booting from USB sticks or
DVDs. Currently, only syslinux and EFI (grub) bootloaders are supported.

Changes since v1:

- fixed typo in machine name
- add multiconfig target
- kas-menu: exclude container image packages if qemuamd64-iso is selected
(as overlay2 fs cannot be stacked and Debian also does not support containers
in the live image)
- add test for building the image

Further, I tested the image with the Test-Single CI target and that also worked:

avocado --show=app,test run --max-parallel-tasks=1 \
testsuite/citest.py:SingleTest.test_single_run -p machine=qemuamd64-iso \
-p distro=bookworm -p image=isar-image-ci

Best regards,
Felix Moessbauer

Felix Moessbauer (7):
Import isoimage-isohybrid from oe
wic: add ISAR version of isohybrid-efi plugin
move squashfs imagetype class from CIP to ISAR
add qemuamd64 target for hybrid iso9660 image
add kas menu target for qemuamd64-iso machine
testsuite: add qemuamd64-iso machine to start_vm script
testsuite: test build of mc:qemuamd64-iso-bookworm:isar-image-base

kas/machine/Kconfig | 7 +
kas/machine/qemuamd64-iso.yaml | 7 +
kas/package/Kconfig | 3 +
meta-isar/classes/squashfs.bbclass | 47 ++
meta-isar/conf/machine/qemuamd64-iso.conf | 29 +
meta-isar/conf/mc.conf | 1 +
.../multiconfig/qemuamd64-iso-bookworm.conf | 4 +
.../lib/wic/canned-wks/isohybrid-efi.wks.in | 2 +
meta/classes/image.bbclass | 2 +-
.../plugins/source/isoimage-isohybrid-isar.py | 535 ++++++++++++++++++
testsuite/citest.py | 1 +
testsuite/start_vm.py | 2 +-
12 files changed, 638 insertions(+), 2 deletions(-)
create mode 100644 kas/machine/qemuamd64-iso.yaml
create mode 100644 meta-isar/classes/squashfs.bbclass
create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
create mode 100644 meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py

--
2.39.5

Felix Moessbauer

unread,
Jan 23, 2025, 4:52:57 AM1/23/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
This adds support to generate a hybrid grub-efi + syslinux ISO9660
image. The patch is written in an add-only style to simplify updates of
the upstream plugin.

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
.../plugins/source/isoimage-isohybrid-isar.py | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)

diff --git a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
index afc9ea0f..b46527b8 100644
--- a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
+++ b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
@@ -18,6 +18,12 @@ from wic.engine import get_custom_config
from wic.pluginbase import SourcePlugin
from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var

+# allow plugins to import from isarpluginbase
+if '__file__' in globals():
+ import sys
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/..")
+from isarpluginbase import (isar_get_filenames, isar_populate_boot_cmd)
+
logger = logging.getLogger('wic')

class IsoImagePlugin(SourcePlugin):
@@ -44,6 +50,7 @@ class IsoImagePlugin(SourcePlugin):
"""

name = 'isoimage-isohybrid'
+ name = 'isoimage-isohybrid-isar'

@classmethod
def do_configure_syslinux(cls, creator, cr_workdir):
@@ -71,6 +78,9 @@ class IsoImagePlugin(SourcePlugin):
syslinux_conf += "LABEL boot\n"

kernel = get_bitbake_var("KERNEL_IMAGETYPE")
+ kernel, initrd = isar_get_filenames(
+ get_bitbake_var("IMAGE_ROOTFS"), get_bitbake_var("KERNEL_FILE")
+ )
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
if get_bitbake_var("INITRAMFS_IMAGE"):
kernel = "%s-%s.bin" % \
@@ -80,6 +90,13 @@ class IsoImagePlugin(SourcePlugin):
syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
% bootloader.append

+ # replace initrd with correct one
+ if initrd:
+ syslinux_conf = syslinux_conf.replace(
+ "initrd=/initrd", "initrd=/%s" % initrd)
+ else:
+ raise WicError("Couldn't find initrd, exiting.")
+
logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
cr_workdir)

@@ -125,9 +142,23 @@ class IsoImagePlugin(SourcePlugin):
kernel = "%s-%s.bin" % \
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))

+ kernel, initrd = isar_get_filenames(
+ get_bitbake_var("IMAGE_ROOTFS"), get_bitbake_var("KERNEL_FILE")
+ )
+
+ bootloader.append = bootloader.append or ""
grubefi_conf += "linux /%s rootwait %s\n" \
% (kernel, bootloader.append)
grubefi_conf += "initrd /initrd \n"
+ grubefi_conf = '\n'.join(grubefi_conf.splitlines()[:-1]) + '\n'
+
+ if initrd:
+ initrds = initrd.split(';')
+ grubefi_conf += "initrd"
+ for rd in initrds:
+ grubefi_conf += " /%s" % rd
+ grubefi_conf += "\n"
+
grubefi_conf += "}\n"

if splashline:
@@ -156,12 +187,14 @@ class IsoImagePlugin(SourcePlugin):
raise WicError("Couldn't find IMAGE_BASENAME, exiting.")

image_type = get_bitbake_var("INITRAMFS_FSTYPES")
+ image_type = image_type or "img"
if not image_type:
raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")

machine = os.path.basename(initrd_dir)

pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
+ pattern = '%s/%s-%s-initrd.%s' % (initrd_dir, image_name, machine, image_type)
files = glob.glob(pattern)
if files:
initrd = files[0]
@@ -227,6 +260,12 @@ class IsoImagePlugin(SourcePlugin):

logger.debug("Payload directory: %s", payload_dir)
shutil.copytree(payload_dir, iso_dir, symlinks=True, dirs_exist_ok=True)
+ if source_params.get('payload'):
+ payload = source_params.get('payload')
+
+ logger.debug("Payload: %s", payload)
+ os.mkdir('%s/live' % iso_dir)
+ shutil.copy(payload, '%s/live' % iso_dir)

@classmethod
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
@@ -299,6 +338,7 @@ class IsoImagePlugin(SourcePlugin):

install_cmd = "install -m 0644 %s/%s %s/%s" % \
(kernel_dir, kernel, isodir, kernel)
+ install_cmd = isar_populate_boot_cmd(rootfs_dir, isodir)
exec_cmd(install_cmd)

#Create bootloader for efi boot
@@ -313,19 +353,46 @@ class IsoImagePlugin(SourcePlugin):
# Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
# didn't contains it
target_arch = get_bitbake_var("TARGET_SYS")
+ distro_arch = get_bitbake_var("DISTRO_ARCH")
+ if distro_arch == "amd64":
+ target_arch = "x86_64"
+ else:
+ target_arch = distro_arch
+
if not target_arch:
raise WicError("Coludn't find target architecture")

if re.match("x86_64", target_arch):
+ grub_target = "x86_64-efi"
grub_src_image = "grub-efi-bootx64.efi"
grub_dest_image = "bootx64.efi"
+ grub_modules = "multiboot efi_uga iorw ata "
+ if get_bitbake_var("DISTRO").startswith("ubuntu") and \
+ os.path.exists('/usr/lib/grub/x86_64-efi/linuxefi.mod'):
+ grub_modules += "linuxefi "
elif re.match('i.86', target_arch):
+ grub_target = "i386-efi"
grub_src_image = "grub-efi-bootia32.efi"
grub_dest_image = "bootia32.efi"
+ grub_modules = "multiboot efi_uga iorw ata "
else:
raise WicError("grub-efi is incompatible with target %s" %
target_arch)

+ if not os.path.isfile("%s/%s" \
+ % (target_dir, grub_dest_image)):
+ grub_cmd = "grub-mkimage -p /EFI/BOOT "
+ grub_cmd += "-O %s -o %s/%s " \
+ % (grub_target, target_dir, grub_dest_image)
+ grub_cmd += "part_gpt part_msdos ntfs ntfscomp fat ext2 "
+ grub_cmd += "normal chain boot configfile linux "
+ grub_cmd += "search efi_gop font gfxterm gfxmenu "
+ grub_cmd += "terminal minicmd test loadenv echo help "
+ grub_cmd += "reboot serial terminfo iso9660 loopback tar "
+ grub_cmd += "memdisk ls search_fs_uuid udf btrfs xfs lvm "
+ grub_cmd += "reiserfs regexp " + grub_modules
+ exec_cmd(grub_cmd)
+
grub_target = os.path.join(target_dir, grub_dest_image)
if not os.path.isfile(grub_target):
grub_src = os.path.join(deploy_dir, grub_src_image)
@@ -393,18 +460,23 @@ class IsoImagePlugin(SourcePlugin):
cls.do_configure_syslinux(creator, cr_workdir)

install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
+ # different name in Debian
+ install_cmd = "install -m 444 %s/syslinux/modules/bios/ldlinux.c32 " % syslinux_dir
install_cmd += "%s/isolinux/ldlinux.sys" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/ISOLINUX/')
install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/ISOLINUX/')
install_cmd += "%s/isolinux/isolinux.bin" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/syslinux/modules/bios/')
install_cmd += "%s/isolinux/ldlinux.c32" % isodir
exec_cmd(install_cmd)

@@ -415,6 +487,8 @@ class IsoImagePlugin(SourcePlugin):
efi_img = "efi.img"

mkisofs_cmd = "mkisofs -V %s " % part.label
+ # use xorriso from Debian
+ mkisofs_cmd = "xorriso -as mkisofs -V %s " % part.label
mkisofs_cmd += "-o %s -U " % iso_img
mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
--
2.39.5

Felix Moessbauer

unread,
Jan 23, 2025, 4:52:58 AM1/23/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
OE-core Revision: b85a09ea450a5e8f49418f4a930805fbb88dc83b

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
.../plugins/source/isoimage-isohybrid-isar.py | 461 ++++++++++++++++++
1 file changed, 461 insertions(+)
create mode 100644 meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py

diff --git a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
new file mode 100644
+ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
+
+ syslinux_conf += "KERNEL /" + kernel + "\n"
+ syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
+ % bootloader.append
+
+ logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
+ cr_workdir)
+
+ with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg:
+ cfg.write(syslinux_conf)
+
+ @classmethod
+ def do_configure_grubefi(cls, part, creator, target_dir):
+ """
+ Create loader-specific (grub-efi) config
+ """
+ configfile = creator.ks.bootloader.configfile
+ if configfile:
+ grubefi_conf = get_custom_config(configfile)
+ if grubefi_conf:
+ logger.debug("Using custom configuration file %s for grub.cfg",
+ configfile)
+ else:
+ raise WicError("configfile is specified "
+ "but failed to get it from %s", configfile)
+ else:
+ splash = os.path.join(target_dir, "splash.jpg")
+ if os.path.exists(splash):
+ splashline = "menu background splash.jpg"
+ else:
+ splashline = ""
+
+ bootloader = creator.ks.bootloader
+
+ grubefi_conf = ""
+ grubefi_conf += "serial --unit=0 --speed=115200 --word=8 "
+ grubefi_conf += "--parity=no --stop=1\n"
+ grubefi_conf += "default=boot\n"
+ grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10)
+ grubefi_conf += "\n"
+ grubefi_conf += "search --set=root --label %s " % part.label
+ grubefi_conf += "\n"
+ grubefi_conf += "menuentry 'boot'{\n"
+
+ kernel = get_bitbake_var("KERNEL_IMAGETYPE")
+ if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
+ if get_bitbake_var("INITRAMFS_IMAGE"):
+ kernel = "%s-%s.bin" % \
+ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
+
+ else:
+ 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,
+ rootfs_dir, native_sysroot):
+ """
+ Called to do the actual content population for a partition i.e. it
+ 'prepares' the partition to be incorporated into the image.
+ In this case, prepare content for a bootable ISO image.
+ """
+
+ isodir = "%s/ISO" % cr_workdir
+
+ 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.")
+ rootfs_dir = rootfs_dir['ROOTFS_DIR']
+ else:
+ if part.rootfs_dir in rootfs_dir:
+ rootfs_dir = rootfs_dir[part.rootfs_dir]
+ elif part.rootfs_dir:
+ rootfs_dir = part.rootfs_dir
+ else:
+ kernel = get_bitbake_var("KERNEL_IMAGETYPE")
+ if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
+ if get_bitbake_var("INITRAMFS_IMAGE"):
+ kernel = "%s-%s.bin" % \
+ (get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))
+
+ else:
+ raise WicError("grub-efi is incompatible with target %s" %
+ target_arch)
+
+ grub_target = os.path.join(target_dir, grub_dest_image)
+ if not os.path.isfile(grub_target):
+ grub_src = os.path.join(deploy_dir, grub_src_image)
+ if not os.path.exists(grub_src):
+ raise WicError("Grub loader %s is not found in %s. "
+ "Please build grub-efi first" % (grub_src_image, deploy_dir))
+ shutil.copy(grub_src, grub_target)
+
+ if not os.path.isfile(os.path.join(target_dir, "boot.cfg")):
+ cls.do_configure_grubefi(part, creator, target_dir)
+
+ else:

Felix Moessbauer

unread,
Jan 23, 2025, 4:53:03 AM1/23/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
As a preparation for live images, we move the squashfs class from
isar-cip-core to ISAR and register it as always included.

ISAR-cip-core revision: 0e85378341fb7b37cf95b1c910ca0260cf4f5cf4

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
meta-isar/classes/squashfs.bbclass | 47 ++++++++++++++++++++++++++++++
meta/classes/image.bbclass | 2 +-
2 files changed, 48 insertions(+), 1 deletion(-)
create mode 100644 meta-isar/classes/squashfs.bbclass

diff --git a/meta-isar/classes/squashfs.bbclass b/meta-isar/classes/squashfs.bbclass
new file mode 100644
index 00000000..9cd7ed3d
--- /dev/null
+++ b/meta-isar/classes/squashfs.bbclass
@@ -0,0 +1,47 @@
+# squashfs image rootfs
+#
+# This software is a part of ISAR.

Felix Moessbauer

unread,
Jan 23, 2025, 4:53:03 AM1/23/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
meta-isar/conf/machine/qemuamd64-iso.conf | 29 +++++++++++++++++++
meta-isar/conf/mc.conf | 1 +
.../multiconfig/qemuamd64-iso-bookworm.conf | 4 +++
.../lib/wic/canned-wks/isohybrid-efi.wks.in | 2 ++
4 files changed, 36 insertions(+)
create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in

diff --git a/meta-isar/conf/machine/qemuamd64-iso.conf b/meta-isar/conf/machine/qemuamd64-iso.conf
new file mode 100644
index 00000000..36cbdf54
--- /dev/null
+++ b/meta-isar/conf/machine/qemuamd64-iso.conf
@@ -0,0 +1,29 @@
+# This software is a part of ISAR.
diff --git a/meta-isar/conf/mc.conf b/meta-isar/conf/mc.conf
index 2a7b69f3..7c190b67 100644
--- a/meta-isar/conf/mc.conf
+++ b/meta-isar/conf/mc.conf
@@ -22,6 +22,7 @@ BBMULTICONFIG = " \
qemuamd64-sb-bullseye \
qemuamd64-bookworm \
qemuamd64-cip-bookworm \
+ qemuamd64-iso-bookworm \
qemuamd64-trixie \
container-amd64-buster \
container-amd64-bullseye \
diff --git a/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf b/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
new file mode 100644
index 00000000..a2597131
--- /dev/null
+++ b/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
@@ -0,0 +1,4 @@
+# This software is a part of ISAR.
+
+MACHINE ?= "qemuamd64-iso"
+DISTRO ?= "debian-bookworm"
diff --git a/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
new file mode 100644
index 00000000..514f756c
--- /dev/null
+++ b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
@@ -0,0 +1,2 @@
+part /boot --source isoimage-isohybrid-isar --sourceparams="loader=grub-efi,payload=${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.squashfs" --ondisk cd --label LIVECD

Felix Moessbauer

unread,
Jan 23, 2025, 4:53:03 AM1/23/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
As this target is incompatible with container runtimes (rootfs uses an
overlay), we also disable the prepbuilt image examples for docker and
podman.

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
kas/machine/Kconfig | 7 +++++++
kas/machine/qemuamd64-iso.yaml | 7 +++++++
kas/package/Kconfig | 3 +++
3 files changed, 17 insertions(+)
create mode 100644 kas/machine/qemuamd64-iso.yaml

diff --git a/kas/machine/Kconfig b/kas/machine/Kconfig
index 1740bd56..8c334a8f 100644
--- a/kas/machine/Kconfig
+++ b/kas/machine/Kconfig
@@ -107,6 +107,12 @@ config MACHINE_QEMU_AMD64_SB
select CODENAME_BULLSEYE
select ARCH_AMD64

+config MACHINE_QEMU_AMD64_ISO
+ bool "qemuamd64-iso"
+ select DISTRO_DEBIAN
+ select CODENAME_BOOKWORM
+ select ARCH_AMD64
+
config MACHINE_QEMU_AMD64
bool "qemuamd64"
select DISTRO_DEBIAN
@@ -252,6 +258,7 @@ config KAS_INCLUDE_MACHINE
default "kas/machine/phyboard-mira.yaml" if MACHINE_PHYBOARD_MIRA
default "kas/machine/qemuamd64-cip.yaml" if MACHINE_QEMU_AMD64_CIP
default "kas/machine/qemuamd64-sb.yaml" if MACHINE_QEMU_AMD64_SB
+ default "kas/machine/qemuamd64-iso.yaml" if MACHINE_QEMU_AMD64_ISO
default "kas/machine/qemuamd64.yaml" if MACHINE_QEMU_AMD64
default "kas/machine/qemuarm.yaml" if MACHINE_QEMU_ARM
default "kas/machine/qemuarm64.yaml" if MACHINE_QEMU_ARM64
diff --git a/kas/machine/qemuamd64-iso.yaml b/kas/machine/qemuamd64-iso.yaml
new file mode 100644
index 00000000..f58a1217
--- /dev/null
+++ b/kas/machine/qemuamd64-iso.yaml
@@ -0,0 +1,7 @@
+# This software is a part of ISAR.
+# Copyright (C) 2025 Siemens AG
+
+header:
+ version: 14
+
+machine: qemuamd64-iso
diff --git a/kas/package/Kconfig b/kas/package/Kconfig
index bea2b121..a49041e8 100644
--- a/kas/package/Kconfig
+++ b/kas/package/Kconfig
@@ -61,6 +61,7 @@ config KAS_INCLUDE_PACKAGE_EXAMPLE_PREBUILT
config PACKAGE_EXPAND_ON_FIRST_BOOT
bool "expand-on-first-boot"
default y
+ depends on !MACHINE_QEMU_AMD64_ISO

config KAS_INCLUDE_PACKAGE_EXPAND_ON_FIRST_BOOT
string
@@ -151,6 +152,7 @@ config PACKAGE_PREBUILT_DOCKER_IMG
bool "prebuilt-docker-img"
default y
depends on ARCH_AMD64 || ARCH_ARM64 || ARCH_ARM
+ depends on !MACHINE_QEMU_AMD64_ISO

config KAS_INCLUDE_PACKAGE_PREBUILT_DOCKER_IMG
string
@@ -162,6 +164,7 @@ config PACKAGE_PREBUILT_PODMAN_IMG
default y
depends on DEBIAN_BULLSEYE || DEBIAN_BOOKWORM || DEBIAN_TRIXIE || UBUNTU_JAMMY || UBUNTU_NOBLE
depends on ARCH_AMD64 || ARCH_ARM64 || ARCH_ARM
+ depends on !MACHINE_QEMU_AMD64_ISO

config KAS_INCLUDE_PACKAGE_PREBUILT_PODMAN_IMG
string
--
2.39.5

Felix Moessbauer

unread,
Jan 23, 2025, 4:53:11 AM1/23/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
testsuite/citest.py | 1 +
1 file changed, 1 insertion(+)

diff --git a/testsuite/citest.py b/testsuite/citest.py
index 82affb1a..504747d0 100755
--- a/testsuite/citest.py
+++ b/testsuite/citest.py
@@ -241,6 +241,7 @@ class NoCrossTest(CIBaseTest):
'mc:nanopi-neo-bookworm:isar-image-base',
'mc:qemuamd64-focal:isar-image-ci',
'mc:qemuamd64-bookworm:isar-image-ci',
+ 'mc:qemuamd64-iso-bookworm:isar-image-base',
'mc:qemui386-bookworm:isar-image-base',
'mc:qemumipsel-bookworm:isar-image-ci',
'mc:hikey-bookworm:isar-image-base',
--
2.39.5

Felix Moessbauer

unread,
Jan 23, 2025, 4:53:11 AM1/23/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
testsuite/start_vm.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/testsuite/start_vm.py b/testsuite/start_vm.py
index 76814ee3..d3621ec3 100755
--- a/testsuite/start_vm.py
+++ b/testsuite/start_vm.py
@@ -148,7 +148,7 @@ def start_qemu(arch, build, distro, image, out, pid, enforce_pcbios):

def parse_args():
parser = argparse.ArgumentParser()
- arch_names = ['arm', 'arm64', 'amd64', 'amd64-sb', 'amd64-cip', 'i386', 'mipsel']
+ arch_names = ['arm', 'arm64', 'amd64', 'amd64-sb', 'amd64-cip', 'amd64-iso', 'i386', 'mipsel']
distro_names = [
'buster',
'bullseye',
--
2.39.5

Uladzimir Bely

unread,
Jan 24, 2025, 5:56:50 AM1/24/25
to Felix Moessbauer, isar-...@googlegroups.com
On Thu, 2025-01-23 at 10:52 +0100, 'Felix Moessbauer' via isar-users
wrote:
> Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
> ---
>  meta-isar/conf/machine/qemuamd64-iso.conf     | 29
> +++++++++++++++++++
>  meta-isar/conf/mc.conf                        |  1 +
>  .../multiconfig/qemuamd64-iso-bookworm.conf   |  4 +++
>  .../lib/wic/canned-wks/isohybrid-efi.wks.in   |  2 ++
>  4 files changed, 36 insertions(+)
>  create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
>  create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-
> bookworm.conf
>  create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-
> efi.wks.in
>
> diff --git a/meta-isar/conf/machine/qemuamd64-iso.conf b/meta-
> isar/conf/machine/qemuamd64-iso.conf
Forgot to comment in on PATCH v1 series...

Would not it be better to include qemuamd64.conf and just add "-iso"
related modification, like it's done for other "qemuamd64-xxx" configs?
--
Best regards,
Uladzimir.



Uladzimir Bely

unread,
Jan 24, 2025, 5:58:55 AM1/24/25
to Felix Moessbauer, isar-...@googlegroups.com
On Thu, 2025-01-23 at 10:52 +0100, 'Felix Moessbauer' via isar-users
wrote:
I've also added run test and currently testing it in CI.

If there is v3 of the patchset, feel free to include/amend it -
https://github.com/ilbers/isar/commit/cd3edbd

If not, I'll send it separately.

--
Best regards,
Uladzimir.



MOESSBAUER, Felix

unread,
Jan 24, 2025, 7:03:12 AM1/24/25
to ub...@ilbers.de, isar-...@googlegroups.com
Hi, thanks for helping me out ;)

I'll send a v3 along with the machine config optimization.

Best regards,
Felix

>
> If not, I'll send it separately.
>

--

Felix Moessbauer

unread,
Jan 24, 2025, 7:36:03 AM1/24/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
This series adds support to create hybrid iso9660 images for ISAR
which can be used as live images for booting from USB sticks or
DVDs. Currently, only syslinux and EFI (grub) bootloaders are supported.

Changes since v2:

- qemuamd64-iso: derive (include) from qemuamd64.
- add run test for qemuamd64-iso machine (based on Uladzimirs proposal, thanks!)

Changes since v1:

- fixed typo in machine name
- add multiconfig target
- kas-menu: exclude container image packages if qemuamd64-iso is selected
(as overlay2 fs cannot be stacked and Debian also does not support containers
in the live image)
- add test for building the image

Further, I tested the image with the Test-Single CI target and that also worked:

avocado --show=app,test run --max-parallel-tasks=1 \
testsuite/citest.py:SingleTest.test_single_run -p machine=qemuamd64-iso \
-p distro=bookworm -p image=isar-image-ci

Best regards,
Felix Moessbauer

Felix Moessbauer (7):
Import isoimage-isohybrid from oe
wic: add ISAR version of isohybrid-efi plugin
move squashfs imagetype class from CIP to ISAR
add qemuamd64-iso target for hybrid iso9660 image
add kas menu target for qemuamd64-iso machine
testsuite: add qemuamd64-iso machine to start_vm script
testsuite: test mc:qemuamd64-iso-bookworm:isar-image-base

kas/machine/Kconfig | 7 +
kas/machine/qemuamd64-iso.yaml | 7 +
kas/package/Kconfig | 3 +
meta-isar/classes/squashfs.bbclass | 47 ++
meta-isar/conf/machine/qemuamd64-iso.conf | 19 +
meta-isar/conf/mc.conf | 1 +
.../multiconfig/qemuamd64-iso-bookworm.conf | 4 +
.../lib/wic/canned-wks/isohybrid-efi.wks.in | 2 +
meta/classes/image.bbclass | 2 +-
.../plugins/source/isoimage-isohybrid-isar.py | 535 ++++++++++++++++++
testsuite/citest.py | 12 +
testsuite/scripts/test_system_running.sh | 22 +
testsuite/start_vm.py | 2 +-
13 files changed, 661 insertions(+), 2 deletions(-)
create mode 100644 kas/machine/qemuamd64-iso.yaml
create mode 100644 meta-isar/classes/squashfs.bbclass
create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
create mode 100644 meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
create mode 100755 testsuite/scripts/test_system_running.sh

--
2.39.5

Felix Moessbauer

unread,
Jan 24, 2025, 7:36:03 AM1/24/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
OE-core Revision: b85a09ea450a5e8f49418f4a930805fbb88dc83b

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
.../plugins/source/isoimage-isohybrid-isar.py | 461 ++++++++++++++++++
1 file changed, 461 insertions(+)
create mode 100644 meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py

diff --git a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
new file mode 100644

Felix Moessbauer

unread,
Jan 24, 2025, 7:36:04 AM1/24/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
This adds support to generate a hybrid grub-efi + syslinux ISO9660
image. The patch is written in an add-only style to simplify updates of
the upstream plugin.

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
.../plugins/source/isoimage-isohybrid-isar.py | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)

diff --git a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
index afc9ea0f..b46527b8 100644
--- a/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
+++ b/meta/scripts/lib/wic/plugins/source/isoimage-isohybrid-isar.py
@@ -18,6 +18,12 @@ from wic.engine import get_custom_config
from wic.pluginbase import SourcePlugin
from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var

+# allow plugins to import from isarpluginbase
+if '__file__' in globals():
+ import sys
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/..")
+from isarpluginbase import (isar_get_filenames, isar_populate_boot_cmd)
+
logger = logging.getLogger('wic')

class IsoImagePlugin(SourcePlugin):
@@ -44,6 +50,7 @@ class IsoImagePlugin(SourcePlugin):
"""

name = 'isoimage-isohybrid'
+ name = 'isoimage-isohybrid-isar'

@classmethod
def do_configure_syslinux(cls, creator, cr_workdir):
@@ -71,6 +78,9 @@ class IsoImagePlugin(SourcePlugin):
syslinux_conf += "LABEL boot\n"

kernel = get_bitbake_var("KERNEL_IMAGETYPE")
+ kernel, initrd = isar_get_filenames(
+ get_bitbake_var("IMAGE_ROOTFS"), get_bitbake_var("KERNEL_FILE")
+ )
if get_bitbake_var("INITRAMFS_IMAGE_BUNDLE") == "1":
if get_bitbake_var("INITRAMFS_IMAGE"):
kernel = "%s-%s.bin" % \
@@ -80,6 +90,13 @@ class IsoImagePlugin(SourcePlugin):
syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
% bootloader.append

+ # replace initrd with correct one
+ if initrd:
+ syslinux_conf = syslinux_conf.replace(
+ "initrd=/initrd", "initrd=/%s" % initrd)
+ else:
+ raise WicError("Couldn't find initrd, exiting.")
+
logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
cr_workdir)

@@ -125,9 +142,23 @@ class IsoImagePlugin(SourcePlugin):
kernel = "%s-%s.bin" % \
(get_bitbake_var("KERNEL_IMAGETYPE"), get_bitbake_var("INITRAMFS_LINK_NAME"))

+ kernel, initrd = isar_get_filenames(
+ get_bitbake_var("IMAGE_ROOTFS"), get_bitbake_var("KERNEL_FILE")
+ )
+
+ bootloader.append = bootloader.append or ""
grubefi_conf += "linux /%s rootwait %s\n" \
% (kernel, bootloader.append)
grubefi_conf += "initrd /initrd \n"
+ grubefi_conf = '\n'.join(grubefi_conf.splitlines()[:-1]) + '\n'
+
+ if initrd:
+ initrds = initrd.split(';')
+ grubefi_conf += "initrd"
+ for rd in initrds:
+ grubefi_conf += " /%s" % rd
+ grubefi_conf += "\n"
+
grubefi_conf += "}\n"

if splashline:
@@ -156,12 +187,14 @@ class IsoImagePlugin(SourcePlugin):
raise WicError("Couldn't find IMAGE_BASENAME, exiting.")

image_type = get_bitbake_var("INITRAMFS_FSTYPES")
+ image_type = image_type or "img"
if not image_type:
raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")

machine = os.path.basename(initrd_dir)

pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
+ pattern = '%s/%s-%s-initrd.%s' % (initrd_dir, image_name, machine, image_type)
files = glob.glob(pattern)
if files:
initrd = files[0]
@@ -227,6 +260,12 @@ class IsoImagePlugin(SourcePlugin):

logger.debug("Payload directory: %s", payload_dir)
shutil.copytree(payload_dir, iso_dir, symlinks=True, dirs_exist_ok=True)
+ if source_params.get('payload'):
+ payload = source_params.get('payload')
+
+ logger.debug("Payload: %s", payload)
+ os.mkdir('%s/live' % iso_dir)
+ shutil.copy(payload, '%s/live' % iso_dir)

@classmethod
def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
@@ -299,6 +338,7 @@ class IsoImagePlugin(SourcePlugin):

install_cmd = "install -m 0644 %s/%s %s/%s" % \
(kernel_dir, kernel, isodir, kernel)
+ install_cmd = isar_populate_boot_cmd(rootfs_dir, isodir)
exec_cmd(install_cmd)

#Create bootloader for efi boot
@@ -313,19 +353,46 @@ class IsoImagePlugin(SourcePlugin):
# Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
# didn't contains it
target_arch = get_bitbake_var("TARGET_SYS")
+ distro_arch = get_bitbake_var("DISTRO_ARCH")
+ if distro_arch == "amd64":
+ target_arch = "x86_64"
+ else:
+ target_arch = distro_arch
+
if not target_arch:
raise WicError("Coludn't find target architecture")

if re.match("x86_64", target_arch):
+ grub_target = "x86_64-efi"
grub_src_image = "grub-efi-bootx64.efi"
grub_dest_image = "bootx64.efi"
+ grub_modules = "multiboot efi_uga iorw ata "
+ if get_bitbake_var("DISTRO").startswith("ubuntu") and \
+ os.path.exists('/usr/lib/grub/x86_64-efi/linuxefi.mod'):
+ grub_modules += "linuxefi "
elif re.match('i.86', target_arch):
+ grub_target = "i386-efi"
grub_src_image = "grub-efi-bootia32.efi"
grub_dest_image = "bootia32.efi"
+ grub_modules = "multiboot efi_uga iorw ata "
else:
raise WicError("grub-efi is incompatible with target %s" %
target_arch)

+ if not os.path.isfile("%s/%s" \
+ % (target_dir, grub_dest_image)):
+ grub_cmd = "grub-mkimage -p /EFI/BOOT "
+ grub_cmd += "-O %s -o %s/%s " \
+ % (grub_target, target_dir, grub_dest_image)
+ grub_cmd += "part_gpt part_msdos ntfs ntfscomp fat ext2 "
+ grub_cmd += "normal chain boot configfile linux "
+ grub_cmd += "search efi_gop font gfxterm gfxmenu "
+ grub_cmd += "terminal minicmd test loadenv echo help "
+ grub_cmd += "reboot serial terminfo iso9660 loopback tar "
+ grub_cmd += "memdisk ls search_fs_uuid udf btrfs xfs lvm "
+ grub_cmd += "reiserfs regexp " + grub_modules
+ exec_cmd(grub_cmd)
+
grub_target = os.path.join(target_dir, grub_dest_image)
if not os.path.isfile(grub_target):
grub_src = os.path.join(deploy_dir, grub_src_image)
@@ -393,18 +460,23 @@ class IsoImagePlugin(SourcePlugin):
cls.do_configure_syslinux(creator, cr_workdir)

install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
+ # different name in Debian
+ install_cmd = "install -m 444 %s/syslinux/modules/bios/ldlinux.c32 " % syslinux_dir
install_cmd += "%s/isolinux/ldlinux.sys" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/ISOLINUX/')
install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/ISOLINUX/')
install_cmd += "%s/isolinux/isolinux.bin" % isodir
exec_cmd(install_cmd)

install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
+ install_cmd = install_cmd.replace('/syslinux/', '/syslinux/modules/bios/')
install_cmd += "%s/isolinux/ldlinux.c32" % isodir
exec_cmd(install_cmd)

@@ -415,6 +487,8 @@ class IsoImagePlugin(SourcePlugin):
efi_img = "efi.img"

mkisofs_cmd = "mkisofs -V %s " % part.label
+ # use xorriso from Debian
+ mkisofs_cmd = "xorriso -as mkisofs -V %s " % part.label
mkisofs_cmd += "-o %s -U " % iso_img
mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
--
2.39.5

Felix Moessbauer

unread,
Jan 24, 2025, 7:36:07 AM1/24/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
As a preparation for live images, we move the squashfs class from
isar-cip-core to ISAR and register it as always included.

ISAR-cip-core revision: 0e85378341fb7b37cf95b1c910ca0260cf4f5cf4

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
meta-isar/classes/squashfs.bbclass | 47 ++++++++++++++++++++++++++++++
meta/classes/image.bbclass | 2 +-
2 files changed, 48 insertions(+), 1 deletion(-)
create mode 100644 meta-isar/classes/squashfs.bbclass

diff --git a/meta-isar/classes/squashfs.bbclass b/meta-isar/classes/squashfs.bbclass
new file mode 100644
index 00000000..9cd7ed3d
--- /dev/null
+++ b/meta-isar/classes/squashfs.bbclass
@@ -0,0 +1,47 @@
+# squashfs image rootfs
+#
+# This software is a part of ISAR.

Felix Moessbauer

unread,
Jan 24, 2025, 7:36:08 AM1/24/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
As this target is incompatible with container runtimes (rootfs uses an
overlay), we also disable the prepbuilt image examples for docker and
podman.

Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
new file mode 100644
index 00000000..f58a1217
--- /dev/null
+++ b/kas/machine/qemuamd64-iso.yaml
@@ -0,0 +1,7 @@
+# This software is a part of ISAR.

Felix Moessbauer

unread,
Jan 24, 2025, 7:36:08 AM1/24/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
meta-isar/conf/machine/qemuamd64-iso.conf | 19 +++++++++++++++++++
meta-isar/conf/mc.conf | 1 +
.../multiconfig/qemuamd64-iso-bookworm.conf | 4 ++++
.../lib/wic/canned-wks/isohybrid-efi.wks.in | 2 ++
4 files changed, 26 insertions(+)
create mode 100644 meta-isar/conf/machine/qemuamd64-iso.conf
create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in

diff --git a/meta-isar/conf/machine/qemuamd64-iso.conf b/meta-isar/conf/machine/qemuamd64-iso.conf
new file mode 100644
index 00000000..eef5d7ec
--- /dev/null
+++ b/meta-isar/conf/machine/qemuamd64-iso.conf
@@ -0,0 +1,19 @@
+# This software is a part of ISAR.
+# Copyright (C) 2025 Siemens AG
+
+WKS_FILE ?= "isohybrid-efi.wks.in"
+IMAGER_INSTALL:wic += " \
+ ${SYSLINUX_BOOTLOADER_INSTALL} \
+ syslinux-utils \
+ isolinux \
+ xorriso \
+"
+
+IMAGE_PREINSTALL += "live-boot"
+IMAGE_INSTALL:remove = "expand-on-first-boot"
+IMAGE_TYPEDEP:wic += "squashfs"
+SQUASHFS_EXCLUDE_DIRS = "boot"
+
+QEMU_DISK_ARGS ?= "-cdrom ##ROOTFS_IMAGE## -bios /usr/share/ovmf/OVMF.fd"
+
+require conf/machine/qemuamd64.conf
diff --git a/meta-isar/conf/mc.conf b/meta-isar/conf/mc.conf
index 2a7b69f3..7c190b67 100644
--- a/meta-isar/conf/mc.conf
+++ b/meta-isar/conf/mc.conf
@@ -22,6 +22,7 @@ BBMULTICONFIG = " \
qemuamd64-sb-bullseye \
qemuamd64-bookworm \
qemuamd64-cip-bookworm \
+ qemuamd64-iso-bookworm \
qemuamd64-trixie \
container-amd64-buster \
container-amd64-bullseye \
diff --git a/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf b/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
new file mode 100644
index 00000000..a2597131
--- /dev/null
+++ b/meta-isar/conf/multiconfig/qemuamd64-iso-bookworm.conf
@@ -0,0 +1,4 @@
+# This software is a part of ISAR.
+
+MACHINE ?= "qemuamd64-iso"
+DISTRO ?= "debian-bookworm"
diff --git a/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
new file mode 100644
index 00000000..514f756c
--- /dev/null
+++ b/meta-isar/scripts/lib/wic/canned-wks/isohybrid-efi.wks.in
@@ -0,0 +1,2 @@
+part /boot --source isoimage-isohybrid-isar --sourceparams="loader=grub-efi,payload=${DEPLOY_DIR_IMAGE}/${IMAGE_FULLNAME}.squashfs" --ondisk cd --label LIVECD

Felix Moessbauer

unread,
Jan 24, 2025, 7:36:13 AM1/24/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer
Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---

Felix Moessbauer

unread,
Jan 24, 2025, 7:36:13 AM1/24/25
to isar-...@googlegroups.com, clara.k...@siemens.com, florian...@siemens.com, jan.k...@siemens.com, Felix Moessbauer, Uladzimir Bely
It also introduces `test_system_running.sh` that can be used in other
run tests to check that all systemd services are started.

Co-Developed-by: Uladzimir Bely <ub...@ilbers.de>
Signed-off-by: Felix Moessbauer <felix.mo...@siemens.com>
---
testsuite/citest.py | 12 ++++++++++++
testsuite/scripts/test_system_running.sh | 22 ++++++++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100755 testsuite/scripts/test_system_running.sh

diff --git a/testsuite/citest.py b/testsuite/citest.py
index 82affb1a..ee965278 100755
--- a/testsuite/citest.py
+++ b/testsuite/citest.py
@@ -241,6 +241,7 @@ class NoCrossTest(CIBaseTest):
'mc:nanopi-neo-bookworm:isar-image-base',
'mc:qemuamd64-focal:isar-image-ci',
'mc:qemuamd64-bookworm:isar-image-ci',
+ 'mc:qemuamd64-iso-bookworm:isar-image-ci',
'mc:qemui386-bookworm:isar-image-base',
'mc:qemumipsel-bookworm:isar-image-ci',
'mc:hikey-bookworm:isar-image-base',
@@ -656,3 +657,14 @@ class VmBootTestFull(CIBaseTest):
self.init()
self.vm_start('arm64', 'bookworm', image='isar-image-ci',
script='test_prebuilt_containers.sh')
+
+ def test_amd64_bookworm_iso(self):
+ self.init()
+ self.vm_start('amd64-iso', 'bookworm', image='isar-image-ci',
+ keep = True
+ )
+
+ def test_amd64_bookworm_iso_system_check(self):
+ self.init()
+ self.vm_start('amd64-iso', 'bookworm', image='isar-image-ci',
+ script='test_system_running.sh 30')
diff --git a/testsuite/scripts/test_system_running.sh b/testsuite/scripts/test_system_running.sh
new file mode 100755
index 00000000..e4a6dca2
--- /dev/null
+++ b/testsuite/scripts/test_system_running.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Checks global status of all services
+
+set -e
+
+cnt=$1
+
+ret=1
+
+while [ 0${cnt} -gt 0 ]; do
+ if systemctl is-system-running; then
+ exit 0
+ else
+ ret=$?
+ fi
+
+ cnt=$((cnt - 1))
+ sleep 1
+done
+
+exit $ret
--
2.39.5

Uladzimir Bely

unread,
Feb 6, 2025, 2:33:56 AM2/6/25
to Felix Moessbauer, isar-...@googlegroups.com
On Fri, 2025-01-24 at 13:35 +0100, 'Felix Moessbauer' via isar-users
wrote:
>  create mode 100644 meta-isar/conf/multiconfig/qemuamd64-iso-
> bookworm.conf
>  create mode 100644 meta-isar/scripts/lib/wic/canned-wks/isohybrid-
> efi.wks.in
>  create mode 100644 meta/scripts/lib/wic/plugins/source/isoimage-
> isohybrid-isar.py
>  create mode 100755 testsuite/scripts/test_system_running.sh
>
> --
> 2.39.5
>

Applied to next, thanks.

--
Best regards,
Uladzimir.



Reply all
Reply to author
Forward
0 new messages