Migrate WiFi and Power/Display/Quiet Hours menus; bump to v2.3.0
By far the riskiest menus migrated so far. Both can affect real system
state outside config.json in ways that are hard to reverse: WiFi
rewrites live netplan config and, over SSH, can disconnect the very
session configuring it; power scheduling can shut the physical machine
down and wake it via RTC.
- lib/config.sh: new $SYSTEMD_DIR/$CRON_D_DIR/$BIN_DIR/$NETPLAN_DIR,
same `: "${VAR:=default}"` pattern as $KIOSK_DIR. Nothing under
menus/ hardcodes /etc/systemd/system, /etc/cron.d, /usr/local/bin, or
/etc/netplan directly, so every test in this change points them at
scratch space instead of ever touching this sandbox's real systemd
units, cron, or network config.
- lib/menu.sh: ported get_ip_address (also fixing its "No IP" fallback,
which never actually fired before - `hostname -I | awk` always exits
0 even on empty output).
- menus/wifi.sh: apply_wifi_config split out from wifi_menu specifically
so tests can drive the netplan-writing logic without needing real
scan hardware. Preserves the legacy netplan backup, 60s SSH watchdog,
and restore-on-failure behavior exactly.
- menus/power_schedule.sh: power schedule (+ RTC wake), display
schedule, quiet hours, and an Electron reload timer (with its own
nested run_menu, mirroring the legacy configured/not-configured
dispatch), plus remove-all. Deliberately excludes the legacy
dispatcher's "Test schedules & system" - a shared diagnostics submenu
(audio/network/keyboard tests) that isn't specific to scheduling and
belongs with a future Advanced/Diagnostics migration instead.
Bugs found and fixed along the way, none papered over:
- The legacy dispatcher refused to open "Configure power schedule" at
all without RTC hardware, even though shutdown-only mode never needed
RTC. Now always available.
- None of the six HH:MM prompts across these menus (shutdown, wake,
display off/on, quiet start/end, custom Electron reload time) were
validated before - plain `read`, no format check. All now go through
ask_time.
- set -e safety (same class as the v2.1.0 run_menu fix), three more
instances: `ls *.yaml` when no netplan file exists still fails under
pipefail even with stderr silenced (masked in practice by cloud-init
usually leaving a file behind); the restore-and-reapply `netplan
apply` after an initial failure was a bare unguarded statement; and
`systemctl enable`/`start` after writing each of the four timer pairs
was unguarded too - caught only by testing in an environment without
a live systemd, but a real enable/start failure on actual hardware
(bad unit, daemon-reload skipped, ...) would hit the exact same crash.
Added a shared enable_and_start_timers() helper used at all four call
sites; all now report a clear warning and return to the menu instead
of taking the session down.
Testing discipline for this round, given the risk:
- No automated test calls the real netplan/nmcli/iw/wpa_cli/systemctl -
confirmed no WiFi tools or `wl*` interface exist in this sandbox, so
wifi_menu's own tools-check safely short-circuits before touching
anything; apply_wifi_config's actual YAML/backup/failure-recovery
logic is tested with sudo/netplan/get_ip_address stubbed instead.
- One stubbing pitfall caught and fixed in the test itself: `nohup sudo
bash "$watchdog" ... &` execs nohup as a real external binary, which
then execs the real sudo - a bash function stub named `sudo` does NOT
intercept that, only stubbing `nohup` itself does. Verified via pgrep
that no real watchdog process or `sleep 60` was ever spawned.
- power_schedule.sh tested with SYSTEMD_DIR/CRON_D_DIR/BIN_DIR pointed
at scratch dirs and only `sudo systemctl` stubbed (tee/rm/chmod/cp
left real, since they only ever touch scratch paths): full lifecycle
for all four schedule types plus remove-all, the RTC-available branch
(including the wake-time-before-shutdown-time hour/day wraparound
arithmetic) via a stubbed rtc_wake_available, and the new
enable_and_start_timers failure path via a stub that fails `enable`
specifically.
- End-to-end: ran the real install.sh as a genuine non-root, non-
"kiosk" user for both menus. WiFi correctly short-circuits on missing
tools without crashing. Power/Display/Quiet Hours (SYSTEMD_DIR/
CRON_D_DIR/BIN_DIR redirected to scratch space) configured all four
schedule types in sequence including the nested Electron Reload menu,
survived four consecutive real "systemctl enable/start failed"
warnings (this container has no live systemd) without the session
dying, then removed everything - confirmed the scratch dirs ended up
empty and config.json was never touched (correctly out of scope for
this menu).
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Ubuntu Based Kiosk
|
||||
|
||||
**Current Version:** 2.2.0 (check script header for latest version)
|
||||
**Current Version:** 2.3.0 (check script header for latest version)
|
||||
**Built with Claude Sonnet 4.6 AI assistance**
|
||||
**License:** GPL v3 - Keep derivatives open source
|
||||
**Repository:** https://github.com/outis1one/ubuntu-based-kiosk/
|
||||
@@ -1194,6 +1194,14 @@ terminal menu and the web UI, so they can't drift apart).
|
||||
change password, inactivity timeout, daily lock time, boot password.
|
||||
The password is SHA-256 hashed before it's ever written to disk, same
|
||||
as the legacy menu — never stored as plaintext.
|
||||
- `menus/wifi.sh` — **WiFi**: the riskiest menu so far — rewrites live
|
||||
netplan config and, over SSH, can disconnect the session configuring
|
||||
it. Preserves the legacy menu's netplan backup, 60-second SSH
|
||||
watchdog, and restore-on-failure exactly.
|
||||
- `menus/power_schedule.sh` — **Power/Display/Quiet Hours**: scheduled
|
||||
shutdown (+ RTC wake where available), display on/off, quiet-hours
|
||||
audio muting, and an Electron reload timer, each as systemd timers.
|
||||
Can power the physical machine off and on a schedule.
|
||||
- `install.sh` — entry point for the modular tool. Run it against an
|
||||
*already-installed* kiosk:
|
||||
```bash
|
||||
@@ -1205,9 +1213,8 @@ terminal menu and the web UI, so they can't drift apart).
|
||||
**Honest status:** this does not yet replace first-time installation, or
|
||||
most of the old installer. `ubuntu-based-kiosk.sh` is still ~12,000
|
||||
lines and still contains its own unremoved, unmodified copies of every
|
||||
menu above (plus WiFi, Power/Display/Quiet Hours, Upgrade, Reinstall,
|
||||
Uninstall, all Addons, and all of Advanced — none of that has moved
|
||||
yet). Both copies coexist deliberately: the old ones stay until enough
|
||||
menu above (plus Upgrade, Reinstall, Uninstall, all Addons, and all of
|
||||
Advanced — none of that has moved yet). Both copies coexist deliberately: the old ones stay until enough
|
||||
of Core Settings/Addons/Advanced is migrated to
|
||||
retire them in one pass, rather than leaving the legacy menu half-wired.
|
||||
Migration continues one `menus/*.sh` file at a time; first-time
|
||||
@@ -1218,9 +1225,16 @@ at all.
|
||||
|
||||
## Project Status & Future Plans
|
||||
|
||||
**Current Version:** 2.2.0
|
||||
**Current Version:** 2.3.0
|
||||
|
||||
**Recent Updates (v2.2.0):**
|
||||
**Recent Updates (v2.3.0):**
|
||||
- **WiFi and Power/Display/Quiet Hours migrated** — by far the riskiest menus tackled so far. WiFi rewrites live netplan config and, over SSH, can disconnect the session configuring it; power scheduling can shut the physical machine down and wake it via RTC. Every legacy safety mechanism is preserved exactly: netplan backup, 60-second SSH watchdog, restore-on-failure for WiFi; RTC availability detection for power scheduling.
|
||||
- **Bug fix:** the legacy menu refused to open "Configure power schedule" at all without RTC hardware, even though shutdown-only scheduling never needed it.
|
||||
- **Bug fix:** none of the six HH:MM time prompts across these menus were format-validated before — a typo silently produced a broken schedule. All now go through the same `ask_time` validator as everywhere else.
|
||||
- **Bug fix (set -e safety):** several more bare statements whose failure would have killed the entire session — `ls *.yaml` with no netplan file present, the backup-restore reapply after a failed `netplan apply`, and `systemctl enable`/`start` after writing each timer pair. The last was only caught by testing without a live systemd; a real failure on actual hardware would have hit the same crash. All now report a warning and return to the menu.
|
||||
- Deliberately **not** migrated: the legacy "Test schedules & system" option, which leads into a shared diagnostics submenu (audio/network/keyboard tests) unrelated to scheduling — that belongs with a future Advanced/Diagnostics pass.
|
||||
|
||||
**Previous (v2.2.0):**
|
||||
- **Fifth menu migrated:** Password Protection & Lockout (`menus/lockout.sh`) — enable/disable, change password, inactivity timeout, daily lock time, boot password. The password is SHA-256 hashed before it's ever written to `config.json` (matching the Electron app's own comparison logic) — verified never stored as plaintext.
|
||||
- **Bug fix:** `lib/menu.sh` was missing `ask_time`/`validate_time` entirely — caught by testing this menu before it shipped; "set a daily lock time" would otherwise have failed for every user. Ported from the legacy script.
|
||||
- **Refactor:** promoted the ON/OFF toggle-label helper out of `menus/display.sh` into a shared `onoff()` in `lib/menu.sh`, so `menus/lockout.sh` doesn't need to depend on another menu file — menus only ever depend on `lib/`.
|
||||
|
||||
Reference in New Issue
Block a user