[1/2] meta-isar: Added unattended mode for deploy-image-wic installer script.

Message ID 20241008102235.34078-2-alexander.heinisch@siemens.com
State Accepted, archived
Headers show
Series Added unattended mode for deploy-image-wic installer script. | expand

Commit Message

alexander.heinisch Oct. 8, 2024, 10:22 a.m. UTC
From: Alexander Heinisch <alexander.heinisch@siemens.com>

In some cases (e.g. automated mass rollouts for precomissioning devices)
it is valueable to not rely on a screen and a keyboard to deploy the
target images on the device.

Therefore, extended on the auto.install patch to allow for completely
unattended installations.

In addition to the auto.install file to provide configuration for the installer we added support
for the kernel cmdline.
 - installer.unattended
 - installer.image.uri ...file name of the image to be installed (parameter name uri chosen since we plan to support download of images in upcoming patches)
 - installer.target.dev ...target device name (e.g. /dev/sda) for the image to be installed to
 - installer.target.overwrite ...strategy how to handle target devices not empty (possible values: OVERWRITE - overwrite data on target | ABORT - abort installation if target not empty)

This introduces a **Breaking change!**

This patch changes behaviour since when auto.install is found
the script is assumed to run unattended. That means no dialogs are shown and no
user interaction is enforced! It also requires all the configurations to be in place
and valid when such file is provided!

Signed-off-by: Alexander Heinisch <alexander.heinisch@siemens.com>
---
 .../deploy-image/deploy-image_0.1.bb          |  7 +-
 .../files/{ => usr/bin}/deploy-image-wic.sh   | 76 ++++++++++-------
 .../usr/lib/deploy-image-wic/handle-config.sh | 83 +++++++++++++++++++
 3 files changed, 134 insertions(+), 32 deletions(-)
 rename meta-isar/recipes-installer/deploy-image/files/{ => usr/bin}/deploy-image-wic.sh (71%)
 mode change 100644 => 100755
 create mode 100644 meta-isar/recipes-installer/deploy-image/files/usr/lib/deploy-image-wic/handle-config.sh

Patch

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
index fe524e52..242ca88e 100644
--- a/meta-isar/recipes-installer/deploy-image/deploy-image_0.1.bb
+++ b/meta-isar/recipes-installer/deploy-image/deploy-image_0.1.bb
@@ -7,11 +7,14 @@  DESCRIPTION = "Install image to device"
 
 inherit dpkg-raw
 
-SRC_URI = "file://deploy-image-wic.sh \
+SRC_URI = "file://usr/bin/deploy-image-wic.sh \
+           file://usr/lib/deploy-image-wic/handle-config.sh \
           "
 DEBIAN_DEPENDS = "bmap-tools, pv, dialog, util-linux, parted, fdisk, gdisk, pigz, xz-utils, pbzip2, zstd"
 do_install[cleandirs] = "${D}/usr/bin/ \
+                         ${D}/usr/lib/deploy-image-wic \
                         "
 do_install() {
-  install -m 0755  ${WORKDIR}/deploy-image-wic.sh ${D}/usr/bin/deploy-image-wic.sh
+    install -m 0755  ${WORKDIR}/usr/bin/deploy-image-wic.sh ${D}/usr/bin/deploy-image-wic.sh
+    install -m 0755  ${WORKDIR}/usr/lib/deploy-image-wic/handle-config.sh ${D}/usr/lib/deploy-image-wic/handle-config.sh
 }
diff --git a/meta-isar/recipes-installer/deploy-image/files/deploy-image-wic.sh b/meta-isar/recipes-installer/deploy-image/files/usr/bin/deploy-image-wic.sh
old mode 100644
new mode 100755
similarity index 71%
rename from meta-isar/recipes-installer/deploy-image/files/deploy-image-wic.sh
rename to meta-isar/recipes-installer/deploy-image/files/usr/bin/deploy-image-wic.sh
index 95188fe3..108a5975
--- a/meta-isar/recipes-installer/deploy-image/files/deploy-image-wic.sh
+++ b/meta-isar/recipes-installer/deploy-image/files/usr/bin/deploy-image-wic.sh
@@ -6,21 +6,18 @@ 
 
 installdata=${INSTALL_DATA:-/install}
 
