[v3] add simple installer to isar

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

Commit Message

Quirin Gylstorff Feb. 22, 2024, 2:58 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 v3:
 - remove disk size
 - add menu to select disk image if no wic image was found
 - allow empty target this will
 - set INSTALLDATA partition size to 4G
 - use --change-directory in wks file

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                             |  17 +++
 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    | 107 ++++++++++++++++++
 .../deploy-image/files/install.override.conf  |   5 +
 .../store-target-image_0.1.bb                 |  23 ++++
 .../lib/wic/canned-wks/installer-efi.wks.in   |   9 ++
 10 files changed, 223 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 March 4, 2024, 4:32 p.m. UTC | #1
On Thu, 2024-02-22 at 15:58 +0100, Quirin Gylstorff 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 v3:
>  - remove disk size
>  - add menu to select disk image if no wic image was found
>  - allow empty target this will
>  - set INSTALLDATA partition size to 4G
>  - use --change-directory in wks file
> 
> 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                             |  17 +++
>  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    | 107
> ++++++++++++++++++
>  .../deploy-image/files/install.override.conf  |   5 +
>  .../store-target-image_0.1.bb                 |  23 ++++
>  .../lib/wic/canned-wks/installer-efi.wks.in   |   9 ++
>  10 files changed, 223 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..bc789064 100644
> --- a/kas/image/Kconfig
> +++ b/kas/image/Kconfig
> @@ -22,11 +22,28 @@ 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
> the 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
> +         If left empty it will generate a installer image without
> payload.
> +         The user of that image needs then to copy a image to the
> partition
> +         labeled INSTALLDATA.
> +       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..d987c5d0
> --- /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.zst"
> 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..ff5a9b4f
> --- /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, zstd"
> +do_install[cleandirs] = "${D}/usr/bin/ \
> +                        
> ${D}/usr/lib/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}/usr/lib/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..a3803302
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-image/files/deploy-image-
> wic.sh
> @@ -0,0 +1,107 @@
> +#!/usr/bin/env bash
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +installdata=${INSTALL_DATA:-/install}
> +
> +DISK_IMAGE=$(find "$installdata" -type f -iname "*.wic*" -a -not -
> iname "*.wic.bmap")
> +if [ -z "$DISK_IMAGE" ]; then
> +    pushd "$installdata"
> +    shopt -s nullglob
> +    array=(*)
> +    shopt -u nullglob
> +    DISK_IMAGE=$(dialog --clear \
> +                --no-tags --menu "Select image to be installed" 10
> 60 3 \
> +                "${array[@]}" --output-fd 1)
> +    popd
> +fi
> +if [ ! -f "$DISK_IMAGE" ]; then
> +    dialog --msgbox "Could not find an image to install.
> Installation aborted." 7 60
> +    exit 1
> +fi
> +DISK_BMAP=$(find "$installdata" -type f -iname "$DISK_IMAGE.bmap")
> +# 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}" > "$installdata"/bmap.log 2>&1; then
> +    dialog --title "ERROR bmap failed with the following output" --
> textbox "$installdata"/bmap.log 24 140
> +    exit 1
> +fi
> +
> +# we need to umount before reboot to avoid
> +# data corruption due to the use of vfat.
> +umount "$installdata"
> +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..9150ce79
> --- /dev/null
> +++ b/meta-isar/recipes-installer/store-target-image/store-target-
> image_0.1.bb
> @@ -0,0 +1,23 @@
> +# 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

Do we really need to do this via a package? This requires a lot of
duplicated resources:

- re-compress potentially gigabytes of data with gz
- upload this package into the apt cache and to sstate

IMHO it would be better to deploy directly into the rootfs.

+ Adriaan

Felix

