[PATCH v1 0/2] installer: split backend APIs from frontend UI

17 views
Skip to first unread message

Kasturi Shekar

unread,
Jan 19, 2026, 12:53:57 AMJan 19
to isar-...@googlegroups.com, Kasturi Shekar
This patch series is a first step towards splitting the installer into
a reusable backend and a frontend.

Patch-1: introduces a small backend API layer (sys_api.sh) that provides
installer functionality via structured shell functions with JSON-style
return values.

Patch-2: adapts the existing dialog-based installer frontend to consume
these APIs, without changing behavior. This serves as validation that
the abstraction is sufficient for the current UI.

Further steps (not included here) would build additional frontends on
top of the same backend APIs, but this series focuses purely on the
foundation and existing workflow.

please refer to the initial discussion here
[1]https://groups.google.com/g/isar-users/c/Uy3Mg9gJnA4

Kasturi Shekar (2):
installer: introduce sys_api.sh backend interface
installer-ui: use sys_api backend for frontend dialogs

.../files/usr/bin/installer_ui.sh | 86 +++++++++++++++++++
.../deploy-image/files/usr/bin/sys_api.sh | 84 ++++++++++++++++++
2 files changed, 170 insertions(+)
create mode 100755 meta-isar/recipes-installer/deploy-image/files/usr/bin/installer_ui.sh
create mode 100644 meta-isar/recipes-installer/deploy-image/files/usr/bin/sys_api.sh

--
2.39.5

Kasturi Shekar

unread,
Jan 19, 2026, 12:54:03 AMJan 19
to isar-...@googlegroups.com, Kasturi Shekar
Signed-off-by: Kasturi Shekar <kasturi...@siemens.com>
---
.../deploy-image/files/usr/bin/sys_api.sh | 84 +++++++++++++++++++
1 file changed, 84 insertions(+)
create mode 100644 meta-isar/recipes-installer/deploy-image/files/usr/bin/sys_api.sh

