Fix kiosk mode
This commit is contained in:
+1
-1
@@ -115,7 +115,7 @@ variable "admin_user" {
|
|||||||
variable "enable_kiosk" {
|
variable "enable_kiosk" {
|
||||||
type = bool
|
type = bool
|
||||||
description = "Build-time feature flag for the graphical kiosk (weston + Chromium + mesa). false (default, current) skips the kiosk provisioner entirely — much faster builds and a far smaller image — while iterating on the boot/network stack. Set true to bake the kiosk back in. (kiosk_url=\"\" also skips it; this flag lets you disable without losing the configured URL.)"
|
description = "Build-time feature flag for the graphical kiosk (weston + Chromium + mesa). false (default, current) skips the kiosk provisioner entirely — much faster builds and a far smaller image — while iterating on the boot/network stack. Set true to bake the kiosk back in. (kiosk_url=\"\" also skips it; this flag lets you disable without losing the configured URL.)"
|
||||||
default = false
|
default = true
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "kiosk_url" {
|
variable "kiosk_url" {
|
||||||
|
|||||||
+36
-18
@@ -83,11 +83,29 @@ step 8 and §5). Retire/reset the errata afterward. Needs the design-doc source
|
|||||||
|
|
||||||
## [~] 4. Kiosk mode — autologin + fullscreen Chromium loading a URL
|
## [~] 4. Kiosk mode — autologin + fullscreen Chromium loading a URL
|
||||||
|
|
||||||
**First cut implemented (2026-06-16) — needs a display to verify.** Wayland
|
**WORKING / display-verified 2026-06-17** (kiosk renders Chromium fullscreen on
|
||||||
kiosk + Chromium from EPEL, baked into the root. **cage is NOT packaged for EL9**
|
the configured URL). Build-flagged OFF by default for now (`enable_kiosk=false`)
|
||||||
(`dnf install cage` → "Unable to find a match"), so switched to **weston
|
while iterating on boot/network — set `-var enable_kiosk=true` to ship it.
|
||||||
kiosk-shell** (weston 8.0.0-10.el9 is in EPEL; kiosk-shell.so landed in weston
|
|
||||||
8.0; far lighter than the GDM+gnome-kiosk alternative).
|
Path to getting here (don't re-discover):
|
||||||
|
- **cage is NOT packaged for EL9** (`dnf install cage` → "Unable to find a
|
||||||
|
match"). Tried weston instead.
|
||||||
|
- **EPEL 9 ships weston 8.0**, which has NEITHER `kiosk-shell.so` NOR the
|
||||||
|
`[autolaunch]` weston.ini section — both arrived in **weston 9.0**. The first
|
||||||
|
cut wrongly assumed 8.0 had them; `shell=kiosk-shell.so` failed to load.
|
||||||
|
`rpm -ql weston` shows only desktop-shell / fullscreen-shell / ivi-shell.
|
||||||
|
- **Resolution: `desktop-shell.so`** (the only packaged shell Chromium's
|
||||||
|
xdg-shell works with — fullscreen-shell needs a client protocol Chromium
|
||||||
|
doesn't speak), stripped bare (`panel-position=none`, black bg, no
|
||||||
|
animation/lock), and Chromium launched by a **wrapper** (kiosk-session) since
|
||||||
|
there's no `[autolaunch]`. Chromium `--kiosk` fullscreens over the shell.
|
||||||
|
- **Seat fix (load-bearing):** weston died with `logind: failed to get session
|
||||||
|
seat` → `failed to create compositor backend`. logind's auto-derivation
|
||||||
|
didn't attach a seat; `Environment=XDG_SEAT=seat0` + `XDG_VTNR=1` in the unit
|
||||||
|
(put into the PAM env before pam_open_session) registers the session on
|
||||||
|
seat0/vt1. `/dev/dri/card0` was present all along (not the issue).
|
||||||
|
- Tested live without a rebuild: the whole root is `systemd.volatile=overlay`,
|
||||||
|
so /etc AND /usr are writable tmpfs at runtime — drop-in the files + restart.
|
||||||
- **`enable_kiosk` Packer var — currently `false` by DEFAULT (set 2026-06-17).**
|
- **`enable_kiosk` Packer var — currently `false` by DEFAULT (set 2026-06-17).**
|
||||||
The whole kiosk provisioner is feature-flagged off while iterating on the
|
The whole kiosk provisioner is feature-flagged off while iterating on the
|
||||||
boot/network stack (DHCP-lease/keep-alive work), for faster builds and a
|
boot/network stack (DHCP-lease/keep-alive work), for faster builds and a
|
||||||
@@ -99,19 +117,19 @@ kiosk-shell** (weston 8.0.0-10.el9 is in EPEL; kiosk-shell.so landed in weston
|
|||||||
- Provisioner enables EPEL, installs `weston chromium mesa-dri-drivers
|
- Provisioner enables EPEL, installs `weston chromium mesa-dri-drivers
|
||||||
mesa-libEGL mesa-libgbm dejavu-sans-fonts`, creates a passwordless
|
mesa-libEGL mesa-libgbm dejavu-sans-fonts`, creates a passwordless
|
||||||
unprivileged `kiosk` user (video/input groups).
|
unprivileged `kiosk` user (video/input groups).
|
||||||
- `files/kiosk/kiosk.service` — runs `weston --use-pixman
|
- `files/kiosk/kiosk.service` — runs `/usr/local/bin/kiosk-session` as `kiosk`
|
||||||
--config=/etc/xdg/weston/weston.ini` as `kiosk` on tty1 via
|
on tty1 via `PAMName=login`+`TTYPath`+`Environment=XDG_SEAT=seat0`/`XDG_VTNR=1`
|
||||||
`PAMName=login`+`TTYPath` (gets seat0 for DRM/input), `Conflicts=getty@tty1`,
|
(gets seat0 for DRM/input), `Conflicts=getty@tty1`, `WantedBy=graphical.target`;
|
||||||
`WantedBy=graphical.target`; default target set to graphical.
|
default target set to graphical.
|
||||||
- `files/kiosk/weston.ini` — `shell=kiosk-shell.so`, `idle-time=0`,
|
- `files/kiosk/weston.ini` — `shell=desktop-shell.so`, `idle-time=0`,
|
||||||
`require-input=false`, `xwayland=false`, `[autolaunch] path=/usr/local/bin/
|
`require-input=false`, `xwayland=false`; `[shell] panel-position=none`,
|
||||||
kiosk-session watch=true`.
|
black `background-color`, `animation=none`, `locking=false`.
|
||||||
- `files/kiosk/kiosk-session` — Chromium with `--kiosk --ozone-platform=wayland
|
- `files/kiosk/kiosk-session` — `exec`s `weston --use-pixman --socket=wayland-kiosk`
|
||||||
--disable-gpu` + tmpfs profile/cache; URL from `/etc/kiosk/kiosk.env`.
|
in the foreground (owns the seat), and launches Chromium (`--kiosk
|
||||||
- **Verify on a VM with a console (Proxmox VNC/SPICE):** weston comes up on
|
--ozone-platform=wayland --disable-gpu`, tmpfs profile/cache, URL from
|
||||||
tty1, Chromium loads the URL over the booted network. Likely tweak points:
|
`/etc/kiosk/kiosk.env`) in a background crash-restart loop.
|
||||||
Chromium ozone/wayland support, dropping `--disable-gpu` on real GPUs,
|
- **Remaining polish (now that it renders):** dropping `--disable-gpu` on real
|
||||||
`/dev/dri` present in the VM (weston needs a DRM device — set Display to
|
GPUs, `/dev/dri` present in the VM (weston needs a DRM device — set Display to
|
||||||
VirtIO-GPU/std), and **SELinux AVCs** for the GUI stack (check `ausearch -m
|
VirtIO-GPU/std), and **SELinux AVCs** for the GUI stack (check `ausearch -m
|
||||||
avc`; the kiosk user is unconfined so likely none — but do NOT set permissive
|
avc`; the kiosk user is unconfined so likely none — but do NOT set permissive
|
||||||
if they appear; add a policy module). Admin SSH (the key user) still works for
|
if they appear; add a policy module). Admin SSH (the key user) still works for
|
||||||
|
|||||||
+44
-17
@@ -1,22 +1,49 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# kiosk-session — launched by cage (Wayland) from kiosk.service.
|
# kiosk-session — main process of kiosk.service.
|
||||||
# Starts Chromium fullscreen on the configured URL.
|
|
||||||
#
|
#
|
||||||
# KIOSK_URL comes from /etc/kiosk/kiosk.env (baked from the kiosk_url Packer
|
# Launches the weston compositor in the FOREGROUND (so it owns the logind seat
|
||||||
# var; a runtime config-agent could override it later). The Chromium profile is
|
# session systemd set up via PAMName=login) and, once weston's Wayland socket is
|
||||||
# pinned to a tmpfs path so writes land in RAM (the root is read-only erofs +
|
# up, runs Chromium fullscreen in the BACKGROUND with a crash-restart loop.
|
||||||
# volatile overlay) — watch RAM if the page is heavy.
|
|
||||||
#
|
#
|
||||||
# VM/GPU notes: --disable-gpu + the pixman wlroots renderer (WLR_RENDERER in
|
# Why a wrapper instead of weston.ini [autolaunch]: EPEL 9 ships weston 8.0,
|
||||||
# kiosk.env) keep this working on VMs with no real GPU. On hardware with a GPU,
|
# which has neither kiosk-shell.so nor [autolaunch] (both weston 9.0). So weston
|
||||||
# drop --disable-gpu (and set WLR_RENDERER=gles2) for compositing.
|
# runs desktop-shell.so (see weston.ini) and we start Chromium here.
|
||||||
set -euo pipefail
|
#
|
||||||
|
# Process model: systemd -> this script -> exec weston. The Chromium loop is
|
||||||
|
# forked before the exec, so it lives in the unit's cgroup; when weston exits the
|
||||||
|
# service is torn down (KillMode=control-group) and the loop dies with it. If
|
||||||
|
# Chromium alone crashes, the loop relaunches it without taking weston down.
|
||||||
|
#
|
||||||
|
# KIOSK_URL comes from /etc/kiosk/kiosk.env. The Chromium profile/cache live on
|
||||||
|
# tmpfs (root is read-only erofs + volatile overlay) — writes land in RAM; watch
|
||||||
|
# RAM if the page is heavy (it can starve the NVMe-oF keep-alive — see TODO).
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
BROWSER=$(command -v chromium-browser || command -v chromium)
|
: "${KIOSK_URL:?KIOSK_URL not set in /etc/kiosk/kiosk.env}"
|
||||||
|
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
|
||||||
|
SOCK=wayland-kiosk
|
||||||
|
|
||||||
exec "$BROWSER" \
|
BROWSER=$(command -v chromium-browser || command -v chromium || true)
|
||||||
--kiosk --noerrdialogs --disable-infobars --incognito --no-first-run \
|
: "${BROWSER:?chromium not found (expected chromium-browser or chromium in PATH)}"
|
||||||
--disable-session-crashed-bubble --start-maximized \
|
|
||||||
--ozone-platform=wayland --disable-gpu \
|
# Background: wait (up to ~60s) for weston's socket, then keep Chromium running.
|
||||||
--user-data-dir=/tmp/kiosk-profile --disk-cache-dir=/tmp/kiosk-cache \
|
(
|
||||||
"${KIOSK_URL:?KIOSK_URL not set in /etc/kiosk/kiosk.env}"
|
for _ in $(seq 1 120); do
|
||||||
|
[ -S "$XDG_RUNTIME_DIR/$SOCK" ] && break
|
||||||
|
sleep 0.5
|
||||||
|
done
|
||||||
|
export WAYLAND_DISPLAY="$SOCK"
|
||||||
|
while :; do
|
||||||
|
"$BROWSER" \
|
||||||
|
--kiosk --noerrdialogs --disable-infobars --incognito --no-first-run \
|
||||||
|
--disable-session-crashed-bubble --start-maximized \
|
||||||
|
--ozone-platform=wayland --disable-gpu \
|
||||||
|
--user-data-dir=/tmp/kiosk-profile --disk-cache-dir=/tmp/kiosk-cache \
|
||||||
|
"$KIOSK_URL" || true
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
) &
|
||||||
|
|
||||||
|
# weston as the foreground process (owns the seat; service restarts if it dies).
|
||||||
|
# desktop-shell + explicit socket; --use-pixman = software rendering for VMs.
|
||||||
|
exec weston --use-pixman --socket="$SOCK" --config=/etc/xdg/weston/weston.ini
|
||||||
|
|||||||
+14
-10
@@ -1,5 +1,5 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Wayland kiosk (weston kiosk-shell + Chromium)
|
Description=Wayland kiosk (weston desktop-shell + Chromium)
|
||||||
Documentation=man:weston(1) man:weston.ini(5)
|
Documentation=man:weston(1) man:weston.ini(5)
|
||||||
# Take over tty1 from the login getty and start after the network is up (the
|
# Take over tty1 from the login getty and start after the network is up (the
|
||||||
# kiosk loads a URL). plymouth-quit lets the splash hand off cleanly.
|
# kiosk loads a URL). plymouth-quit lets the splash hand off cleanly.
|
||||||
@@ -10,10 +10,15 @@ Conflicts=getty@tty1.service
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
User=kiosk
|
User=kiosk
|
||||||
# A real PAM login session on tty1 so logind assigns seat0 — cage/wlroots needs
|
# A real PAM login session on tty1 so logind assigns seat0 — weston needs a seat
|
||||||
# a seat for DRM master + libinput. (PAMName runs account/session, not auth, so
|
# for DRM master + libinput. (PAMName runs account/session, not auth, so the
|
||||||
# the passwordless kiosk user is fine.)
|
# passwordless kiosk user is fine.) XDG_SEAT/XDG_VTNR are set into the PAM
|
||||||
|
# environment before pam_open_session, so pam_systemd registers the session on
|
||||||
|
# seat0/vt1 — WITHOUT them logind's auto-derivation failed and weston died with
|
||||||
|
# "logind: failed to get session seat" -> "failed to create compositor backend".
|
||||||
PAMName=login
|
PAMName=login
|
||||||
|
Environment=XDG_SEAT=seat0
|
||||||
|
Environment=XDG_VTNR=1
|
||||||
TTYPath=/dev/tty1
|
TTYPath=/dev/tty1
|
||||||
TTYReset=yes
|
TTYReset=yes
|
||||||
TTYVHangup=yes
|
TTYVHangup=yes
|
||||||
@@ -24,12 +29,11 @@ StandardError=journal
|
|||||||
UtmpIdentifier=tty1
|
UtmpIdentifier=tty1
|
||||||
UtmpMode=user
|
UtmpMode=user
|
||||||
EnvironmentFile=/etc/kiosk/kiosk.env
|
EnvironmentFile=/etc/kiosk/kiosk.env
|
||||||
# weston with kiosk-shell (every app fullscreen). --use-pixman = software
|
# kiosk-session launches weston (foreground, owns the seat) + Chromium. weston
|
||||||
# rendering for VMs/no-GPU. weston.ini's [autolaunch] runs /usr/local/bin/
|
# 8.0 (EPEL 9) lacks kiosk-shell.so/[autolaunch], so the wrapper does what those
|
||||||
# kiosk-session (Chromium) and, with watch=true, weston exits if it dies — so
|
# would have — see kiosk-session and weston.ini. If weston dies, Restart=always
|
||||||
# Restart=always relaunches the whole stack. cage (the original choice) isn't
|
# relaunches the whole stack; a Chromium-only crash is handled inside the wrapper.
|
||||||
# packaged for EL9; weston kiosk-shell is the minimal EL9-available equivalent.
|
ExecStart=/usr/local/bin/kiosk-session
|
||||||
ExecStart=/usr/bin/weston --use-pixman --config=/etc/xdg/weston/weston.ini
|
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
|
|
||||||
|
|||||||
+16
-9
@@ -1,12 +1,15 @@
|
|||||||
# weston kiosk configuration (consumed by kiosk.service: weston --config=...).
|
# weston kiosk configuration (consumed by kiosk-session: weston --config=...).
|
||||||
#
|
#
|
||||||
# kiosk-shell makes every client fullscreen with no decorations/desktop — the
|
# Target is EPEL 9's weston 8.0, which has NEITHER kiosk-shell.so NOR the
|
||||||
# kiosk behaviour cage gave us. The [autolaunch] app is the Chromium wrapper;
|
# [autolaunch] section (both arrived in weston 9.0). So we use desktop-shell.so —
|
||||||
# watch=true makes weston exit when it exits, so kiosk.service (Restart=always)
|
# the only packaged shell that Chromium's xdg-shell surfaces work with — stripped
|
||||||
# relaunches the whole stack on a browser crash.
|
# down to a bare black surface, and launch Chromium ourselves from kiosk-session.
|
||||||
|
# Chromium --kiosk then fullscreens over this shell.
|
||||||
|
|
||||||
[core]
|
[core]
|
||||||
shell=kiosk-shell.so
|
# desktop-shell.so is the shell; fullscreen-shell needs a special client protocol
|
||||||
|
# Chromium doesn't speak, and kiosk-shell isn't in this weston.
|
||||||
|
shell=desktop-shell.so
|
||||||
# No screen blanking on a kiosk.
|
# No screen blanking on a kiosk.
|
||||||
idle-time=0
|
idle-time=0
|
||||||
# Don't refuse to start if no input device is present (headless/VM consoles).
|
# Don't refuse to start if no input device is present (headless/VM consoles).
|
||||||
@@ -14,6 +17,10 @@ require-input=false
|
|||||||
# No X11 apps here — Chromium runs native Wayland (--ozone-platform=wayland).
|
# No X11 apps here — Chromium runs native Wayland (--ozone-platform=wayland).
|
||||||
xwayland=false
|
xwayland=false
|
||||||
|
|
||||||
[autolaunch]
|
[shell]
|
||||||
path=/usr/local/bin/kiosk-session
|
# Bare kiosk surface: no panel, solid black background, no animations, no lock.
|
||||||
watch=true
|
# Chromium --kiosk draws fullscreen on top of this.
|
||||||
|
panel-position=none
|
||||||
|
background-color=0xff000000
|
||||||
|
animation=none
|
||||||
|
locking=false
|
||||||
|
|||||||
Reference in New Issue
Block a user