> +
> +INSTALLER_TARGET_IMAGE ??= "isar-image-base"
> +IMG_DATA_FILE ??= "${INSTALLER_TARGET_IMAGE}-${DISTRO}-${MACHINE}"
> +IMG_DATA_POSTFIX ??= "wic.zst"
> +do_install[mcdepends] = "${@ 'mc:installer:installer-target:' +
> d.getVar('INSTALLER_TARGET_IMAGE') + ':do_image_wic' if
> d.getVar('INSTALLER_TARGET_IMAGE') else ''}"
> +do_install[cleandirs] = "${D}/install/"
> +do_install() {
> +  if [ -f ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX}
> ]; then
> +    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/
> +  else
> +    # mcopy cannot handle .keep or empty directory , therefore use
> visible file
> +    touch ${D}/install/keep
> +  fi
> +}
> 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..daaec3f6
> --- /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 --change-directory=install --label
> INSTALLDATA --size 4G --fstype=vfat --use-uuid --align 1024
MOESSBAUER, Felix March 5, 2024, 8:24 a.m. UTC | #2
On Thu, 2024-02-22 at 15:58 +0100, Quirin Gylstorff 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 v3:
>  - remove disk size
>  - add menu to select disk image if no wic image was found
>  - allow empty target this will
>  - set INSTALLDATA partition size to 4G
>  - use --change-directory in wks file
> 
> 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                             |  17 +++
>  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    | 107
> ++++++++++++++++++
>  .../deploy-image/files/install.override.conf  |   5 +
>  .../store-target-image_0.1.bb                 |  23 ++++
>  .../lib/wic/canned-wks/installer-efi.wks.in   |   9 ++
>  10 files changed, 223 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..bc789064 100644
> --- a/kas/image/Kconfig
> +++ b/kas/image/Kconfig
> @@ -22,11 +22,28 @@ 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
> the 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
> +         If left empty it will generate a installer image without
> payload.
> +         The user of that image needs then to copy a image to the
> partition
> +         labeled INSTALLDATA.
> +       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..d987c5d0
> --- /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.zst"
> 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..ff5a9b4f
> --- /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, zstd"
> +do_install[cleandirs] = "${D}/usr/bin/ \
> +                        
> ${D}/usr/lib/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}/usr/lib/systemd/system/getty@tty1.service.d/override.conf

Please also enable this on the ttyS0:

+ install -m 0755 ${WORKDIR}/install.override.conf
${D}/usr/lib/systemd/system/serial-getty@ttyS0.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..a3803302
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-image/files/deploy-image-
> wic.sh
> @@ -0,0 +1,107 @@
> +#!/usr/bin/env bash
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +installdata=${INSTALL_DATA:-/install}
> +
> +DISK_IMAGE=$(find "$installdata" -type f -iname "*.wic*" -a -not -
> iname "*.wic.bmap")
> +if [ -z "$DISK_IMAGE" ]; then
> +    pushd "$installdata"
> +    shopt -s nullglob
> +    array=(*)
> +    shopt -u nullglob
> +    DISK_IMAGE=$(dialog --clear \
> +                --no-tags --menu "Select image to be installed" 10
> 60 3 \
> +                "${array[@]}" --output-fd 1)
> +    popd
> +fi
> +if [ ! -f "$DISK_IMAGE" ]; then
> +    dialog --msgbox "Could not find an image to install.
> Installation aborted." 7 60
> +    exit 1
> +fi
> +DISK_BMAP=$(find "$installdata" -type f -iname "$DISK_IMAGE.bmap")
> +# 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)

This information is useless, as the user cannot know how the devices
are enumerated. At least the device size and maybe vendor should be
shown to let the user select the correct device.

Please also add an exit button if the user does not want to install
(instead of forcing him to run CTRL-C).

> +
> +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}" > "$installdata"/bmap.log 2>&1; then
> +    dialog --title "ERROR bmap failed with the following output" --
> textbox "$installdata"/bmap.log 24 140
> +    exit 1
> +fi

By this no progress is shown. I played around with --psplash-pipe and
dialog --gauge, but unfortunately this is broken till 3.7 (due to a bug
in bmap-tools). How about leaving the dialog and just showing the
output of the bmaptool?

Felix

