[v2] add simple installer to isar

Message ID 20240208202935.293080-1-Quirin.Gylstorff@siemens.com
State Superseded, archived
Headers show
Series [v2] add simple installer to isar | expand

Commit Message

Quirin Gylstorff Feb. 8, 2024, 8:28 p.m. UTC
From: Quirin Gylstorff <quirin.gylstorff@siemens.com>

This is a example to create installer image which contains another
target image. It uses a multiconfig aproach to seperate the settings
of the installer from the target settings.

Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
---
Changes v2:
 - Add dialog in case of multiple disk targets
 - Add dialog before starting the installtion
   This was added as there was no indication that an installation
   occurs
 - add `--use-uuid` for boot section in installer wic to avoid an error
   if the target disk is mount as /dev/sda
 - remove unnecessary /bin/sh from getty override


 kas/image/Kconfig                             | 14 +++
 kas/image/isar-image-installer.yaml           | 13 +++
 .../conf/multiconfig/installer-target.conf    |  6 ++
 .../conf/multiconfig/isar-installer.conf      |  5 +
 .../images/isar-image-installer.bb            | 17 ++++
 .../deploy-image/deploy-image_0.1.bb          | 21 +++++
 .../deploy-image/files/deploy-image-wic.sh    | 94 +++++++++++++++++++
 .../deploy-image/files/install.override.conf  |  5 +
 .../store-target-image_0.1.bb                 | 19 ++++
 .../lib/wic/canned-wks/installer-efi.wks.in   |  9 ++
 10 files changed, 203 insertions(+)
 create mode 100644 kas/image/isar-image-installer.yaml
 create mode 100644 meta-isar/conf/multiconfig/installer-target.conf
 create mode 100644 meta-isar/conf/multiconfig/isar-installer.conf
 create mode 100644 meta-isar/recipes-core/images/isar-image-installer.bb
 create mode 100644 meta-isar/recipes-installer/deploy-image/deploy-image_0.1.bb
 create mode 100644 meta-isar/recipes-installer/deploy-image/files/deploy-image-wic.sh
 create mode 100644 meta-isar/recipes-installer/deploy-image/files/install.override.conf
 create mode 100644 meta-isar/recipes-installer/store-target-image/store-target-image_0.1.bb
 create mode 100644 meta-isar/scripts/lib/wic/canned-wks/installer-efi.wks.in

Comments

MOESSBAUER, Felix Feb. 22, 2024, 11:46 a.m. UTC | #1
On Thu, 2024-02-08 at 21:28 +0100, 'Quirin Gylstorff' via isar-users
wrote:
> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> 
> This is a example to create installer image which contains another
> target image. It uses a multiconfig aproach to seperate the settings
> of the installer from the target settings.
> 
> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> ---
> Changes v2:
>  - Add dialog in case of multiple disk targets
>  - Add dialog before starting the installtion
>    This was added as there was no indication that an installation
>    occurs
>  - add `--use-uuid` for boot section in installer wic to avoid an
> error
>    if the target disk is mount as /dev/sda
>  - remove unnecessary /bin/sh from getty override
> 
> 
>  kas/image/Kconfig                             | 14 +++
>  kas/image/isar-image-installer.yaml           | 13 +++
>  .../conf/multiconfig/installer-target.conf    |  6 ++
>  .../conf/multiconfig/isar-installer.conf      |  5 +
>  .../images/isar-image-installer.bb            | 17 ++++
>  .../deploy-image/deploy-image_0.1.bb          | 21 +++++
>  .../deploy-image/files/deploy-image-wic.sh    | 94
> +++++++++++++++++++
>  .../deploy-image/files/install.override.conf  |  5 +
>  .../store-target-image_0.1.bb                 | 19 ++++
>  .../lib/wic/canned-wks/installer-efi.wks.in   |  9 ++
>  10 files changed, 203 insertions(+)
>  create mode 100644 kas/image/isar-image-installer.yaml
>  create mode 100644 meta-isar/conf/multiconfig/installer-target.conf
>  create mode 100644 meta-isar/conf/multiconfig/isar-installer.conf
>  create mode 100644 meta-isar/recipes-core/images/isar-image-
> installer.bb
>  create mode 100644 meta-isar/recipes-installer/deploy-image/deploy-
> image_0.1.bb
>  create mode 100644 meta-isar/recipes-installer/deploy-
> image/files/deploy-image-wic.sh
>  create mode 100644 meta-isar/recipes-installer/deploy-
> image/files/install.override.conf
>  create mode 100644 meta-isar/recipes-installer/store-target-
> image/store-target-image_0.1.bb
>  create mode 100644 meta-isar/scripts/lib/wic/canned-wks/installer-
> efi.wks.in
> 
> diff --git a/kas/image/Kconfig b/kas/image/Kconfig
> index 8e617386..be6d7019 100644
> --- a/kas/image/Kconfig
> +++ b/kas/image/Kconfig
> @@ -22,11 +22,25 @@ config IMAGE_DEBUG
>         help
>           This image includes some tools preinstalled useful for
> debug.
>  
> +menuconfig IMAGE_INSTALLER
> +       bool "Installer image"
> +       help
> +         This image contains a target image and scripts to install
> that target image on a device.
> +
> +config INSTALLER_TARGET_IMAGE
> +       string "Install Base or Debug image"
> +       default "isar-image-base"
> +       help
> +        This selects the target image of the installer:
> +         - isar-image-base
> +         - isar-image-debug
> +       depends on IMAGE_INSTALLER
>  endchoice
>  
>  config KAS_INCLUDE_IMAGE
>         string
>         default "kas/image/isar-image-base.yaml" if IMAGE_BASE
>         default "kas/image/isar-image-debug.yaml" if IMAGE_DEBUG
> +       default "kas/image/isar-image-installer.yaml" if

