diff --git a/Readme.md b/Readme.md index 2c4fec7..bb952c0 100644 --- a/Readme.md +++ b/Readme.md @@ -55,10 +55,10 @@ chmod +x ubuntu-based-kiosk.sh && ./ubuntu-based-kiosk.sh The installer will guide you through configuration during setup. > The modular `./install.sh` (see "Modular Management" below) can also -> provision a kiosk from scratch now, as an alternative to the -> single-file installer above. `ubuntu-based-kiosk.sh` remains the more -> battle-tested path and the only one that supports Upgrade/Full -> Reinstall of an existing install. +> provision a kiosk from scratch now, and has its own Upgrade, as an +> alternative to the single-file installer above. `ubuntu-based-kiosk.sh` +> remains the more battle-tested path and the only one that supports +> 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. - `kiosk-app/` — the Electron app source (`main.js`, `preload.js`, the dialog HTML files, `package.json`, `start.sh`), copied to the kiosk - directory during provisioning. Also the basis for a future clean - `git pull`-based Upgrade. + directory during provisioning and re-copied during Upgrade. - `provision/files/` — every other system template file provisioning installs (X11 configs, udev rules, systemd units, the power-button and HDMI-mirroring scripts, polkit rules), laid out mirroring their real destination path, e.g. `provision/files/etc/X11/xorg.conf.d/ 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 Settings / Addons / Advanced** like the legacy menu. On a machine 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 ``` -**Honest status:** first-time installation is now covered — `install.sh` -provisions a kiosk from a bare Ubuntu Server box, not just an -already-installed one — but `ubuntu-based-kiosk.sh` is still ~12,000 -lines and still contains its own unremoved, unmodified copies of every -menu above, including the legacy three-option (Client/Server/Full) -Easy Asterisk Intercom — the modular version only replaces the Client -option, by design. Two pieces remain legacy-only: Upgrade and Full -Reinstall, both coupled to `ubuntu-based-kiosk.sh`'s own heredoc -self-extraction of main.js/preload.js/etc — a different mechanism from -the new provisioning, which copies real files from `kiosk-app/` and +**Honest status:** first-time installation and Upgrade are now covered — +`install.sh` provisions a kiosk from a bare Ubuntu Server box, not just +an already-installed one, and can pull/apply its own updates — but +`ubuntu-based-kiosk.sh` is still ~12,000 lines and still contains its +own unremoved, unmodified copies of every menu above, including the +legacy three-option (Client/Server/Full) Easy Asterisk Intercom — the +modular version only replaces the Client option, by design. One piece +remains legacy-only: Full Reinstall, coupled to +`ubuntu-based-kiosk.sh`'s own heredoc self-extraction of +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 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 @@ -1341,9 +1347,14 @@ full migration pass. ## 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. - **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. diff --git a/install.sh b/install.sh index a94ec96..65f7f73 100755 --- a/install.sh +++ b/install.sh @@ -11,11 +11,13 @@ # # ubuntu-based-kiosk.sh, the original single-file installer, still # 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 -# reimplement: Upgrade and Full Reinstall, both coupled to that script's -# own heredoc self-extraction of main.js/preload.js/etc - a different -# mechanism than provisioning (which now copies real files from -# kiosk-app/ and provision/files/, not heredocs) and not yet ported. +# new kiosk. Upgrade (Advanced -> Upgrade) is now here too, but not a +# port of the legacy version - that one re-extracted heredocs on every +# run; kiosk-app/ and provision/files/ are real files in this git +# checkout, so the modular Upgrade is `git pull` + re-running the same +# 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: # Core Settings: Sites & Page Timing, Display & Interaction, Timezone, @@ -36,7 +38,9 @@ # (menus/advanced_emergency_hotspot.sh), Clone Settings # (menus/clone_settings.sh - export/apply portable settings across # 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): # git clone @@ -82,6 +86,11 @@ source "$SCRIPT_DIR/menus/addon_lms_squeezelite.sh" source "$SCRIPT_DIR/menus/addon_asterisk_intercom.sh" # shellcheck source=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 source "$SCRIPT_DIR/menus/advanced_factory_reset.sh" # shellcheck source=menus/advanced_virtual_consoles.sh @@ -164,8 +173,8 @@ addons_menu() { } advanced_menu_builder() { - MENU_LABELS=("Diagnostics" "Electron Maintenance" "Factory Reset" "Virtual Consoles" "Emergency Hotspot" "Clone Settings") - MENU_HANDLERS=(diagnostics_menu advanced_electron_menu advanced_factory_reset_menu advanced_virtual_consoles_menu advanced_emergency_hotspot_menu clone_settings_menu) + 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 advanced_upgrade_menu) } advanced_menu() { diff --git a/menus/advanced_upgrade.sh b/menus/advanced_upgrade.sh new file mode 100644 index 0000000..96502fa --- /dev/null +++ b/menus/advanced_upgrade.sh @@ -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 +} diff --git a/ubuntu-based-kiosk.sh b/ubuntu-based-kiosk.sh index 709a231..d41c7aa 100644 --- a/ubuntu-based-kiosk.sh +++ b/ubuntu-based-kiosk.sh @@ -1,8 +1,28 @@ #!/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, # Not Just Manages an Existing One # - Until now, ./install.sh only worked against an already-installed @@ -521,7 +541,7 @@ set -euo pipefail ### SECTION 1: CONSTANTS & GLOBALS ################################################################################ -SCRIPT_VERSION="2.14.0" +SCRIPT_VERSION="2.15.0" # Resolve the real path to this script file. # When piped (curl|bash or wget|bash), BASH_SOURCE[0] is a pipe descriptor,