> +
> +# we need to umount before reboot to avoid
> +# data corruption due to the use of vfat.
> +umount "$installdata"
> +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..9150ce79
> --- /dev/null
> +++ b/meta-isar/recipes-installer/store-target-image/store-target-
> image_0.1.bb
> @@ -0,0 +1,23 @@
> +# 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.zst"
> +do_install[mcdepends] = "${@ 'mc:installer:installer-target:' +
> d.getVar('INSTALLER_TARGET_IMAGE') + ':do_image_wic' if
> d.getVar('INSTALLER_TARGET_IMAGE') else ''}"
> +do_install[cleandirs] = "${D}/install/"
> +do_install() {
> +  if [ -f ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX}
> ]; then
> +    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/
> +  else
> +    # mcopy cannot handle .keep or empty directory , therefore use
> visible file
> +    touch ${D}/install/keep
> +  fi
> +}
> 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..daaec3f6
> --- /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 --change-directory=install --label
> INSTALLDATA --size 4G --fstype=vfat --use-uuid --align 1024
MOESSBAUER, Felix March 6, 2024, 12:20 p.m. UTC | #3
On Thu, 2024-02-22 at 15:58 +0100, Quirin Gylstorff 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 v3:
>  - remove disk size
>  - add menu to select disk image if no wic image was found
>  - allow empty target this will
>  - set INSTALLDATA partition size to 4G
>  - use --change-directory in wks file
> 
> 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                             |  17 +++
>  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    | 107
> ++++++++++++++++++
>  .../deploy-image/files/install.override.conf  |   5 +
>  .../store-target-image_0.1.bb                 |  23 ++++
>  .../lib/wic/canned-wks/installer-efi.wks.in   |   9 ++
>  10 files changed, 223 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..bc789064 100644
> --- a/kas/image/Kconfig
> +++ b/kas/image/Kconfig
> @@ -22,11 +22,28 @@ 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
> the 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
> +         If left empty it will generate a installer image without
> payload.
> +         The user of that image needs then to copy a image to the
> partition
> +         labeled INSTALLDATA.
> +       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"

"installer" does not exist. Should it be "isar-installer"?

> diff --git a/meta-isar/conf/multiconfig/installer-target.conf b/meta-
> isar/conf/multiconfig/installer-target.conf
> new file mode 100644
> index 00000000..d987c5d0
> --- /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.zst"

This only works for a >=bookworm installer, which is sometimes tricky
to achieve if a BSP is needed for the machine. E.g. for some arm
machines, we still have bullseye only BSPs.
In case zstd is not supported by bmaptool, a completely misleading
error message is printed, as reported in [1].

We better use the following:

TARGET_IMAGE_FSTYPE = "wic.zst"
TARGET_IMAGE_FSTYPE:buster = "wic.xz"
TARGET_IMAGE_FSTYPE:bullseye = "wic.xz"

IMAGE_FSTYPES += "${TARGET_IMAGE_FSTYPE}"