Currently, an image must be included. However, this installer would
also be useful without an image. Then, a user could manually copy in an
image file. Please add this option as well.

> IMAGE_INSTALLER
>  
>  endmenu
> diff --git a/kas/image/isar-image-installer.yaml b/kas/image/isar-
> image-installer.yaml
> new file mode 100644
> index 00000000..a2c466dd
> --- /dev/null
> +++ b/kas/image/isar-image-installer.yaml
> @@ -0,0 +1,13 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +header:
> +  version: 14
> +
> +target: mc:installer:isar-image-installer
> +
> +local_conf_header:
> +  installer_multiconfig: |
> +    BBMULTICONFIG += "installer installer-target"
> diff --git a/meta-isar/conf/multiconfig/installer-target.conf b/meta-
> isar/conf/multiconfig/installer-target.conf
> new file mode 100644
> index 00000000..254c91a6
> --- /dev/null
> +++ b/meta-isar/conf/multiconfig/installer-target.conf
> @@ -0,0 +1,6 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +IMAGE_FSTYPES += "wic.xz"
> diff --git a/meta-isar/conf/multiconfig/isar-installer.conf b/meta-
> isar/conf/multiconfig/isar-installer.conf
> new file mode 100644
> index 00000000..11afcb85
> --- /dev/null
> +++ b/meta-isar/conf/multiconfig/isar-installer.conf
> @@ -0,0 +1,5 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> diff --git a/meta-isar/recipes-core/images/isar-image-installer.bb
> b/meta-isar/recipes-core/images/isar-image-installer.bb
> new file mode 100644
> index 00000000..27de03d5
> --- /dev/null
> +++ b/meta-isar/recipes-core/images/isar-image-installer.bb
> @@ -0,0 +1,17 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +inherit image
> +DESCRIPTION = "Example of a ISAR based Installer Image"
> +
> +# Use variable to switch easily to another wks
> +INSTALLER_WKS_FILE ??= "installer-efi.wks.in"
> +WKS_FILE = "${INSTALLER_WKS_FILE}"
> +IMAGER_INSTALL:wic:append = " systemd-boot"
> +
> +IMAGE_INSTALL += "store-target-image"
> +IMAGE_INSTALL += "deploy-image"
> +
> +IMAGE_INSTALL:remove = "expand-on-first-boot"
> diff --git a/meta-isar/recipes-installer/deploy-image/deploy-
> image_0.1.bb b/meta-isar/recipes-installer/deploy-image/deploy-
> image_0.1.bb
> new file mode 100644
> index 00000000..9bf25445
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-image/deploy-image_0.1.bb
> @@ -0,0 +1,21 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +DESCRIPTION = "add target image to rootfs"
> +
> +
> +inherit dpkg-raw
> +
> +SRC_URI = "file://deploy-image-wic.sh \
> +           file://install.override.conf \
> +          "
> +DEPENDS = "store-target-image"
> +DEBIAN_DEPENDS = "store-target-image, bmap-tools, pv, dialog, util-
> linux, parted, fdisk, gdisk, pigz, xz-utils, pbzip2"
> +do_install[cleandirs] = "${D}/usr/bin/ \
> +                        
> ${D}/etc/systemd/system/getty@tty1.service.d/"

Please install to /usr/lib/systemd/...