diff --git a/meta-isar/recipes-installer/deploy-image/files/usr/bin/sys_api.sh b/meta-isar/recipes-installer/deploy-image/files/usr/bin/sys_api.sh
new file mode 100644
index 00000000..b144419e
--- /dev/null
+++ b/meta-isar/recipes-installer/deploy-image/files/usr/bin/sys_api.sh
@@ -0,0 +1,84 @@
+#!/usr/bin/env bash
+#
+# sys_api.sh — Ported installer system APIs
+# -------------------------------------------------------------------
+
+# Load shared framework utilities
+source ./func.sh || {
+ echo "Error: func.sh not found or not readable." >&2
+ exit 1
+}
+
+# -------------------------------------------------------------------
+# API: locate_disk_images
+# Description:
+# Find disk image files (.wic, .wic.bz2) under given path.
+# Usage:
+# sys_locate_disk_images search_path=/install
+# Returns JSON:
+# {"error":"", "retval":"0", "images":["/install/image.wic", ...]}
+# -------------------------------------------------------------------
+sys_locate_disk_images() {
+ local -A ARGS
+ local required=(search_path)
+ api_args ARGS required[@] "$@" || {
+ pack_return_data error "$_args_error" retval "1"
+ return 1
+ }
+
+ local fn="${FUNCNAME[0]}"
+ local path="${ARGS[search_path]}"
+
+ log_info "$fn" "Searching for disk images in '$path'"
+
+ local images
+ images=$(find "$path" -type f -iname "*.wic*" ! -iname "*.wic.bmap" 2>/dev/null)
+
+ # when no images found in /install
+ if [[ -z "$images" ]]; then
+ log_warn "$fn" "No images found."
+ pack_return_data error "No images found" retval "1"
+ return 1
+ fi
+
+ # Convert newline-separated paths into JSON array elements
+ local json_images
+ json_images=$(printf '"%s",' $images | sed 's/,$//')
+ # final JSON response on stdout
+ echo "{ \"error\":\"\", \"retval\":\"0\", \"images\":[${json_images}] }"
+}
+
+
+# -------------------------------------------------------------------
+# API: sys_list_valid_target_devices
+# Description:
+# Shell-friendly variant of sys_get_valid_target_devices.
+# Prints one valid device per line (absolute path).
+# Usage:
+# sys_list_valid_target_devices
+# Output:
+# /dev/sdb
+# /dev/sdc
+# -------------------------------------------------------------------
+sys_list_valid_target_devices() {
+ local dev
+
+ for dev in /sys/block/*; do
+ dev=$(basename "$dev")
+
+ case "$dev" in
+ loop*|ram*|sr*|mtd*)
+ continue
+ ;;
+ esac
+
+ # skip inactive md devices
+ if [[ "$dev" == md* ]]; then
+ [ -f "/sys/block/$dev/md/array_state" ] || continue
+ state=$(cat /sys/block/$dev/md/array_state)
+ [ "$state" = "active" ] || [ "$state" = "clean" ] || continue
+ fi
+
+ echo "/dev/$dev"
+ done
+}
--
2.39.5

Kasturi Shekar

unread,
Jan 19, 2026, 12:54:06 AMJan 19
to isar-...@googlegroups.com, Kasturi Shekar
Signed-off-by: Kasturi Shekar <kasturi...@siemens.com>
---
.../files/usr/bin/installer_ui.sh | 86 +++++++++++++++++++
1 file changed, 86 insertions(+)
create mode 100755 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
new file mode 100755
index 00000000..33685c6f
--- /dev/null
+++ b/meta-isar/recipes-installer/deploy-image/files/usr/bin/installer_ui.sh
@@ -0,0 +1,86 @@
+#!/usr/bin/env bash
+#
+# installer_ui.sh — Attended installer frontend
+# ------------------------------------------------
+
+SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
+INSTALL_DATA=${INSTALL_DATA:-./install}
+
+# Backend APIs
+. "$SCRIPT_DIR/sys_api.sh"
+
+# ------------------------------------------------
+# Helpers
+# ------------------------------------------------
+die() {
+ dialog --msgbox "$1" 6 60
+ exit 1
+}
+
+# ------------------------------------------------
+# UI: Select image
+# ------------------------------------------------
+ui_select_image() {
+ local images json list=()
+
+ # On failure, show error dialog and exit
+ json=$(sys_locate_disk_images search_path="$INSTALL_DATA") || \
+ die "No installable images found in $INSTALL_DATA"
+
+ # Extract image paths from JSON
+ images=$(echo "$json" | sed -n 's/.*"images":\[\(.*\)\].*/\1/p' | tr -d '"' | tr ',' '\n')
+
+ # Building dialog menu entries
+ for img in $images; do
+ base=$(basename "$img")
+ list+=("$img" "$base")
+ done
+
+ # Display menu and capture selection
+ INSTALL_IMAGE=$(dialog --no-tags \
+ --menu "Select image to install" 10 70 5 \
+ "${list[@]}" \
+ --output-fd 1) || exit 0
+}
+
+# ------------------------------------------------
+# UI: Select target device
+# ------------------------------------------------
+ui_select_target_device() {
+ local list=()
+
+ devices=$(sys_list_valid_target_devices) || \
+ die "No valid target devices found"
+
+ for dev in $devices; do
+ [ -b "$dev" ] || continue
+
+ 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
+ state="empty"
+ else
+ state="contains data"
+ fi
+
+ list+=("$dev" "$dev ($size, $state)")
+ done
+
+ if [ "${#list[@]}" -lt 2 ]; then
+ die "no installable target devices available"
+ fi
+
+ TARGET_DEVICE=$(dialog --no-tags \
+ --menu "Select target device" 10 70 6 \
+ "${list[@]}" \
+ --output-fd 1) || exit 0
+}
+
+run_interactive_installer() {
+ clear
+ ui_select_image
+ ui_select_target_device
+}
+
+run_interactive_installer
--
2.39.5

Reply all
Reply to author
Forward
0 new messages