-AUTO_INSTALL=false
-OVERWRITE=
-
-if [ -f "$installdata/auto.install" ]; then
-    exec 3<"$installdata/auto.install"
-    read -r DISK_IMAGE <&3
-    read -r TARGET_DEVICE <&3
-    read -r OVERWRITE <&3
-    exec 3>&-
-    if [ ! -b ${TARGET_DEVICE} ]; then
-        dialog --msgbox "Target device is not a valid block device. Installation aborted." 6 60
-        exit 1
-    fi
-    AUTO_INSTALL=true
-else
+SCRIPT_DIR=$( dirname -- "$( readlink -f -- "$0"; )"; )
+
+. ${SCRIPT_DIR}/../lib/deploy-image-wic/handle-config.sh
+
+
+# Map config params
+AUTO_INSTALL=${installer_unattended}
+DISK_IMAGE=${installer_image_uri}
+TARGET_DEVICE=${installer_target_dev}
+OVERWRITE=${installer_target_overwrite}
+
+if ! $AUTO_INSTALL; then
     DISK_IMAGE=$(find "$installdata" -type f -iname "*.wic*" -a -not -iname "*.wic.bmap" -exec basename {} \;)
     if [ -z "$DISK_IMAGE" ] || [ ! -f "$installdata/$DISK_IMAGE" ]; then
         pushd "$installdata"
@@ -36,16 +33,14 @@  else
             fi
         fi
     fi
-fi
 
-if [ ! -f "$installdata/$DISK_IMAGE" ]; then
-    dialog --msgbox "Could not find an image to install. Installation aborted." 6 60
-    exit 1
-fi
-DISK_BMAP=$(find "$installdata" -type f -iname "${DISK_IMAGE%.wic*}.wic.bmap")
-# inspired by poky/meta/recipes-core/initrdscripts/files/install-efi.sh
+    if [ ! -f "$installdata/$DISK_IMAGE" ]; then
+        dialog --msgbox "Could not find an image to install. Installation aborted." 6 60
+        exit 1
+    fi
+    DISK_BMAP=$(find "$installdata" -type f -iname "${DISK_IMAGE%.wic*}.wic.bmap")
 
-if ! $AUTO_INSTALL; then
+    # inspired by poky/meta/recipes-core/initrdscripts/files/install-efi.sh
     target_device_list=""
     current_root_dev_type=$(findmnt / -o fstype -n)
     if [ ${current_root_dev_type} = "nfs" ]; then
@@ -126,25 +121,46 @@  if ! $AUTO_INSTALL; then
                 --yesno "Start installing\n'$DISK_IMAGE'\nto $TARGET_DEVICE (capacity: $TARGET_DEVICE_SIZE)" 7 60; then
         exit 0
     fi
+
+    # set absolute paths to be compatible with unattended mode
+    DISK_IMAGE="$installdata/$DISK_IMAGE"
+
+    if [ -z "$DISK_BMAP" ]; then
+        DISK_BMAP="$installdata/$DISK_BMAP"
+    fi
 fi
 
-if [ "$OVERWRITE" != "OVERWRITE" ] && ! cmp /dev/zero "$TARGET_DEVICE" -n 1M && \
-   ! dialog --defaultno \
-            --yesno "WARNING: Target device is not empty! Continue anyway?" 5 60; then
-    exit 0
+if ! cmp /dev/zero "$TARGET_DEVICE" -n 1M; then
+    if ! $AUTO_INSTALL && \
+       ! dialog --defaultno \
+                --yesno "WARNING: Target device is not empty! Continue anyway?" 5 60; then
+        exit 0
+    else
+        if [ "$OVERWRITE" != "OVERWRITE" ]; then
+            echo "Target device is not empty! -> Abort"
+            echo "If you want to override existing data set \"installer_target_overwrite=OVERWRITE\""
+        fi
+    fi
 fi
 
 bmap_options=""
 if [ -z "$DISK_BMAP" ]; then
     bmap_options="--nobmap"
 fi
