From: "'Kasturi shekar' via isar-users" <isar-users@googlegroups.com>
To: isar-users@googlegroups.com
Cc: "kasturi.shekar" <kasturi.shekar@siemens.com>
Subject: [PATCH 2/4] installer: extract attended UI to installer_ui.sh
Date: Mon, 27 Apr 2026 12:09:54 +0530 [thread overview]
Message-ID: <20260427063957.603123-3-kasturi.shekar@siemens.com> (raw)
In-Reply-To: <20260427063957.603123-1-kasturi.shekar@siemens.com>
From: "kasturi.shekar" <kasturi.shekar@siemens.com>
Move attended dialog interactions into installer_ui.sh
The new UI module provides:
- image selection menu
- target device selection menu
- install and overwrite confirmation dialogs
- error and info dialogs
- attended progress gauge hooks
Signed-off-by: kasturi.shekar <kasturi.shekar@siemens.com>
---
.../files/usr/bin/installer_ui.sh | 217 +++++++++++++-----
1 file changed, 161 insertions(+), 56 deletions(-)
mode change 100755 => 100644 meta-isar/recipes-installer/deploy-image/files/usr/bin/installer_ui.sh
diff --git a/meta-isar/recipes-installer/deploy-image/files/usr/bin/installer_ui.sh b/meta-isar/recipes-installer/deploy-image/files/usr/bin/installer_ui.sh
old mode 100755
new mode 100644
index 33685c6f..9d3ba5de
--- a/meta-isar/recipes-installer/deploy-image/files/usr/bin/installer_ui.sh
+++ b/meta-isar/recipes-installer/deploy-image/files/usr/bin/installer_ui.sh
@@ -1,86 +1,191 @@
#!/usr/bin/env bash
+# This software is a part of ISAR.
+# Copyright (C) Siemens AG, 2026
#
-# installer_ui.sh — Attended installer frontend
-# ------------------------------------------------
+# SPDX-License-Identifier: MIT
-SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
-INSTALL_DATA=${INSTALL_DATA:-./install}
+#--------------------------------------------------------------------------
+# installer_ui.sh - Frontend/UI helpers for isar installer.
+#
+# This file is intentionally UI-only:
+# - dialog menus and message boxes
+# - attended confirmations
+# - user abort countdown handling
+#--------------------------------------------------------------------------
+UI_GAUGE_PID=""
+
+#--------------------------------------------------------------------------
+# ui_show_error <message>
+#
+# Displays an error dialog in attended mode.
+#--------------------------------------------------------------------------
+ui_show_error() {
+ local message="$1"
+ dialog --msgbox "$message" 6 60
+}
-# Backend APIs
-. "$SCRIPT_DIR/sys_api.sh"
+#--------------------------------------------------------------------------
+# ui_show_info <message>
+#
+# Displays an informational dialog in attended mode.
+#--------------------------------------------------------------------------
+ui_show_info() {
+ local message="$1"
+ dialog --msgbox "$message" 6 60
+}
+
+#--------------------------------------------------------------------------
+# ui_countdown_allow_attended_switch <seconds> <abort_file>
+#
+# In unattended mode, this gives users a chance to switch to attended
+# mode by pressing any key. Returns 0 when attended mode should be
+# used, and 1 otherwise.
+#--------------------------------------------------------------------------
+ui_countdown_allow_attended_switch() {
+ local timeout="$1"
+ local abort_file="$2"
+ local i
+
+ # Countdown loop prints a message once per second and accepts a key press.
+ # If any key is pressed, create the abort trigger file for the caller.
+ for ((i=timeout; i>0; i--)); do
+ echo -ne "\rUnattended installation will start in $i seconds. Press any key to switch to attended mode..."
+
+ if [ -f "$abort_file" ] || read -n 1 -t 1; then
+ touch "$abort_file"
+ echo
+ return 0
+ fi
+ done
-# ------------------------------------------------
-# Helpers
-# ------------------------------------------------
-die() {
- dialog --msgbox "$1" 6 60
- exit 1
+ echo
+ return 1
}
-# ------------------------------------------------
-# UI: Select image
-# ------------------------------------------------
-ui_select_image() {
- local images json list=()
+#--------------------------------------------------------------------------
+# ui_select_image_menu <install_data_dir>
+#
+# Uses sys_list_installable_entries backend API and returns selected
+# relative image path on stdout.
+#--------------------------------------------------------------------------
+ui_select_image_menu() {
+ local install_data_dir="$1"
+ local list=()
+ local entry
+ local selected
- # On failure, show error dialog and exit
- json=$(sys_locate_disk_images search_path="$INSTALL_DATA") || \
- die "No installable images found in $INSTALL_DATA"
+ while IFS= read -r entry; do
+ [ -n "$entry" ] || continue
+ list+=("$entry" "$entry")
+ done < <(sys_list_installable_entries "$install_data_dir")
- # Extract image paths from JSON
- images=$(echo "$json" | sed -n 's/.*"images":\[\(.*\)\].*/\1/p' | tr -d '"' | tr ',' '\n')
+ if [ "${#list[@]}" -eq 0 ]; then
+ return 1
+ fi
- # Building dialog menu entries
- for img in $images; do
- base=$(basename "$img")
- list+=("$img" "$base")
- done
+ selected=$(dialog --no-tags \
+ --menu "Select image to be installed" 12 70 6 \
+ "${list[@]}" --output-fd 1) || return 2
- # Display menu and capture selection
- INSTALL_IMAGE=$(dialog --no-tags \
- --menu "Select image to install" 10 70 5 \
- "${list[@]}" \
- --output-fd 1) || exit 0
+ echo "$selected"
+ return 0
}
-# ------------------------------------------------
-# UI: Select target device
-# ------------------------------------------------
-ui_select_target_device() {
+#--------------------------------------------------------------------------
+# ui_select_target_device_menu <device...>
+#
+# Displays candidate target devices and returns selected /dev path.
+#--------------------------------------------------------------------------
+ui_select_target_device_menu() {
local list=()
+ local target
+ local target_size
+ local state
+ local selected
- devices=$(sys_list_valid_target_devices) || \
- die "No valid target devices found"
+ for target in "$@"; do
+ [ -b "$target" ] || continue
- for dev in $devices; do
- [ -b "$dev" ] || continue
+ target_size=$(sys_device_size "$target")
+ [ -n "$target_size" ] || target_size="unknown"
- size=$(lsblk --nodeps --noheadings -o SIZE "$dev" 2>/dev/null | tr -d " ")
- [ -z "$size" ] && size="unknown"
-
- if cmp /dev/zero "$dev" -n 1M >/dev/null 2>&1; then
+ # Indicate whether the selected device is already empty, to help users
+ # avoid accidental overwrite of data.
+ if sys_device_is_empty "$target"; then
state="empty"
else
state="contains data"
fi
- list+=("$dev" "$dev ($size, $state)")
+ list+=("$target" "$target ($target_size, $state)")
done
- if [ "${#list[@]}" -lt 2 ]; then
- die "no installable target devices available"
+ if [ "${#list[@]}" -eq 0 ]; then
+ return 1
fi
- TARGET_DEVICE=$(dialog --no-tags \
- --menu "Select target device" 10 70 6 \
- "${list[@]}" \
- --output-fd 1) || exit 0
+ selected=$(dialog --no-tags \
+ --menu "Select device to install image to" 12 70 6 \
+ "${list[@]}" --output-fd 1) || return 2
+
+ echo "$selected"
+ return 0
}
-run_interactive_installer() {
- clear
- ui_select_image
- ui_select_target_device
+#--------------------------------------------------------------------------
+# ui_confirm_install <image_path> <target_device> <target_size>
+#
+# Returns:
+# 0 when user confirms, 1 when canceled.
+#--------------------------------------------------------------------------
+ui_confirm_install() {
+ local image_path="$1"
+ local target_device="$2"
+ local target_size="$3"
+
+ dialog --yes-label Ok --no-label Cancel \
+ --yesno "Start installing\n'$image_path'\nto $target_device (capacity: $target_size)" 8 70
+}
+
+#--------------------------------------------------------------------------
+# ui_confirm_overwrite
+#
+# Returns:
+# 0 when user accepts overwrite, 1 when canceled.
+#--------------------------------------------------------------------------
+ui_confirm_overwrite() {
+ dialog --defaultno --yesno "WARNING: Target device is not empty! Continue anyway?" 8 70
+}
+
+#--------------------------------------------------------------------------
+# ui_start_progress_gauge <pipe_path>
+#
+# Opens a dialog gauge and updates it from bmaptool psplash pipe.
+#--------------------------------------------------------------------------
+ui_start_progress_gauge() {
+ local pipe_path="$1"
+
+ (
+ while true; do
+ if read -r line < "$pipe_path"; then
+ percentage=$(echo "$line" | awk '{ print $2 }')
+ echo "$percentage"
+ fi
+ done
+ ) | dialog --gauge "Flashing image, please wait..." 10 70 0 &
+
+ UI_GAUGE_PID=$!
+}
+
+#--------------------------------------------------------------------------
+# ui_stop_progress_gauge
+#
+# Best-effort termination of the active progress gauge process.
+#--------------------------------------------------------------------------
+ui_stop_progress_gauge() {
+ if [ -n "$UI_GAUGE_PID" ]; then
+ kill "$UI_GAUGE_PID" 2>/dev/null || true
+ UI_GAUGE_PID=""
+ fi
}
-run_interactive_installer
--
2.47.3
--
You received this message because you are subscribed to the Google Groups "isar-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isar-users+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/isar-users/20260427063957.603123-3-kasturi.shekar%40siemens.com.
next prev parent reply other threads:[~2026-04-27 6:40 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-27 6:39 [PATCH 0/4] installer: separate installer into backend, UI, and flow modules 'Kasturi shekar' via isar-users
2026-04-27 6:39 ` [PATCH 1/4] installer: extract backend helpers to sys_api.sh 'Kasturi shekar' via isar-users
2026-04-27 6:39 ` 'Kasturi shekar' via isar-users [this message]
2026-04-27 6:39 ` [PATCH 3/4] installer: add installer flow module and entrypoint 'Kasturi shekar' via isar-users
2026-04-27 6:39 ` [PATCH 4/4] installer: install seprated installer modules in recipe 'Kasturi shekar' via isar-users
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260427063957.603123-3-kasturi.shekar@siemens.com \
--to=isar-users@googlegroups.com \
--cc=kasturi.shekar@siemens.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox