Add Upgrade to install.sh (v2.15.0)

The legacy Upgrade re-extracted main.js/preload.js/etc from its own
heredocs on every run - a mechanism the modular tool has no equivalent
of now that kiosk-app/ and provision/files/ are real files in the git
checkout. The new Advanced -> Upgrade is `git pull` (only after a
clean-tree check, and only as a fast-forward - never an automatic
merge) followed by re-running the same packages/kiosk-app/display/
firewall/power-management steps lib/provision.sh already has for a
fresh install, reused rather than reimplemented. Also offers an
on-demand Electron version check via the existing action_update_electron,
since Electron isn't versioned by this repo.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VfsFSoRqfbRG7XAg5RoE7e
This commit is contained in:
Claude
2026-08-19 13:50:25 +00:00
parent 037a62e008
commit d411b05cae
4 changed files with 212 additions and 28 deletions
+29 -18
View File
@@ -55,10 +55,10 @@ chmod +x ubuntu-based-kiosk.sh && ./ubuntu-based-kiosk.sh
The installer will guide you through configuration during setup. The installer will guide you through configuration during setup.
> The modular `./install.sh` (see "Modular Management" below) can also > The modular `./install.sh` (see "Modular Management" below) can also
> provision a kiosk from scratch now, as an alternative to the > provision a kiosk from scratch now, and has its own Upgrade, as an
> single-file installer above. `ubuntu-based-kiosk.sh` remains the more > alternative to the single-file installer above. `ubuntu-based-kiosk.sh`
> battle-tested path and the only one that supports Upgrade/Full > remains the more battle-tested path and the only one that supports
> Reinstall of an existing install. > Full Reinstall of an existing install.
--- ---
@@ -1280,13 +1280,18 @@ terminal menu and the web UI, so they can't drift apart).
time. See "Recent Updates (v2.14.0)" below. time. See "Recent Updates (v2.14.0)" below.
- `kiosk-app/` — the Electron app source (`main.js`, `preload.js`, the - `kiosk-app/` — the Electron app source (`main.js`, `preload.js`, the
dialog HTML files, `package.json`, `start.sh`), copied to the kiosk dialog HTML files, `package.json`, `start.sh`), copied to the kiosk
directory during provisioning. Also the basis for a future clean directory during provisioning and re-copied during Upgrade.
`git pull`-based Upgrade.
- `provision/files/` — every other system template file provisioning - `provision/files/` — every other system template file provisioning
installs (X11 configs, udev rules, systemd units, the power-button installs (X11 configs, udev rules, systemd units, the power-button
and HDMI-mirroring scripts, polkit rules), laid out mirroring their and HDMI-mirroring scripts, polkit rules), laid out mirroring their
real destination path, e.g. `provision/files/etc/X11/xorg.conf.d/ real destination path, e.g. `provision/files/etc/X11/xorg.conf.d/
foo.conf` installs to `/etc/X11/xorg.conf.d/foo.conf`. foo.conf` installs to `/etc/X11/xorg.conf.d/foo.conf`.
- `menus/advanced_upgrade.sh`**Upgrade** (Advanced): `git pull` (only
as a clean fast-forward) plus re-running the same
packages/kiosk-app/display/firewall/power-management provisioning
steps, so any code or hardware-config change picked up by the pull
actually takes effect. Also offers an on-demand Electron version
check. See "Recent Updates (v2.15.0)" below.
- `install.sh` — entry point for the modular tool, now grouped **Core - `install.sh` — entry point for the modular tool, now grouped **Core
Settings / Addons / Advanced** like the legacy menu. On a machine Settings / Addons / Advanced** like the legacy menu. On a machine
with no kiosk installed yet, it provisions one first (see with no kiosk installed yet, it provisions one first (see
@@ -1298,16 +1303,17 @@ terminal menu and the web UI, so they can't drift apart).
./install.sh ./install.sh
``` ```
**Honest status:** first-time installation is now covered — `install.sh` **Honest status:** first-time installation and Upgrade are now covered —
provisions a kiosk from a bare Ubuntu Server box, not just an `install.sh` provisions a kiosk from a bare Ubuntu Server box, not just
already-installed one — but `ubuntu-based-kiosk.sh` is still ~12,000 an already-installed one, and can pull/apply its own updates — but
lines and still contains its own unremoved, unmodified copies of every `ubuntu-based-kiosk.sh` is still ~12,000 lines and still contains its
menu above, including the legacy three-option (Client/Server/Full) own unremoved, unmodified copies of every menu above, including the
Easy Asterisk Intercom — the modular version only replaces the Client legacy three-option (Client/Server/Full) Easy Asterisk Intercom — the
option, by design. Two pieces remain legacy-only: Upgrade and Full modular version only replaces the Client option, by design. One piece
Reinstall, both coupled to `ubuntu-based-kiosk.sh`'s own heredoc remains legacy-only: Full Reinstall, coupled to
self-extraction of main.js/preload.js/etc — a different mechanism from `ubuntu-based-kiosk.sh`'s own heredoc self-extraction of
the new provisioning, which copies real files from `kiosk-app/` and main.js/preload.js/etc — a different mechanism from the new
provisioning, which copies real files from `kiosk-app/` and
`provision/files/` instead. The legacy Export/Import Settings is also `provision/files/` instead. The legacy Export/Import Settings is also
staying as-is; Clone Settings is a new, narrower feature alongside it, staying as-is; Clone Settings is a new, narrower feature alongside it,
not a replacement for it — see "Recent Updates (v2.13.0)" below for why not a replacement for it — see "Recent Updates (v2.13.0)" below for why
@@ -1341,9 +1347,14 @@ full migration pass.
## Project Status & Future Plans ## Project Status & Future Plans
**Current Version:** 2.14.0 **Current Version:** 2.15.0
**Recent Updates (v2.14.0):** **Recent Updates (v2.15.0):**
- **New: Upgrade** (Advanced → Upgrade) — not a port of the legacy Upgrade, which re-extracted `main.js`/`preload.js`/etc from its own heredocs on every run. `kiosk-app/` and `provision/files/` are real files in this git checkout now, so the modular Upgrade is `git pull` (after confirming a clean working tree, and only as a fast-forward — never an automatic merge) followed by re-running the same packages/kiosk-app/display/firewall/power-management steps `lib/provision.sh` already has for a fresh install, reused rather than reimplemented. Skips the interactive first-run settings wizard and the "reboot now" prompt.
- Also offers an on-demand Electron version check regardless of whether there was code to pull (Electron isn't versioned by this repo) — reuses the existing, already-tested `action_update_electron` as-is.
- Requires a real git checkout (not the no-git ZIP download option) and a clean working tree; a diverged local history fails the pull cleanly with a clear message rather than attempting an automatic merge.
**Previous (v2.14.0):**
- **`./install.sh` now provisions a kiosk from scratch, not just manages an existing one.** Until now it only worked against an already-installed kiosk — `ubuntu-based-kiosk.sh` was still the only path from a bare Ubuntu Server box to a running one. On a machine with no kiosk-app directory yet, it now installs packages, creates the kiosk user, installs Node.js/Electron, sets up LightDM+Openbox autologin, audio/video/HDMI/power-button hardware handling, and the firewall, then hands off to the same Core Settings menus for initial configuration — matching the legacy script's own install-then-configure flow, on the modular codebase. - **`./install.sh` now provisions a kiosk from scratch, not just manages an existing one.** Until now it only worked against an already-installed kiosk — `ubuntu-based-kiosk.sh` was still the only path from a bare Ubuntu Server box to a running one. On a machine with no kiosk-app directory yet, it now installs packages, creates the kiosk user, installs Node.js/Electron, sets up LightDM+Openbox autologin, audio/video/HDMI/power-button hardware handling, and the firewall, then hands off to the same Core Settings menus for initial configuration — matching the legacy script's own install-then-configure flow, on the modular codebase.
- **New: `lib/provision.sh`**, the provisioning steps — built almost entirely by calling menus already migrated below (`core_settings_menu`, emergency hotspot, virtual consoles) instead of reimplementing that configuration logic a third time. Reuse cut it down to roughly 300 lines against the legacy script's ~4,000-line `first_time_install()`. - **New: `lib/provision.sh`**, the provisioning steps — built almost entirely by calling menus already migrated below (`core_settings_menu`, emergency hotspot, virtual consoles) instead of reimplementing that configuration logic a third time. Reuse cut it down to roughly 300 lines against the legacy script's ~4,000-line `first_time_install()`.
- **New: `lib/electron.sh`** — `electron_install_binary()`, extracted out of `menus/advanced_electron.sh` so fresh provisioning and the existing "Fix blank screen" action share one implementation instead of two copies of the same repair sequence. - **New: `lib/electron.sh`** — `electron_install_binary()`, extracted out of `menus/advanced_electron.sh` so fresh provisioning and the existing "Fix blank screen" action share one implementation instead of two copies of the same repair sequence.
+17 -8
View File
@@ -11,11 +11,13 @@
# #
# ubuntu-based-kiosk.sh, the original single-file installer, still # ubuntu-based-kiosk.sh, the original single-file installer, still
# exists and still works, but is no longer the only way to provision a # exists and still works, but is no longer the only way to provision a
# new kiosk. Two things remain there that this tool deliberately doesn't # new kiosk. Upgrade (Advanced -> Upgrade) is now here too, but not a
# reimplement: Upgrade and Full Reinstall, both coupled to that script's # port of the legacy version - that one re-extracted heredocs on every
# own heredoc self-extraction of main.js/preload.js/etc - a different # run; kiosk-app/ and provision/files/ are real files in this git
# mechanism than provisioning (which now copies real files from # checkout, so the modular Upgrade is `git pull` + re-running the same
# kiosk-app/ and provision/files/, not heredocs) and not yet ported. # provisioning steps, reused rather than reimplemented (see
# menus/advanced_upgrade.sh). Full Reinstall remains legacy-only - it
# has no equivalent here yet.
# #
# Migrated so far, grouped the same way the legacy menu groups them: # Migrated so far, grouped the same way the legacy menu groups them:
# Core Settings: Sites & Page Timing, Display & Interaction, Timezone, # Core Settings: Sites & Page Timing, Display & Interaction, Timezone,
@@ -36,7 +38,9 @@
# (menus/advanced_emergency_hotspot.sh), Clone Settings # (menus/advanced_emergency_hotspot.sh), Clone Settings
# (menus/clone_settings.sh - export/apply portable settings across # (menus/clone_settings.sh - export/apply portable settings across
# several kiosks; deliberately excludes machine-bound credentials # several kiosks; deliberately excludes machine-bound credentials
# like Authelia/WireGuard/Asterisk Intercom - see the file header). # like Authelia/WireGuard/Asterisk Intercom - see the file header),
# Upgrade (menus/advanced_upgrade.sh - git pull + re-provision, plus
# an on-demand Electron version check).
# #
# Usage (works whether or not a kiosk is already installed): # Usage (works whether or not a kiosk is already installed):
# git clone <repo> # git clone <repo>
@@ -82,6 +86,11 @@ source "$SCRIPT_DIR/menus/addon_lms_squeezelite.sh"
source "$SCRIPT_DIR/menus/addon_asterisk_intercom.sh" source "$SCRIPT_DIR/menus/addon_asterisk_intercom.sh"
# shellcheck source=menus/advanced_electron.sh # shellcheck source=menus/advanced_electron.sh
source "$SCRIPT_DIR/menus/advanced_electron.sh" source "$SCRIPT_DIR/menus/advanced_electron.sh"
# shellcheck source=menus/advanced_upgrade.sh
# Depends on action_update_electron above and the provision_* functions
# sourced later (lib/provision.sh) - safe either way, bash resolves
# function calls at run time, not source time.
source "$SCRIPT_DIR/menus/advanced_upgrade.sh"
# shellcheck source=menus/advanced_factory_reset.sh # shellcheck source=menus/advanced_factory_reset.sh
source "$SCRIPT_DIR/menus/advanced_factory_reset.sh" source "$SCRIPT_DIR/menus/advanced_factory_reset.sh"
# shellcheck source=menus/advanced_virtual_consoles.sh # shellcheck source=menus/advanced_virtual_consoles.sh
@@ -164,8 +173,8 @@ addons_menu() {
} }
advanced_menu_builder() { advanced_menu_builder() {
MENU_LABELS=("Diagnostics" "Electron Maintenance" "Factory Reset" "Virtual Consoles" "Emergency Hotspot" "Clone Settings") MENU_LABELS=("Diagnostics" "Electron Maintenance" "Factory Reset" "Virtual Consoles" "Emergency Hotspot" "Clone Settings" "Upgrade")
MENU_HANDLERS=(diagnostics_menu advanced_electron_menu advanced_factory_reset_menu advanced_virtual_consoles_menu advanced_emergency_hotspot_menu clone_settings_menu) MENU_HANDLERS=(diagnostics_menu advanced_electron_menu advanced_factory_reset_menu advanced_virtual_consoles_menu advanced_emergency_hotspot_menu clone_settings_menu advanced_upgrade_menu)
} }
advanced_menu() { advanced_menu() {
+144
View File
@@ -0,0 +1,144 @@
#!/bin/bash
################################################################################
# menus/advanced_upgrade.sh - "Upgrade" (Advanced): pull the latest code
# from git and re-apply provisioning, plus an on-demand Electron update.
#
# ubuntu-based-kiosk.sh's Upgrade extracted fresh copies of main.js/
# preload.js/etc from its own heredocs on every run - the modular tool
# has no heredocs to extract from. kiosk-app/ and provision/files/ are
# real files in this git checkout, so "get whatever's new" is just
# `git pull` followed by re-running the same steps lib/provision.sh
# already has for a fresh install - reused here, not reimplemented,
# minus the interactive first-run settings wizard and the "reboot now"
# prompt (upgrading shouldn't re-ask sites/hotspot/vconsoles or reboot
# the whole machine). Electron itself isn't versioned by this repo, so
# checking for a newer Electron is a separate step: the existing,
# already-tested action_update_electron (menus/advanced_electron.sh),
# reused as-is rather than duplicated.
#
# Depends on: lib/menu.sh, lib/config.sh, lib/electron.sh,
# lib/provision.sh, menus/advanced_electron.sh being sourced first.
################################################################################
advanced_upgrade_status() {
if git -C "$SCRIPT_DIR" rev-parse --is-inside-work-tree &>/dev/null; then
local branch rev
branch=$(git -C "$SCRIPT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
rev=$(git -C "$SCRIPT_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown")
echo "Installed from git: $branch @ $rev"
else
echo "Installed from git: not a git checkout (upgrade unavailable)"
fi
}
advanced_upgrade_menu_builder() {
MENU_LABELS=("Check for and apply updates")
MENU_HANDLERS=(action_upgrade)
}
advanced_upgrade_menu() {
run_menu "UPGRADE" advanced_upgrade_menu_builder advanced_upgrade_status
}
################################################################################
# Actions
################################################################################
action_upgrade() {
echo
if ! command -v git &>/dev/null; then
log_error "git is not installed - can't check for updates"
pause
return 1
fi
if ! git -C "$SCRIPT_DIR" rev-parse --is-inside-work-tree &>/dev/null; then
log_error "$SCRIPT_DIR is not a git checkout - re-clone the repo to get this feature"
pause
return 1
fi
if [[ -n "$(git -C "$SCRIPT_DIR" status --porcelain)" ]]; then
log_error "Local changes in $SCRIPT_DIR - commit or discard them first, then retry"
pause
return 1
fi
log_info "Checking for updates..."
if ! git -C "$SCRIPT_DIR" fetch origin; then
log_error "Could not reach GitHub - check your internet connection"
pause
return 1
fi
local branch local_rev remote_rev
branch=$(git -C "$SCRIPT_DIR" rev-parse --abbrev-ref HEAD)
local_rev=$(git -C "$SCRIPT_DIR" rev-parse HEAD)
remote_rev=$(git -C "$SCRIPT_DIR" rev-parse "origin/$branch" 2>/dev/null || true)
if [[ -z "$remote_rev" ]]; then
log_error "Could not find origin/$branch - is this checkout tracking a real branch?"
pause
return 1
fi
if [[ "$local_rev" == "$remote_rev" ]]; then
log_success "Already up to date ($branch @ ${local_rev:0:8})"
else
echo
echo "Changes available:"
git -C "$SCRIPT_DIR" --no-pager log --oneline "${local_rev}..${remote_rev}"
echo
if ask_yes_no "Pull these changes and re-apply setup (packages, app files, hardware config)?" "y"; then
if ! git -C "$SCRIPT_DIR" pull --ff-only origin "$branch"; then
log_error "Pull failed (not a fast-forward) - resolve manually in $SCRIPT_DIR"
pause
return 1
fi
log_success "Pulled latest code ($branch @ $(git -C "$SCRIPT_DIR" rev-parse --short HEAD))"
echo
log_info "Re-applying setup with the updated code..."
provision_install_packages
provision_create_kiosk_user
provision_install_nodejs
# Bare call, not `if ! provision_install_app; then`: testing a
# multi-statement function as an if-condition exempts
# everything inside it from set -e for the duration (see
# lib/provision.sh's own call to this same function). $? is
# captured right after instead - accurate either way, and
# doesn't add a new exemption on top of the one this action
# already has from being invoked through run_menu's dispatch.
provision_install_app
local app_rc=$?
if [[ $app_rc -ne 0 ]]; then
log_error "Upgrade stopped - app reinstall failed, see above"
pause
return 1
fi
provision_configure_display
provision_configure_firewall
provision_configure_power_management
log_success "Setup refreshed"
echo
if ask_yes_no "Restart kiosk display now to apply changes?" "y"; then
sudo systemctl restart lightdm
else
log_info "Restart later with: sudo systemctl restart lightdm"
fi
else
echo "Cancelled"
fi
fi
echo
if ask_yes_no "Check for and install the latest Electron version too?" "y"; then
action_update_electron
return
fi
pause
}
+22 -2
View File
@@ -1,8 +1,28 @@
#!/bin/bash #!/bin/bash
################################################################################ ################################################################################
### Ubuntu Based Kiosk v2.14.0 ### ### Ubuntu Based Kiosk v2.15.0 ###
################################################################################ ################################################################################
# #
# RELEASE v2.15.0 - Upgrade Migrated to install.sh (Advanced -> Upgrade)
# - New in ./install.sh's Advanced menu: Upgrade. Not a port of this
# script's Upgrade - that one re-extracted main.js/preload.js/etc from
# its own heredocs on every run, a mechanism that has no equivalent
# here now that kiosk-app/ and provision/files/ are real files in the
# git checkout. The modular Upgrade is `git pull` (only after
# confirming the working tree is clean and the pull is a fast-forward
# - never an automatic merge) followed by re-running the same
# packages/kiosk-app/display/firewall/power-management steps
# lib/provision.sh already has for a fresh install, reused rather than
# reimplemented. Skips the interactive first-run settings wizard and
# the "reboot now" prompt - those don't belong in a routine upgrade.
# - Also offers an on-demand Electron version check/update regardless of
# whether there was any code to pull, since Electron isn't versioned
# by this repo - reuses the existing, already-tested
# action_update_electron (menus/advanced_electron.sh) as-is.
# - Requires a git checkout (not the no-git ZIP download option) and a
# clean working tree; a diverged local history fails the pull cleanly
# with a clear message instead of attempting an automatic merge.
#
# RELEASE v2.14.0 - install.sh Now Provisions a Kiosk From Scratch, # RELEASE v2.14.0 - install.sh Now Provisions a Kiosk From Scratch,
# Not Just Manages an Existing One # Not Just Manages an Existing One
# - Until now, ./install.sh only worked against an already-installed # - Until now, ./install.sh only worked against an already-installed
@@ -521,7 +541,7 @@ set -euo pipefail
### SECTION 1: CONSTANTS & GLOBALS ### SECTION 1: CONSTANTS & GLOBALS
################################################################################ ################################################################################
SCRIPT_VERSION="2.14.0" SCRIPT_VERSION="2.15.0"
# Resolve the real path to this script file. # Resolve the real path to this script file.
# When piped (curl|bash or wget|bash), BASH_SOURCE[0] is a pipe descriptor, # When piped (curl|bash or wget|bash), BASH_SOURCE[0] is a pipe descriptor,