-clear
-if ! bmaptool copy ${bmap_options} "$installdata/$DISK_IMAGE" "${TARGET_DEVICE}"; then
+
+if ! $AUTO_INSTALL; then
+    clear
+fi
+
+if ! bmaptool copy ${bmap_options} "$DISK_IMAGE" "${TARGET_DEVICE}"; then
     exit 1
 fi
 
 if ! $AUTO_INSTALL; then
     dialog --title "Reboot" \
-           --msgbox "Installation is successful. System will be rebooted. Please remove the USB stick." 6 60
+           --msgbox "Installation was successful. System will be rebooted. Please remove the USB stick." 6 60
+else
+    echo "Installation was successful."
 fi
+
 exit 0
diff --git a/meta-isar/recipes-installer/deploy-image/files/usr/lib/deploy-image-wic/handle-config.sh b/meta-isar/recipes-installer/deploy-image/files/usr/lib/deploy-image-wic/handle-config.sh
new file mode 100644
index 00000000..af37150e
--- /dev/null
+++ b/meta-isar/recipes-installer/deploy-image/files/usr/lib/deploy-image-wic/handle-config.sh
@@ -0,0 +1,83 @@ 
+#!/usr/bin/env bash
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2024
+#
+# SPDX-License-Identifier: MIT
+
+installer_unattended=false
+installer_image_uri=
+installer_target_dev=
+installer_target_overwrite=
+
+if [ -f "$installdata/auto.install" ]; then
+    exec 3<"$installdata/auto.install"
+    read -r installer_image_uri <&3
+    read -r installer_target_dev <&3
+    read -r installer_target_overwrite <&3
+    exec 3>&-
+
+    installer_unattended=true
+fi
+
+# But let kernel cmdline overrule
+for x in $(cat /proc/cmdline); do
+    case $x in
+        installer.unattended*)
+            installer_unattended=true
+        ;;
+        installer.image.uri=*)
+            installer_image_uri=${x#installer.image.uri=}
+            installer_unattended=true
+        ;;
+        installer.target.dev=*)
+            installer_target_dev=${x#installer.target.dev=}
+            installer_unattended=true
+        ;;
+        installer.target.overwrite*)
+            installer_target_overwrite="OVERWRITE"
+            installer_unattended=true
+        ;;
+    esac
+done
+
+## Check config
+all_values_set=false
+if [ -n "${installer_image_uri}" ] && [ -n "${installer_target_dev}" ] && [ -n "${installer_target_overwrite}" ]; then
+    all_values_set=true
+fi
+
+if ${installer_unattended} && ! ${all_values_set}; then
+    echo "When running in unattended mode all values needed for installation have to be set! -> Abort"
+    exit 1
+fi
+
+if ${installer_unattended}; then
+    echo "Got config:"
+    echo "  installer_unattended=${installer_unattended}"
+    echo "  installer_image_uri=${installer_image_uri}"
+    echo "  installer_target_dev=${installer_target_dev}"
+    echo "  installer_target_overwrite=${installer_target_overwrite}"
+
+    case ${installer_target_overwrite} in
+        OVERWRITE|ABORT)
+        ;;
+        *)
+            echo "When running in unattended mode only \"installer_target_overwrite=OVERWRITE | ABORT\" is valid! You specified \"${installer_target_overwrite}\" -> Abort"
+            exit 1
+        ;;
+    esac
+
+    if [ ! -b ${installer_target_dev} ]; then
+        echo "Target device \"${installer_target_dev}\" is not a valid block device. -> Abort"
+        exit 1
+    fi
+
+    if [ ! -f "${installer_image_uri}" ]; then
+        if [ ! -f "$installdata/${installer_image_uri}" ]; then
+            echo "Could not find image file ${installer_image_uri} nor $installdata/${installer_image_uri} to install. -> Abort"
+            exit 1
+        else
+            installer_image_uri=$installdata/${installer_image_uri}
+        fi
+    fi
+fi