From patchwork Mon Apr 27 06:39:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kasturi shekar X-Patchwork-Id: 5050 Return-Path: Received: from shymkent.ilbers.de ([unix socket]) by shymkent (Cyrus 2.5.10-Debian-2.5.10-3+deb9u2) with LMTPA; Mon, 27 Apr 2026 08:40:15 +0200 X-Sieve: CMU Sieve 2.4 Received: from mail-qv1-f64.google.com (mail-qv1-f64.google.com [209.85.219.64]) by shymkent.ilbers.de (8.15.2/8.15.2/Debian-8+deb9u1) with ESMTPS id 63R6e6SK000469 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 27 Apr 2026 08:40:07 +0200 Received: by mail-qv1-f64.google.com with SMTP id 6a1803df08f44-8ae6aa148a7sf189109796d6.0 for ; Sun, 26 Apr 2026 23:40:07 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1777272001; cv=pass; d=google.com; s=arc-20240605; b=JS/wmeCXa68xyonL2qsrUs9uTm/cMoHpI5xf5MZF/QI9uOyBPHQSGGrEmirCQtA2o9 z13xG70OBBcLJV40C9/hChgz55fzTlO4+8ZVHsGk3Sw2l/8NqTCj9WIitjGM0TaAXk43 1FzRSyiViWyEJjbfhEmU9eqinenvt4uvVgKQqVSmRXgl9BepVea4Uw/rqVK/MRC75qMJ C33PR7BFY3ZXMI0f/K7tiP5xVcljyZFXdyc165CTuZ4/Pr/cnxQT5GleG/UV+JCVLdok pTkiN99aKsDHpua89EuUywJxP/qVnFX6157GE6KKYON86l6GwsFCFFMRx3jHSUWYr0QU fc6g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to:feedback-id :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=ZncHi4nBRsL1VqRmAq6UsTvNVqkiA+A6Oq/N+qTFRRw=; fh=Oc8uYKG1IM9Ou4GrtQJDdFx71c7Hs+Nt1AnEdH6ixJw=; b=T9aBzg/VkdToKWaHfLqe7bNunS+X/NU2bS3JtazkZpCHsIDILnqTnbrZww0fV4FKTX h0aTzal53z3jGDvirYaX7IxydINlAahHylIDHiQndtwzAYDTkB6aZbWXKkGfvNqq1aJY QlWg5Tw8+yOFQQZNX33Rh8AXAKJFlMl7twwIOZlrVgJYGBNovOrqF0vb/WKLJl8teuL6 OkoQ+nMAs1Vvx9b2v1gQleHol3HdxgoCtDJdHcamXaghKzFLeLUD6OQWphPAnb/lHZ4K kZZkd624nxPTnOWRDmpRblcmhGjIoPkTNX7yfF6THH+Hox9OEnVqeAu1ZBzlJDJXKlxr dUuw==; darn=isar-build.org ARC-Authentication-Results: i=2; gmr-mx.google.com; dkim=pass header.i=@siemens.com header.s=fm2 header.b=Oou6e1m4; spf=pass (google.com: domain of fm-1328757-202604270639584cea3f4a0b00020755-xtyvbq@rts-flowmailer.siemens.com designates 185.136.64.228 as permitted sender) smtp.mailfrom=fm-1328757-202604270639584cea3f4a0b00020755-XTYvBq@rts-flowmailer.siemens.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=siemens.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20251104; t=1777272001; x=1777876801; darn=isar-build.org; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender:feedback-id :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZncHi4nBRsL1VqRmAq6UsTvNVqkiA+A6Oq/N+qTFRRw=; b=izgvo83vW9tTV4G2/rMI6lTSGwPcwMJX06QotnE02mZWEeTUlm3Ja7jPjPnkyOs2ta S0nPMv+6me/PDDgFQSxwUd2DtlSNn3AvVLuZiXerLVwB68dcPT2CdJfITT1uEdOWa8LK mTfKTFeikxYHieFvB+4yLyErfuO1lkOgz+KD1sQvGBGIXPPph2nJVNM82Pjv8UQu5T/G PWaYz0wPM6cJ/v40cEblc9ZNPL8KDTbcpGNpMUhKeaEf6XotQmqoWDJ3y4kJOoLE+VpR fn1mUrkiZNwxdMXPLgWpu2bJ/G8aP/+joME8HHlHA9djofzThuFOMHhadYLaqrXj0ppB XvDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777272001; x=1777876801; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender:feedback-id :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-beenthere:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=ZncHi4nBRsL1VqRmAq6UsTvNVqkiA+A6Oq/N+qTFRRw=; b=SPi+ZDuLL3eb0LYOm05DMdFjwgkbtc24n2O5kYtY3S004XPWWd4gRCIJHRelwRzPqx DXvULFlUdsw9XH4R2DEubla/nymly88GxCpWubLaIIp+l0YPsM1yBp2Hrebh2NVRmjoE 7LJf/Wr2hqpOUPon9+tfZXvQeyBU7uJarArCWjIy4iv0RN95KtuRawWTOYnbsEdE2Xmg kd3FoNM0HAYDhPaD8IjzwShfvGspWULnpM/aiuJPEvdcqQ15xp19xfmkesspfeKKDHGl hWzIkxFZiUpVELasO6ttSvFGePPXyEc0Rh/XJqUUz4CRYxFnZE34DHR7vAUKQxuo42Aa 4ulQ== X-Forwarded-Encrypted: i=2; AFNElJ/lDKtd1/zzonuYB0Ng8LWhaoe4oMULB65RFl/T4jfCcUq8EyeHYsyf28xLc5JWnCooXg7yWLk=@isar-build.org X-Gm-Message-State: AOJu0YxZDsGvhighulr6BLA6Nxr5n4AMoELPwryQUA6EZjAE1aHca88G vh+XKsyE8tmi+TSQm08OTQnvxbbJOy0tWDN6SiVq+wnCOj7/mYcE2Cty X-Received: by 2002:a05:6214:500f:b0:89c:da2b:d137 with SMTP id 6a1803df08f44-8b0287e49e3mr527403726d6.33.1777272001052; Sun, 26 Apr 2026 23:40:01 -0700 (PDT) X-BeenThere: isar-users@googlegroups.com; h="AYAyTiLr0XP4xmYAmr7S/4taG9jw/aC9FUZK17CQ779wqsGx7g==" Received: by 2002:a05:622a:4656:b0:50f:b181:6ae0 with SMTP id d75a77b69052e-50fb1816d70ls47318281cf.0.-pod-prod-00-us; Sun, 26 Apr 2026 23:40:00 -0700 (PDT) X-Received: by 2002:a05:622a:1902:b0:50b:8b8c:f68b with SMTP id d75a77b69052e-50e367b90a2mr541560811cf.39.1777272000211; Sun, 26 Apr 2026 23:40:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1777272000; cv=none; d=google.com; s=arc-20240605; b=Pg+I2ZcIv8yRYXvpJvGe1TzIRyAi20t8nvCt/nzyqZhkQYLnvf2CKjp2hZ98NuI2nk NuG5S0Ws39HPFy2gh5Y2p5hMr/rKrLEY5KUdJp8eWYny8gOKjvKoCvzJfKRFDm4tx9GX gRK+jXGdLArQuDHzTZeG73LyVmZ0zsWiz2l7fh1TzbdOIx2O8gkJF9+R4Cs2FmD4WnV0 N1B/571K2n17ArpBHJX30lsbh6sZ3TKLjClXzlZ0Ykb8PiwATWNhobbbButmWNtny2uV WDhnQhYPvaeGLEFw1gNI0C+su5ucUDCd7t4c8iXp13r4m6jIaqniKR+zxy1pBP2/ynRU qfKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=feedback-id:content-transfer-encoding:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:dkim-signature; bh=ytomooH9Ej5VaG//kMNK2ngS+woy9XntQRff8LUEiDY=; fh=kh6mBxUBxYhzFhhtG3ckYICU9JWCX223LZXZsw4oG5w=; b=eezjHhrnqTqXfqm1aWo0XIOS4NGWCCC6WSgIcfYwaqDqODY5QaipQSf6kyEG8WhZkw pTJ3iMl8eS5Ht9Kgt/RT3kqaAL7D8FFbbKgO4smBbVmfLO5dr4OsqafwNWX2iZ0KUBRw WVTajUFlypT/vQUZno4y3jPVIyOJbdD+6VRpyIiJo/TsFIs6EMkZAYIApBGqhlvvW1AQ Uzar7mbRWWUqI7I/kqEIdjr7rRaGtOcMxe3c3PYwxMkSGpAgFs9/QkSYeTgnLdgDunUg oT5izUgUBA5y6UPHKIahP+6gC4kbM576O2VdI6kaLm5KVlsNSdxpLffOUoBtvB+eA775 f85Q==; dara=google.com ARC-Authentication-Results: i=1; gmr-mx.google.com; dkim=pass header.i=@siemens.com header.s=fm2 header.b=Oou6e1m4; spf=pass (google.com: domain of fm-1328757-202604270639584cea3f4a0b00020755-xtyvbq@rts-flowmailer.siemens.com designates 185.136.64.228 as permitted sender) smtp.mailfrom=fm-1328757-202604270639584cea3f4a0b00020755-XTYvBq@rts-flowmailer.siemens.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=siemens.com Received: from mta-64-228.siemens.flowmailer.net (mta-64-228.siemens.flowmailer.net. [185.136.64.228]) by gmr-mx.google.com with ESMTPS id d75a77b69052e-50fbe8b5d39si6680961cf.4.2026.04.26.23.40.00 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Apr 2026 23:40:00 -0700 (PDT) Received-SPF: pass (google.com: domain of fm-1328757-202604270639584cea3f4a0b00020755-xtyvbq@rts-flowmailer.siemens.com designates 185.136.64.228 as permitted sender) client-ip=185.136.64.228; Received: by mta-64-228.siemens.flowmailer.net with ESMTPSA id 202604270639584cea3f4a0b00020755 for ; Mon, 27 Apr 2026 08:39:59 +0200 X-Patchwork-Original-From: "'Kasturi shekar' via isar-users" From: Kasturi shekar To: isar-users@googlegroups.com Cc: "kasturi.shekar" Subject: [PATCH 2/4] installer: extract attended UI to installer_ui.sh Date: Mon, 27 Apr 2026 12:09:54 +0530 Message-ID: <20260427063957.603123-3-kasturi.shekar@siemens.com> In-Reply-To: <20260427063957.603123-1-kasturi.shekar@siemens.com> References: <20260427063957.603123-1-kasturi.shekar@siemens.com> MIME-Version: 1.0 X-Flowmailer-Platform: Siemens Feedback-ID: 519:519-1328757:519-21489:flowmailer X-Original-Sender: kasturi.shekar@siemens.com X-Original-Authentication-Results: gmr-mx.google.com; dkim=pass header.i=@siemens.com header.s=fm2 header.b=Oou6e1m4; spf=pass (google.com: domain of fm-1328757-202604270639584cea3f4a0b00020755-xtyvbq@rts-flowmailer.siemens.com designates 185.136.64.228 as permitted sender) smtp.mailfrom=fm-1328757-202604270639584cea3f4a0b00020755-XTYvBq@rts-flowmailer.siemens.com; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=siemens.com X-Original-From: Kasturi shekar Reply-To: Kasturi shekar Precedence: list Mailing-list: list isar-users@googlegroups.com; contact isar-users+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: isar-users@googlegroups.com X-Google-Group-Id: 914930254986 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , X-Spam-Status: No, score=-4.9 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_MSPIKE_H2,RCVD_IN_RP_CERTIFIED, RCVD_IN_RP_RNBL,RCVD_IN_RP_SAFE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on shymkent.ilbers.de X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= From: "kasturi.shekar" 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 --- .../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 +# +# 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 +# +# Displays an informational dialog in attended mode. +#-------------------------------------------------------------------------- +ui_show_info() { + local message="$1" + dialog --msgbox "$message" 6 60 +} + +#-------------------------------------------------------------------------- +# ui_countdown_allow_attended_switch +# +# 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 +# +# 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 +# +# 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 +# +# 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 +# +# 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