Until now ./install.sh only managed an already-installed kiosk; ubuntu-based-kiosk.sh was still the only path from a bare Ubuntu Server box to a running one. install.sh now provisions from scratch too: packages, kiosk user, Node.js/Electron, LightDM+Openbox autologin, audio/video/HDMI/power-button hardware setup, and the firewall, then hands off to the already-migrated Core Settings/Advanced menus for initial configuration instead of reimplementing that logic again. - lib/provision.sh: the new provisioning flow, built mostly by calling existing menus (core_settings_menu, emergency hotspot, virtual consoles) - cuts it to ~300 lines against the legacy script's ~4,000-line first_time_install(). - lib/electron.sh: electron_install_binary() extracted out of menus/advanced_electron.sh so provisioning and the existing "Fix blank screen" action share one implementation. - kiosk-app/ and provision/files/: the Electron app source and every system template file, extracted byte-for-byte out of ubuntu-based-kiosk.sh's heredocs into real files. - Found and fixed a bash set -e gotcha along the way: testing a multi-statement function as an if-condition (`if ! some_func; then`) silently exempts everything inside that function from set -e for the duration of the call. Fixed in the new provisioning code and in menus/advanced_electron.sh's pre-existing repair action, which had the same shape. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VfsFSoRqfbRG7XAg5RoE7e
37 lines
1.3 KiB
Bash
Executable File
37 lines
1.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# Assumes DISPLAY/XAUTHORITY are set (for xrandr) and pactl already has a
|
|
# working PipeWire/pulse socket for the invoking context.
|
|
|
|
QUERY=$(xrandr --query 2>/dev/null)
|
|
[ -z "$QUERY" ] && exit 0
|
|
|
|
PRIMARY_OUTPUT=$(echo "$QUERY" | awk '/ primary/{print $1; exit}')
|
|
[ -z "$PRIMARY_OUTPUT" ] && exit 0
|
|
|
|
EXTERNAL_CONNECTED=$(echo "$QUERY" | awk -v p="$PRIMARY_OUTPUT" '/ connected/ && $1!=p{f=1} END{print (f==1)?"yes":"no"}')
|
|
|
|
HDMI_SINK=$(pactl list sinks short 2>/dev/null | awk 'tolower($2) ~ /hdmi/{print $2; exit}')
|
|
NON_HDMI_SINK=$(pactl list sinks short 2>/dev/null | awk 'tolower($2) !~ /hdmi/{print $2; exit}')
|
|
|
|
route_to() {
|
|
local sink="$1" label="$2"
|
|
if [ -z "$sink" ]; then
|
|
logger "KIOSK: no $label audio sink found, leaving routing unchanged"
|
|
return
|
|
fi
|
|
pactl set-default-sink "$sink" 2>/dev/null \
|
|
&& logger "KIOSK: audio routed to $label sink ($sink)" \
|
|
|| logger "KIOSK: failed to route audio to $label sink ($sink)"
|
|
pactl list sink-inputs short 2>/dev/null | awk '{print $1}' | while read -r sid; do
|
|
pactl move-sink-input "$sid" "$sink" 2>/dev/null
|
|
done
|
|
pactl set-sink-volume "$sink" 100% 2>/dev/null
|
|
pactl set-sink-mute "$sink" 0 2>/dev/null
|
|
}
|
|
|
|
if [ "$EXTERNAL_CONNECTED" = "yes" ]; then
|
|
route_to "$HDMI_SINK" "HDMI"
|
|
else
|
|
route_to "$NON_HDMI_SINK" "built-in"
|
|
fi
|