Commit Graph
6 Commits
Author SHA1 Message Date
Claude d4b75ca1b9 Folder image slideshow sites; Electron 42 -> 44
Slideshow: a site whose path is a local folder (/home/kiosk/photos/, or
any existing directory) plays its images full-screen instead of showing
Chromium's directory listing. kiosk-app/slideshow.js maps the folder URL
to slideshow.html (resolveSiteUrl - used where main.js loads a view and
where attachView re-checks the configured URL) and pushes the image list
into the page from the main process (the page has no fs access), re-read
every minute so added/removed images show up without a restart. Natural
file-name order, crossfade, letterboxed by default; optional
slideshow.json in the folder: interval, shuffle, fit, transition,
recursive. provision_install_app already copies kiosk-app/*.js/*.html,
so new installs and Advanced -> Upgrade pick it up.

Electron: ^42.0.0 -> ^44.0.0. Electron supports the latest three majors
(44/43/42), so 42 drops out when 45 ships. Checked the 43/44 breaking
changes against kiosk-app: nothing it uses changed (no clipboard,
safeStorage, net.request, utilityProcess; BrowserView is deprecated but
still present through 46). The offline bundle builder now retries
Electron's install.js download, which crashes outright if a large
download is cut off mid-stream.

Tested with the real main.js on Electron 44.5.1 under Xvfb + Openbox:
slideshow fills the screen, cycles in order (01, 02, 10) skipping a .txt
file, honours slideshow.json, and an image added mid-run joined the
rotation after the refresh. Offline bundle rebuilt with Electron 44.5.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cjz8a58eB5P9sUweqd3NHm
2026-10-03 14:08:50 +00:00
Claude 5792e201b6 Offline CUPS from the normal menu, local-file sites, build-dep install
- CUPS (Addons -> CUPS Printing, from ./install.sh or the Web UI) now
  installs from the offline bundle by itself when the kiosk can't reach
  the Ubuntu archive: lib/config.sh's run_with_offline_fallback switches
  apt to the bundle (kiosk-offline-apt on) around the install and back
  afterwards. No-op on manual installs or when online.
- Fix cups_is_installed reporting "not installed" for an installed CUPS:
  `dpkg -l | grep -q` under install.sh's pipefail fails when grep exits
  early and dpkg takes SIGPIPE. Uses dpkg-query on the one package now.
- Sites: an absolute path (/home/kiosk/docs/menu.pdf) is accepted and
  turned into a percent-encoded file:// URL, identically in the Sites
  menu (sites_parse_url) and the Web UI (parseUrl, with tests). Electron
  42 shows local HTML, PDFs (built-in viewer) and images as-is.
- iso/build-iso.sh checks its build tools (plus the --offline ones) and
  offers to `sudo apt install` what's missing; --install-deps does it
  without asking. --offline now refuses non-amd64 hosts up front.

Tested: offline chroot of the 26.04.1 server filesystem - action_install_cups
installed CUPS + printer-driver-all/hplip/gutenprint from the bundle with
no network and left apt back on normal sources; webui test suite passes;
Electron 42 rendered a file:// PDF and PNG with spaces/# in the path;
build-iso.sh stopped with the install command when apt-utils was missing
and no TTY, and installed it and built the ISO with --install-deps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cjz8a58eB5P9sUweqd3NHm
2026-10-03 13:29:04 +00:00
Claude a170dc6228 ISO: add --offline bundle so the kiosk installs with no internet
`iso/build-iso.sh --offline` (and the workflow's new `offline` box, on by
default) adds ~420 MB to the ISO and copies it to /opt/kiosk-offline:

- apt/: local repository with every package install.sh's provisioning
  and the CUPS addon install ask for, NodeSource's nodejs, and all
  dependencies a fresh server install doesn't already have. Resolved
  against the source ISO's own package manifest via a synthesized dpkg
  status (iso/offline/fake-dpkg-status.py), so apt downloads only what's
  missing and makes the same virtual/alternative choices as the target.
- npm/: prebuilt kiosk-app (Electron 42, binary included - it no longer
  downloads at npm install time) and Web UI node_modules.

On first boot, kiosk-firstboot installs online as before when there's
internet; with none it waits KIOSK_OFFLINE_WAIT (90s), then runs
`kiosk-offline-apt on` (apt.conf.d drop-in: bundle is the ONLY source)
and turns it off again afterwards. install.sh notices offline mode via
offline_mode_active (lib/config.sh) and installs nodejs from the bundle
and unpacks prebuilt node_modules instead of npm install.

Package lists moved into PROVISION_APT_PACKAGES /
PROVISION_INTEL_APT_PACKAGES / CUPS_APT_PACKAGES so the bundler reads
the same lists install.sh installs from.

Tested: built against the 26.04.1 ISO, then in a network-less chroot of
the ISO's own server filesystem installed every package set, ran
provision_create_kiosk_user/install_nodejs/install_app and
webui_install_app_files in offline mode (Electron runs, no missing
libraries, chrome-sandbox setuid), and ran kiosk-firstboot through the
offline switch with a stub install.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cjz8a58eB5P9sUweqd3NHm
2026-10-03 04:34:32 +00:00
Claude 7f171cf52b Add "Build kiosk ISO" GitHub Actions workflow
Manually triggered (workflow_dispatch): pick interactive /
unattended-kiosk / fully-automatic, optionally pre-set the admin user
(password from the KIOSK_ADMIN_PASSWORD repo secret, never a logged
input), hostname and SSH key. Runs iso/build-iso.sh and uploads the ISO
plus its sha256 as a run artifact (uncompressed, 3-day default retention).

build-iso.sh changes to run in CI:
- Password can come from $KIOSK_ADMIN_PASSWORD; with no TTY and no
  password it fails clearly instead of hanging on a prompt.
- Stage the repo by fetching the commit rather than `git clone --branch`,
  which fails on actions/checkout's detached HEAD; the branch name falls
  back to $GITHUB_REF_NAME, then main, and is set to track origin so
  Advanced -> Upgrade works on the installed kiosk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cjz8a58eB5P9sUweqd3NHm
2026-10-03 03:00:11 +00:00
Claude 0dfc2dd3ef build-iso: reject usernames the Ubuntu installer reserves
Found by an emulated install: Subiquity refuses --username admin (a
system group) at boot with 'Username is reserved by the system', after
the user has already written the stick. Check against subiquity's
reserved-usernames list at build time instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cjz8a58eB5P9sUweqd3NHm
2026-10-03 01:29:32 +00:00
Claude aee6b779eb Add all-in-one Ubuntu Server 26.04 + kiosk install ISO builder
iso/build-iso.sh remasters the official 26.04.x live-server ISO (downloaded
and checksum-verified, or --iso PATH) with xorriso, replaying its BIOS/UEFI
boot records unchanged. It adds:

- /autoinstall.yaml: Subiquity autoinstall that answers locale/keyboard/SSH
  and by default leaves only network, storage and identity interactive
  (--username/--auto-storage/--auto-network/--no-confirm/--fully-automatic
  make those automatic too). late-commands copy the repo (a clone of the
  current HEAD) to /opt/ubuntu-based-kiosk and enable a first-boot service.
- iso/firstboot/kiosk-firstboot(.service): on first boot, takes tty1, waits
  for cloud-init and internet, copies the repo to the admin user's home and
  runs ./install.sh as that user with temporary passwordless sudo (removed
  on every exit path). Failed/interrupted installs re-run next boot.

install.sh hooks for this:
- KIOSK_UNATTENDED=1 makes ask_yes_no take each prompt's default and skips
  the Core Settings menu (--unattended).
- KIOSK_PROVISION_DONE_MARKER is touched by provision_finish before the
  reboot prompt, so the caller can tell a finished install from an
  interrupted one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cjz8a58eB5P9sUweqd3NHm
2026-10-03 01:18:54 +00:00