[1] https://github.com/intel/bmap-tools/issues/132

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..ff5a9b4f
> --- /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, zstd"
> +do_install[cleandirs] = "${D}/usr/bin/ \
> +                        
> ${D}/usr/lib/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}/usr/lib/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..a3803302
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-image/files/deploy-image-
> wic.sh
> @@ -0,0 +1,107 @@
> +#!/usr/bin/env bash
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +installdata=${INSTALL_DATA:-/install}
> +
> +DISK_IMAGE=$(find "$installdata" -type f -iname "*.wic*" -a -not -
> iname "*.wic.bmap")
> +if [ -z "$DISK_IMAGE" ]; then
> +    pushd "$installdata"
> +    shopt -s nullglob
> +    array=(*)
> +    shopt -u nullglob
> +    DISK_IMAGE=$(dialog --clear \
> +                --no-tags --menu "Select image to be installed" 10
> 60 3 \
> +                "${array[@]}" --output-fd 1)
> +    popd
> +fi
> +if [ ! -f "$DISK_IMAGE" ]; then
> +    dialog --msgbox "Could not find an image to install.
> Installation aborted." 7 60
> +    exit 1
> +fi
> +DISK_BMAP=$(find "$installdata" -type f -iname "$DISK_IMAGE.bmap")
> +# 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}" > "$installdata"/bmap.log 2>&1; then
> +    dialog --title "ERROR bmap failed with the following output" --
> textbox "$installdata"/bmap.log 24 140
> +    exit 1
> +fi
> +
> +# we need to umount before reboot to avoid
> +# data corruption due to the use of vfat.
> +umount "$installdata"
> +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..9150ce79
> --- /dev/null
> +++ b/meta-isar/recipes-installer/store-target-image/store-target-
> image_0.1.bb
> @@ -0,0 +1,23 @@
> +# 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.zst"
> +do_install[mcdepends] = "${@ 'mc:installer:installer-target:' +
> d.getVar('INSTALLER_TARGET_IMAGE') + ':do_image_wic' if
> d.getVar('INSTALLER_TARGET_IMAGE') else ''}"
> +do_install[cleandirs] = "${D}/install/"
> +do_install() {
> +  if [ -f ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX}
> ]; then
> +    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/
> +  else
> +    # mcopy cannot handle .keep or empty directory , therefore use
> visible file
> +    touch ${D}/install/keep
> +  fi
> +}
> 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..daaec3f6
> --- /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 --change-directory=install --label
> INSTALLDATA --size 4G --fstype=vfat --use-uuid --align 1024
MOESSBAUER, Felix March 7, 2024, 10:44 a.m. UTC | #4
On Thu, 2024-02-22 at 15:58 +0100, Quirin Gylstorff 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 v3:
>  - remove disk size
>  - add menu to select disk image if no wic image was found
>  - allow empty target this will
>  - set INSTALLDATA partition size to 4G
>  - use --change-directory in wks file
> 
> 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                             |  17 +++
>  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    | 107
> ++++++++++++++++++
>  .../deploy-image/files/install.override.conf  |   5 +
>  .../store-target-image_0.1.bb                 |  23 ++++
>  .../lib/wic/canned-wks/installer-efi.wks.in   |   9 ++
>  10 files changed, 223 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..bc789064 100644
> --- a/kas/image/Kconfig
> +++ b/kas/image/Kconfig
> @@ -22,11 +22,28 @@ 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
> the 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
> +         If left empty it will generate a installer image without
> payload.
> +         The user of that image needs then to copy a image to the
> partition
> +         labeled INSTALLDATA.
> +       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..d987c5d0
> --- /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.zst"
> 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..ff5a9b4f
> --- /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, zstd"
> +do_install[cleandirs] = "${D}/usr/bin/ \
> +                        
> ${D}/usr/lib/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}/usr/lib/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..a3803302
> --- /dev/null
> +++ b/meta-isar/recipes-installer/deploy-image/files/deploy-image-
> wic.sh
> @@ -0,0 +1,107 @@
> +#!/usr/bin/env bash
> +# This software is a part of ISAR.
> +# Copyright (C) Siemens AG, 2024
> +#
> +# SPDX-License-Identifier: MIT
> +
> +installdata=${INSTALL_DATA:-/install}
> +
> +DISK_IMAGE=$(find "$installdata" -type f -iname "*.wic*" -a -not -
> iname "*.wic.bmap")
> +if [ -z "$DISK_IMAGE" ]; then
> +    pushd "$installdata"
> +    shopt -s nullglob
> +    array=(*)
> +    shopt -u nullglob
> +    DISK_IMAGE=$(dialog --clear \
> +                --no-tags --menu "Select image to be installed" 10
> 60 3 \
> +                "${array[@]}" --output-fd 1)
> +    popd
> +fi
> +if [ ! -f "$DISK_IMAGE" ]; then
> +    dialog --msgbox "Could not find an image to install.
> Installation aborted." 7 60
> +    exit 1
> +fi
> +DISK_BMAP=$(find "$installdata" -type f -iname "$DISK_IMAGE.bmap")
> +# 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}" > "$installdata"/bmap.log 2>&1; then
> +    dialog --title "ERROR bmap failed with the following output" --
> textbox "$installdata"/bmap.log 24 140
> +    exit 1
> +fi
> +
> +# we need to umount before reboot to avoid
> +# data corruption due to the use of vfat.
> +umount "$installdata"
> +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..9150ce79
> --- /dev/null
> +++ b/meta-isar/recipes-installer/store-target-image/store-target-
> image_0.1.bb
> @@ -0,0 +1,23 @@
> +# 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.zst"
> +do_install[mcdepends] = "${@ 'mc:installer:installer-target:' +
> d.getVar('INSTALLER_TARGET_IMAGE') + ':do_image_wic' if
> d.getVar('INSTALLER_TARGET_IMAGE') else ''}"
> +do_install[cleandirs] = "${D}/install/"
> +do_install() {
> +  if [ -f ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX}
> ]; then
> +    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/
> +  else
> +    # mcopy cannot handle .keep or empty directory , therefore use
> visible file
> +    touch ${D}/install/keep
> +  fi
> +}
> 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..daaec3f6
> --- /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