> +do_install() {
> +  install -m 0755  ${WORKDIR}/deploy-image-wic.sh
> ${D}/usr/bin/deploy-image-wic.sh
> +  install -m 0755 ${WORKDIR}/install.override.conf
> ${D}/etc/systemd/system/getty@tty1.service.d/override.conf
> +}
> diff --git a/meta-isar/recipes-installer/deploy-image/files/deploy-
> image-wic.sh b/meta-isar/recipes-installer/deploy-image/files/deploy-
> image-wic.sh
> new file mode 100644
> index 00000000..6f1cf96a
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-image/files/deploy-image-
> wic.sh
> @@ -0,0 +1,94 @@
> +#!/usr/bin/env bash
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +DISK_IMAGE=$(find /install -type f -iname "*.wic*" -a -not -iname
> "*.wic.bmap")
> +DISK_BMAP=$(find /install -type f -iname "$DISK_IMAGE.bmap")
> +DISK_IMAGE_SIZE=$(cat /install/*_size)

Where does this file come from? Why not just measure the size or read
from the bmap?

> +if [ "$DISK_IMAGE_SIZE" -gt "$(( 4096 * 1024 * 1024 ))" ]; then
> +    echo "IMAGE_SIZE: '$DISK_IMAGE_SIZE' is to big for vfat"
> +fi
> +
> +# inspired by poky/meta/recipes-core/initrdscripts/files/install-
> efi.sh
> +
> +target_device_list=""
> +current_root_dev=$(grep "[[:blank:]]/[[:blank:]]" /proc/mounts | awk
> '{print $1}')
> +current_root_dev=${current_root_dev#\/dev/}
> +case $current_root_dev in
> +    mmcblk*)
> +    ;;
> +    nvme*)
> +    ;;
> +    *)
> +        current_root_dev=${current_root_dev%%[0-9]*}
> +    ;;
> +esac
> +
> +echo "Searching for target device..."
> +
> +devices=$(find /sys/block/ -type b,c,f,l -not -iname "mmcblk*" -
> printf "%f\n") || true
> +mmc_devices=$(find /sys/block/ -type b,c,f,l -iname "mmcblk[0-9]" -
> printf "%f\n") || true
> +devices="$devices $mmc_devices"
> +
> +for device in $devices; do
> +    case $device in
> +        loop*)
> +            # skip loop device
> +            ;;
> +        mtd*)
> +            ;;
> +        sr*)
> +            # skip CDROM device
> +            ;;
> +        ram*)
> +            # skip ram device
> +            ;;
> +        *)
> +            case $device in
> +                $current_root_dev*)
> +                # skip the device we are running from
> +                ;;
> +                *)
> +                    target_device_list="$target_device_list $device"
> +                ;;
> +            esac
> +            ;;
> +    esac
> +done
> +
> +if [ -z "${target_device_list}" ]; then
> +    dialog --msgbox "You need another device (besides the live
> device /dev/${current_root_dev}) to install the image. Installation
> aborted." 7 60
> +    exit 1
> +fi
> +
> +if [ "$(echo "$target_device_list" | wc -w)" -gt 1 ]; then
> +    array=()
> +    for target in $target_device_list; do
> +        array+=("$target" "/dev/$target")
> +    done
> +    TARGET_DEVICE=$(dialog --clear \
> +                --no-tags --menu "Select device to install
> $DISK_IMAGE" 10 60 3 \
> +                "${array[@]}" --output-fd 1)
> +
> +else
> +    TARGET_DEVICE=$(echo "$target_device_list" | tr -d " ")
> +fi
> +
> +dialog --msgbox "Start installing '$DISK_IMAGE' to
> '$TARGET_DEVICE'." 7 60
> +
> +set -e
> +bmap_options=""
> +if [ -z "$DISK_BMAP" ]; then
> +    bmap_options="--nobmap"
> +fi
> +if ! bmaptool copy "${bmap_options}" "$DISK_IMAGE"
> "/dev/${TARGET_DEVICE}" > /install/bmap.log 2>&1; then
> +    dialog --title "ERROR bmap failed with the following output" --
> textbox /install/bmap.log 24 140
> +    exit 1
> +fi
> +
> +umount /install
> +sync
> +dialog --title "Reboot" --msgbox "Installation is successful. System
> will be rebooted. Please remove the USB stick." 7 60
> +reboot
> diff --git a/meta-isar/recipes-installer/deploy-
> image/files/install.override.conf b/meta-isar/recipes-
> installer/deploy-image/files/install.override.conf
> new file mode 100644
> index 00000000..73874caa
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-
> image/files/install.override.conf
> @@ -0,0 +1,5 @@
> +[Service]
> +ExecStart=
> +ExecStart=/usr/bin/deploy-image-wic.sh
> +StandardInput=tty
> +StandardOutput=tty
> diff --git a/meta-isar/recipes-installer/store-target-image/store-
> target-image_0.1.bb b/meta-isar/recipes-installer/store-target-
> image/store-target-image_0.1.bb
> new file mode 100644
> index 00000000..feb3c6d7
> --- /dev/null
> +++ b/meta-isar/recipes-installer/store-target-image/store-target-
> image_0.1.bb
> @@ -0,0 +1,19 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +DESCRIPTION = "Add a given target image to rootfs"
> +
> +inherit dpkg-raw
> +
> +INSTALLER_TARGET_IMAGE ??= "isar-image-base"
> +IMG_DATA_FILE ??= "${INSTALLER_TARGET_IMAGE}-${DISTRO}-${MACHINE}"
> +IMG_DATA_POSTFIX ??= "wic.xz"
> +do_install[mcdepends] = "mc:installer:installer-
> target:${INSTALLER_TARGET_IMAGE}:do_image_wic"
> +do_install[cleandirs] = "${D}/install/"
> +do_install() {
> +  install -m 0600 
> ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX}
> ${D}/install/
> +  install -m 0600  ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.wic.bmap
> ${D}/install/
> +  echo $(du -b
> ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX} | awk
> '{print $1}') > ${D}/install/${IMG_DATA_FILE}_size
> +}
> diff --git a/meta-isar/scripts/lib/wic/canned-wks/installer-
> efi.wks.in b/meta-isar/scripts/lib/wic/canned-wks/installer-
> efi.wks.in
> new file mode 100644
> index 00000000..e2be17f1
> --- /dev/null
> +++ b/meta-isar/scripts/lib/wic/canned-wks/installer-efi.wks.in
> @@ -0,0 +1,9 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +bootloader --ptable gpt --timeout 3 --append "rootwait
> console=ttyS0,115200 console=tty0 earlyprintk"
> +part /boot --source bootimg-efi-isar --sourceparams "loader=systemd-
> boot" --label efi --part-type EF00 --align 1024 --use-uuid
> +part / --source rootfs --fstype ext4 --label installroot --align
> 1024 --use-uuid
> +part /install --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/install

Please use --change-directory=install instead of --rootfs-dir=. As we
use vfat and the installer is only able to deploy a single file, please
just use a fixed size of 4GB of that partition. By that, we can easily
manually copy in images.

Anyways, this installer would be a great addition to ISAR.

Felix

> --label INSTALLDATA --fstype=vfat --use-uuid --align 1024
> -- 
> 2.43.0
>
MOESSBAUER, Felix Feb. 22, 2024, 11:53 a.m. UTC | #2
On Thu, 2024-02-08 at 21:28 +0100, 'Quirin Gylstorff' via isar-users
wrote:
> From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> 
> This is a example to create installer image which contains another
> target image. It uses a multiconfig aproach to seperate the settings
> of the installer from the target settings.
> 
> Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
> ---
> Changes v2:
>  - Add dialog in case of multiple disk targets
>  - Add dialog before starting the installtion
>    This was added as there was no indication that an installation
>    occurs
>  - add `--use-uuid` for boot section in installer wic to avoid an
> error
>    if the target disk is mount as /dev/sda
>  - remove unnecessary /bin/sh from getty override
> 
> 
>  kas/image/Kconfig                             | 14 +++
>  kas/image/isar-image-installer.yaml           | 13 +++
>  .../conf/multiconfig/installer-target.conf    |  6 ++
>  .../conf/multiconfig/isar-installer.conf      |  5 +
>  .../images/isar-image-installer.bb            | 17 ++++
>  .../deploy-image/deploy-image_0.1.bb          | 21 +++++
>  .../deploy-image/files/deploy-image-wic.sh    | 94
> +++++++++++++++++++
>  .../deploy-image/files/install.override.conf  |  5 +
>  .../store-target-image_0.1.bb                 | 19 ++++
>  .../lib/wic/canned-wks/installer-efi.wks.in   |  9 ++
>  10 files changed, 203 insertions(+)
>  create mode 100644 kas/image/isar-image-installer.yaml
>  create mode 100644 meta-isar/conf/multiconfig/installer-target.conf
>  create mode 100644 meta-isar/conf/multiconfig/isar-installer.conf
>  create mode 100644 meta-isar/recipes-core/images/isar-image-
> installer.bb
>  create mode 100644 meta-isar/recipes-installer/deploy-image/deploy-
> image_0.1.bb
>  create mode 100644 meta-isar/recipes-installer/deploy-
> image/files/deploy-image-wic.sh
>  create mode 100644 meta-isar/recipes-installer/deploy-
> image/files/install.override.conf
>  create mode 100644 meta-isar/recipes-installer/store-target-
> image/store-target-image_0.1.bb
>  create mode 100644 meta-isar/scripts/lib/wic/canned-wks/installer-
> efi.wks.in
> 
> diff --git a/kas/image/Kconfig b/kas/image/Kconfig
> index 8e617386..be6d7019 100644
> --- a/kas/image/Kconfig
> +++ b/kas/image/Kconfig
> @@ -22,11 +22,25 @@ config IMAGE_DEBUG
>         help
>           This image includes some tools preinstalled useful for
> debug.
>  
> +menuconfig IMAGE_INSTALLER
> +       bool "Installer image"
> +       help
> +         This image contains a target image and scripts to install
> that target image on a device.
> +
> +config INSTALLER_TARGET_IMAGE
> +       string "Install Base or Debug image"
> +       default "isar-image-base"
> +       help
> +        This selects the target image of the installer:
> +         - isar-image-base
> +         - isar-image-debug
> +       depends on IMAGE_INSTALLER
>  endchoice
>  
>  config KAS_INCLUDE_IMAGE
>         string
>         default "kas/image/isar-image-base.yaml" if IMAGE_BASE
>         default "kas/image/isar-image-debug.yaml" if IMAGE_DEBUG
> +       default "kas/image/isar-image-installer.yaml" if
> IMAGE_INSTALLER
>  
>  endmenu
> diff --git a/kas/image/isar-image-installer.yaml b/kas/image/isar-
> image-installer.yaml
> new file mode 100644
> index 00000000..a2c466dd
> --- /dev/null
> +++ b/kas/image/isar-image-installer.yaml
> @@ -0,0 +1,13 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +header:
> +  version: 14
> +
> +target: mc:installer:isar-image-installer
> +
> +local_conf_header:
> +  installer_multiconfig: |
> +    BBMULTICONFIG += "installer installer-target"
> diff --git a/meta-isar/conf/multiconfig/installer-target.conf b/meta-
> isar/conf/multiconfig/installer-target.conf
> new file mode 100644
> index 00000000..254c91a6
> --- /dev/null
> +++ b/meta-isar/conf/multiconfig/installer-target.conf
> @@ -0,0 +1,6 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +IMAGE_FSTYPES += "wic.xz"

Please switch over to zstandard (zst), as compression and esp.
decompression is much faster and requires less memory.

Yocto also uses zst as default compression type for some time now.

Felix

> diff --git a/meta-isar/conf/multiconfig/isar-installer.conf b/meta-
> isar/conf/multiconfig/isar-installer.conf
> new file mode 100644
> index 00000000..11afcb85
> --- /dev/null
> +++ b/meta-isar/conf/multiconfig/isar-installer.conf
> @@ -0,0 +1,5 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> diff --git a/meta-isar/recipes-core/images/isar-image-installer.bb
> b/meta-isar/recipes-core/images/isar-image-installer.bb
> new file mode 100644
> index 00000000..27de03d5
> --- /dev/null
> +++ b/meta-isar/recipes-core/images/isar-image-installer.bb
> @@ -0,0 +1,17 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +inherit image
> +DESCRIPTION = "Example of a ISAR based Installer Image"
> +
> +# Use variable to switch easily to another wks
> +INSTALLER_WKS_FILE ??= "installer-efi.wks.in"
> +WKS_FILE = "${INSTALLER_WKS_FILE}"
> +IMAGER_INSTALL:wic:append = " systemd-boot"
> +
> +IMAGE_INSTALL += "store-target-image"
> +IMAGE_INSTALL += "deploy-image"
> +
> +IMAGE_INSTALL:remove = "expand-on-first-boot"
> diff --git a/meta-isar/recipes-installer/deploy-image/deploy-
> image_0.1.bb b/meta-isar/recipes-installer/deploy-image/deploy-
> image_0.1.bb
> new file mode 100644
> index 00000000..9bf25445
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-image/deploy-image_0.1.bb
> @@ -0,0 +1,21 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +DESCRIPTION = "add target image to rootfs"
> +
> +
> +inherit dpkg-raw
> +
> +SRC_URI = "file://deploy-image-wic.sh \
> +           file://install.override.conf \
> +          "
> +DEPENDS = "store-target-image"
> +DEBIAN_DEPENDS = "store-target-image, bmap-tools, pv, dialog, util-
> linux, parted, fdisk, gdisk, pigz, xz-utils, pbzip2"
> +do_install[cleandirs] = "${D}/usr/bin/ \
> +                        
> ${D}/etc/systemd/system/getty@tty1.service.d/"
> +do_install() {
> +  install -m 0755  ${WORKDIR}/deploy-image-wic.sh
> ${D}/usr/bin/deploy-image-wic.sh
> +  install -m 0755 ${WORKDIR}/install.override.conf
> ${D}/etc/systemd/system/getty@tty1.service.d/override.conf
> +}
> diff --git a/meta-isar/recipes-installer/deploy-image/files/deploy-
> image-wic.sh b/meta-isar/recipes-installer/deploy-image/files/deploy-
> image-wic.sh
> new file mode 100644
> index 00000000..6f1cf96a
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-image/files/deploy-image-
> wic.sh
> @@ -0,0 +1,94 @@
> +#!/usr/bin/env bash
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +DISK_IMAGE=$(find /install -type f -iname "*.wic*" -a -not -iname
> "*.wic.bmap")
> +DISK_BMAP=$(find /install -type f -iname "$DISK_IMAGE.bmap")
> +DISK_IMAGE_SIZE=$(cat /install/*_size)
> +if [ "$DISK_IMAGE_SIZE" -gt "$(( 4096 * 1024 * 1024 ))" ]; then
> +    echo "IMAGE_SIZE: '$DISK_IMAGE_SIZE' is to big for vfat"
> +fi
> +
> +# inspired by poky/meta/recipes-core/initrdscripts/files/install-
> efi.sh
> +
> +target_device_list=""
> +current_root_dev=$(grep "[[:blank:]]/[[:blank:]]" /proc/mounts | awk
> '{print $1}')
> +current_root_dev=${current_root_dev#\/dev/}
> +case $current_root_dev in
> +    mmcblk*)
> +    ;;
> +    nvme*)
> +    ;;
> +    *)
> +        current_root_dev=${current_root_dev%%[0-9]*}
> +    ;;
> +esac
> +
> +echo "Searching for target device..."
> +
> +devices=$(find /sys/block/ -type b,c,f,l -not -iname "mmcblk*" -
> printf "%f\n") || true
> +mmc_devices=$(find /sys/block/ -type b,c,f,l -iname "mmcblk[0-9]" -
> printf "%f\n") || true
> +devices="$devices $mmc_devices"
> +
> +for device in $devices; do
> +    case $device in
> +        loop*)
> +            # skip loop device
> +            ;;
> +        mtd*)
> +            ;;
> +        sr*)
> +            # skip CDROM device
> +            ;;
> +        ram*)
> +            # skip ram device
> +            ;;
> +        *)
> +            case $device in
> +                $current_root_dev*)
> +                # skip the device we are running from
> +                ;;
> +                *)
> +                    target_device_list="$target_device_list $device"
> +                ;;
> +            esac
> +            ;;
> +    esac
> +done
> +
> +if [ -z "${target_device_list}" ]; then
> +    dialog --msgbox "You need another device (besides the live
> device /dev/${current_root_dev}) to install the image. Installation
> aborted." 7 60
> +    exit 1
> +fi
> +
> +if [ "$(echo "$target_device_list" | wc -w)" -gt 1 ]; then
> +    array=()
> +    for target in $target_device_list; do
> +        array+=("$target" "/dev/$target")
> +    done
> +    TARGET_DEVICE=$(dialog --clear \
> +                --no-tags --menu "Select device to install
> $DISK_IMAGE" 10 60 3 \
> +                "${array[@]}" --output-fd 1)
> +
> +else
> +    TARGET_DEVICE=$(echo "$target_device_list" | tr -d " ")
> +fi
> +
> +dialog --msgbox "Start installing '$DISK_IMAGE' to
> '$TARGET_DEVICE'." 7 60
> +
> +set -e
> +bmap_options=""
> +if [ -z "$DISK_BMAP" ]; then
> +    bmap_options="--nobmap"
> +fi
> +if ! bmaptool copy "${bmap_options}" "$DISK_IMAGE"
> "/dev/${TARGET_DEVICE}" > /install/bmap.log 2>&1; then
> +    dialog --title "ERROR bmap failed with the following output" --
> textbox /install/bmap.log 24 140
> +    exit 1
> +fi
> +
> +umount /install
> +sync
> +dialog --title "Reboot" --msgbox "Installation is successful. System
> will be rebooted. Please remove the USB stick." 7 60
> +reboot
> diff --git a/meta-isar/recipes-installer/deploy-
> image/files/install.override.conf b/meta-isar/recipes-
> installer/deploy-image/files/install.override.conf
> new file mode 100644
> index 00000000..73874caa
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-
> image/files/install.override.conf
> @@ -0,0 +1,5 @@
> +[Service]
> +ExecStart=
> +ExecStart=/usr/bin/deploy-image-wic.sh
> +StandardInput=tty
> +StandardOutput=tty
> diff --git a/meta-isar/recipes-installer/store-target-image/store-
> target-image_0.1.bb b/meta-isar/recipes-installer/store-target-
> image/store-target-image_0.1.bb
> new file mode 100644
> index 00000000..feb3c6d7
> --- /dev/null
> +++ b/meta-isar/recipes-installer/store-target-image/store-target-
> image_0.1.bb
> @@ -0,0 +1,19 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +DESCRIPTION = "Add a given target image to rootfs"
> +
> +inherit dpkg-raw
> +
> +INSTALLER_TARGET_IMAGE ??= "isar-image-base"
> +IMG_DATA_FILE ??= "${INSTALLER_TARGET_IMAGE}-${DISTRO}-${MACHINE}"
> +IMG_DATA_POSTFIX ??= "wic.xz"
> +do_install[mcdepends] = "mc:installer:installer-
> target:${INSTALLER_TARGET_IMAGE}:do_image_wic"
> +do_install[cleandirs] = "${D}/install/"
> +do_install() {
> +  install -m 0600 
> ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX}
> ${D}/install/
> +  install -m 0600  ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.wic.bmap
> ${D}/install/
> +  echo $(du -b
> ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX} | awk
> '{print $1}') > ${D}/install/${IMG_DATA_FILE}_size
> +}
> diff --git a/meta-isar/scripts/lib/wic/canned-wks/installer-
> efi.wks.in b/meta-isar/scripts/lib/wic/canned-wks/installer-
> efi.wks.in
> new file mode 100644
> index 00000000..e2be17f1
> --- /dev/null
> +++ b/meta-isar/scripts/lib/wic/canned-wks/installer-efi.wks.in
> @@ -0,0 +1,9 @@
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +bootloader --ptable gpt --timeout 3 --append "rootwait
> console=ttyS0,115200 console=tty0 earlyprintk"
> +part /boot --source bootimg-efi-isar --sourceparams "loader=systemd-
> boot" --label efi --part-type EF00 --align 1024 --use-uuid
> +part / --source rootfs --fstype ext4 --label installroot --align
> 1024 --use-uuid
> +part /install --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/install -
> -label INSTALLDATA --fstype=vfat --use-uuid --align 1024
> -- 
> 2.43.0
>

Patch

diff --git a/kas/image/Kconfig b/kas/image/Kconfig
index 8e617386..be6d7019 100644
--- a/kas/image/Kconfig
+++ b/kas/image/Kconfig
@@ -22,11 +22,25 @@  config IMAGE_DEBUG
 	help
 	  This image includes some tools preinstalled useful for debug.
 
+menuconfig IMAGE_INSTALLER
+	bool "Installer image"
+	help
+	  This image contains a target image and scripts to install that target image on a device.
+
+config INSTALLER_TARGET_IMAGE
+	string "Install Base or Debug image"
+	default "isar-image-base"
+	help
+	 This selects the target image of the installer:
+	  - isar-image-base
+	  - isar-image-debug
+	depends on IMAGE_INSTALLER
 endchoice
 
 config KAS_INCLUDE_IMAGE
 	string
 	default "kas/image/isar-image-base.yaml" if IMAGE_BASE
 	default "kas/image/isar-image-debug.yaml" if IMAGE_DEBUG
+	default "kas/image/isar-image-installer.yaml" if IMAGE_INSTALLER
 
 endmenu
diff --git a/kas/image/isar-image-installer.yaml b/kas/image/isar-image-installer.yaml
new file mode 100644
index 00000000..a2c466dd
--- /dev/null
+++ b/kas/image/isar-image-installer.yaml
@@ -0,0 +1,13 @@ 
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+header:
+  version: 14
+
+target: mc:installer:isar-image-installer
+
+local_conf_header:
+  installer_multiconfig: |
+    BBMULTICONFIG += "installer installer-target"
diff --git a/meta-isar/conf/multiconfig/installer-target.conf b/meta-isar/conf/multiconfig/installer-target.conf
new file mode 100644
index 00000000..254c91a6
--- /dev/null
+++ b/meta-isar/conf/multiconfig/installer-target.conf
@@ -0,0 +1,6 @@ 
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+IMAGE_FSTYPES += "wic.xz"
diff --git a/meta-isar/conf/multiconfig/isar-installer.conf b/meta-isar/conf/multiconfig/isar-installer.conf
new file mode 100644
index 00000000..11afcb85
--- /dev/null
+++ b/meta-isar/conf/multiconfig/isar-installer.conf
@@ -0,0 +1,5 @@ 
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
diff --git a/meta-isar/recipes-core/images/isar-image-installer.bb b/meta-isar/recipes-core/images/isar-image-installer.bb
new file mode 100644
index 00000000..27de03d5
--- /dev/null
+++ b/meta-isar/recipes-core/images/isar-image-installer.bb
@@ -0,0 +1,17 @@ 
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+inherit image
+DESCRIPTION = "Example of a ISAR based Installer Image"
+
+# Use variable to switch easily to another wks
+INSTALLER_WKS_FILE ??= "installer-efi.wks.in"
+WKS_FILE = "${INSTALLER_WKS_FILE}"
+IMAGER_INSTALL:wic:append = " systemd-boot"
+
+IMAGE_INSTALL += "store-target-image"
+IMAGE_INSTALL += "deploy-image"
+
+IMAGE_INSTALL:remove = "expand-on-first-boot"
diff --git a/meta-isar/recipes-installer/deploy-image/deploy-image_0.1.bb b/meta-isar/recipes-installer/deploy-image/deploy-image_0.1.bb
new file mode 100644
index 00000000..9bf25445
--- /dev/null
+++ b/meta-isar/recipes-installer/deploy-image/deploy-image_0.1.bb
@@ -0,0 +1,21 @@ 
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+DESCRIPTION = "add target image to rootfs"
+
+
+inherit dpkg-raw
+
+SRC_URI = "file://deploy-image-wic.sh \
+           file://install.override.conf \
+          "
+DEPENDS = "store-target-image"
+DEBIAN_DEPENDS = "store-target-image, bmap-tools, pv, dialog, util-linux, parted, fdisk, gdisk, pigz, xz-utils, pbzip2"
+do_install[cleandirs] = "${D}/usr/bin/ \
+                         ${D}/etc/systemd/system/getty@tty1.service.d/"
+do_install() {
+  install -m 0755  ${WORKDIR}/deploy-image-wic.sh ${D}/usr/bin/deploy-image-wic.sh
+  install -m 0755 ${WORKDIR}/install.override.conf ${D}/etc/systemd/system/getty@tty1.service.d/override.conf
+}
diff --git a/meta-isar/recipes-installer/deploy-image/files/deploy-image-wic.sh b/meta-isar/recipes-installer/deploy-image/files/deploy-image-wic.sh
new file mode 100644
index 00000000..6f1cf96a
--- /dev/null
+++ b/meta-isar/recipes-installer/deploy-image/files/deploy-image-wic.sh
@@ -0,0 +1,94 @@ 
+#!/usr/bin/env bash
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+DISK_IMAGE=$(find /install -type f -iname "*.wic*" -a -not -iname "*.wic.bmap")
+DISK_BMAP=$(find /install -type f -iname "$DISK_IMAGE.bmap")
+DISK_IMAGE_SIZE=$(cat /install/*_size)
+if [ "$DISK_IMAGE_SIZE" -gt "$(( 4096 * 1024 * 1024 ))" ]; then
+    echo "IMAGE_SIZE: '$DISK_IMAGE_SIZE' is to big for vfat"
+fi
+
+# inspired by poky/meta/recipes-core/initrdscripts/files/install-efi.sh
+
+target_device_list=""
+current_root_dev=$(grep "[[:blank:]]/[[:blank:]]" /proc/mounts | awk '{print $1}')
+current_root_dev=${current_root_dev#\/dev/}
+case $current_root_dev in
+    mmcblk*)
+    ;;
+    nvme*)
+    ;;
+    *)
+        current_root_dev=${current_root_dev%%[0-9]*}
+    ;;
+esac
+
+echo "Searching for target device..."
+
+devices=$(find /sys/block/ -type b,c,f,l -not -iname "mmcblk*" -printf "%f\n") || true
+mmc_devices=$(find /sys/block/ -type b,c,f,l -iname "mmcblk[0-9]" -printf "%f\n") || true
+devices="$devices $mmc_devices"
+
+for device in $devices; do
+    case $device in
+        loop*)
+            # skip loop device
+            ;;
+        mtd*)
+            ;;
+        sr*)
+            # skip CDROM device
+            ;;
+        ram*)
+            # skip ram device
+            ;;
+        *)
+            case $device in
+                $current_root_dev*)
+                # skip the device we are running from
+                ;;
+                *)
+                    target_device_list="$target_device_list $device"
+                ;;
+            esac
+            ;;
+    esac
+done
+
+if [ -z "${target_device_list}" ]; then
+    dialog --msgbox "You need another device (besides the live device /dev/${current_root_dev}) to install the image. Installation aborted." 7 60
+    exit 1
+fi
+
+if [ "$(echo "$target_device_list" | wc -w)" -gt 1 ]; then
+    array=()
+    for target in $target_device_list; do
+        array+=("$target" "/dev/$target")
+    done
+    TARGET_DEVICE=$(dialog --clear \
+                --no-tags --menu "Select device to install $DISK_IMAGE" 10 60 3 \
+                "${array[@]}" --output-fd 1)
+
+else
+    TARGET_DEVICE=$(echo "$target_device_list" | tr -d " ")
+fi
+
+dialog --msgbox "Start installing '$DISK_IMAGE' to '$TARGET_DEVICE'." 7 60
+
+set -e
+bmap_options=""
+if [ -z "$DISK_BMAP" ]; then
+    bmap_options="--nobmap"
+fi
+if ! bmaptool copy "${bmap_options}" "$DISK_IMAGE" "/dev/${TARGET_DEVICE}" > /install/bmap.log 2>&1; then
+    dialog --title "ERROR bmap failed with the following output" --textbox /install/bmap.log 24 140
+    exit 1
+fi
+
+umount /install
+sync
+dialog --title "Reboot" --msgbox "Installation is successful. System will be rebooted. Please remove the USB stick." 7 60
+reboot
diff --git a/meta-isar/recipes-installer/deploy-image/files/install.override.conf b/meta-isar/recipes-installer/deploy-image/files/install.override.conf
new file mode 100644
index 00000000..73874caa
--- /dev/null
+++ b/meta-isar/recipes-installer/deploy-image/files/install.override.conf
@@ -0,0 +1,5 @@ 
+[Service]
+ExecStart=
+ExecStart=/usr/bin/deploy-image-wic.sh
+StandardInput=tty
+StandardOutput=tty
diff --git a/meta-isar/recipes-installer/store-target-image/store-target-image_0.1.bb b/meta-isar/recipes-installer/store-target-image/store-target-image_0.1.bb
new file mode 100644
index 00000000..feb3c6d7
--- /dev/null
+++ b/meta-isar/recipes-installer/store-target-image/store-target-image_0.1.bb
@@ -0,0 +1,19 @@ 
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+DESCRIPTION = "Add a given target image to rootfs"
+
+inherit dpkg-raw
+
+INSTALLER_TARGET_IMAGE ??= "isar-image-base"
+IMG_DATA_FILE ??= "${INSTALLER_TARGET_IMAGE}-${DISTRO}-${MACHINE}"
+IMG_DATA_POSTFIX ??= "wic.xz"
+do_install[mcdepends] = "mc:installer:installer-target:${INSTALLER_TARGET_IMAGE}:do_image_wic"
+do_install[cleandirs] = "${D}/install/"
+do_install() {
+  install -m 0600  ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX} ${D}/install/
+  install -m 0600  ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.wic.bmap ${D}/install/
+  echo $(du -b ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX} | awk '{print $1}') > ${D}/install/${IMG_DATA_FILE}_size
+}
diff --git a/meta-isar/scripts/lib/wic/canned-wks/installer-efi.wks.in b/meta-isar/scripts/lib/wic/canned-wks/installer-efi.wks.in
new file mode 100644
index 00000000..e2be17f1
--- /dev/null
+++ b/meta-isar/scripts/lib/wic/canned-wks/installer-efi.wks.in
@@ -0,0 +1,9 @@ 
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+bootloader --ptable gpt --timeout 3 --append "rootwait console=ttyS0,115200 console=tty0 earlyprintk"
+part /boot --source bootimg-efi-isar --sourceparams "loader=systemd-boot" --label efi --part-type EF00 --align 1024 --use-uuid
+part / --source rootfs --fstype ext4 --label installroot --align 1024 --use-uuid
+part /install --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/install --label INSTALLDATA --fstype=vfat --use-uuid --align 1024