We need to exclude the /install folder here, otherwise the installer
will contain the payload twice.

Felix

> +part /install --source rootfs --change-directory=install --label
> INSTALLDATA --size 4G --fstype=vfat --use-uuid --align 1024

Patch

diff --git a/kas/image/Kconfig b/kas/image/Kconfig
index 8e617386..bc789064 100644
--- a/kas/image/Kconfig
+++ b/kas/image/Kconfig
@@ -22,11 +22,28 @@  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 the 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
+	  If left empty it will generate a installer image without payload.
+	  The user of that image needs then to copy a image to the partition
+	  labeled INSTALLDATA.
+	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..d987c5d0
--- /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.zst"
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..ff5a9b4f
--- /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, zstd"
+do_install[cleandirs] = "${D}/usr/bin/ \
+                         ${D}/usr/lib/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}/usr/lib/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..a3803302
--- /dev/null
+++ b/meta-isar/recipes-installer/deploy-image/files/deploy-image-wic.sh
@@ -0,0 +1,107 @@ 
+#!/usr/bin/env bash
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+installdata=${INSTALL_DATA:-/install}
+
+DISK_IMAGE=$(find "$installdata" -type f -iname "*.wic*" -a -not -iname "*.wic.bmap")
+if [ -z "$DISK_IMAGE" ]; then
+    pushd "$installdata"
+    shopt -s nullglob
+    array=(*)
+    shopt -u nullglob
+    DISK_IMAGE=$(dialog --clear \
+                --no-tags --menu "Select image to be installed" 10 60 3 \
+                "${array[@]}" --output-fd 1)
+    popd
+fi
+if [ ! -f "$DISK_IMAGE" ]; then
+    dialog --msgbox "Could not find an image to install. Installation aborted." 7 60
+    exit 1
+fi
+DISK_BMAP=$(find "$installdata" -type f -iname "$DISK_IMAGE.bmap")
+# 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}" > "$installdata"/bmap.log 2>&1; then
+    dialog --title "ERROR bmap failed with the following output" --textbox "$installdata"/bmap.log 24 140
+    exit 1
+fi
+
+# we need to umount before reboot to avoid
+# data corruption due to the use of vfat.
+umount "$installdata"
+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..9150ce79
--- /dev/null
+++ b/meta-isar/recipes-installer/store-target-image/store-target-image_0.1.bb
@@ -0,0 +1,23 @@ 
+# 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.zst"
+do_install[mcdepends] = "${@ 'mc:installer:installer-target:' + d.getVar('INSTALLER_TARGET_IMAGE') + ':do_image_wic' if d.getVar('INSTALLER_TARGET_IMAGE') else ''}"
+do_install[cleandirs] = "${D}/install/"
+do_install() {
+  if [ -f ${DEPLOY_DIR_IMAGE}/${IMG_DATA_FILE}.${IMG_DATA_POSTFIX} ]; then
+    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/
+  else
+    # mcopy cannot handle .keep or empty directory , therefore use visible file
+    touch ${D}/install/keep
+  fi
+}
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..daaec3f6
--- /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 --change-directory=install --label INSTALLDATA --size 4G --fstype=vfat --use-uuid --align 1024