diff --git a/squashdisplay/README.txt b/squashdisplay/README.txt new file mode 100644 index 0000000..8e428c5 --- /dev/null +++ b/squashdisplay/README.txt @@ -0,0 +1,137 @@ +Squash Display Kiosk Template +============================== + +This template configures a Raspberry Pi or Linux system as a dedicated kiosk display +that automatically boots to a fullscreen web browser showing a specified URL. + +IMPORTANT: This template makes SYSTEM-LEVEL changes to the host machine, including +installing packages, configuring auto-login, and modifying system services. + +REQUIREMENTS +------------ +* Raspberry Pi or Linux system with HDMI output +* Fresh Raspberry Pi OS Lite installation (recommended) +* Docker installed (for running setup) +* Internet connection for package installation +* Target URL to display + +WHAT IT DOES +------------ +This template automates the complete kiosk setup process: +1. Installs required packages (Chromium, X server, utilities) +2. Creates/configures kiosk user account +3. Sets up auto-login on boot +4. Configures X server to start automatically +5. Launches Chromium in kiosk mode +6. Disables screen blanking and power management +7. Optional watchdog to restart browser if it crashes +8. Configures GPU memory for better performance (RPi) + +CONFIGURATION +------------- +Key settings in service.env: + +* KIOSK_URL - The webpage to display (required) +* KIOSK_USER - System user for kiosk (default: squash) +* DISPLAY_WIDTH/HEIGHT/REFRESH - Display resolution +* GPU_MEM - GPU memory allocation in MB (RPi only) +* ENABLE_WATCHDOG - Auto-restart crashed browser +* ENABLE_AUTO_LOGIN - Boot directly to kiosk +* ENABLE_HDMI_KEEP_ALIVE - Prevent display sleep + +INSTALLATION +------------ +1. Configure your settings in the service configuration +2. Run: ./install.sh +3. Confirm system modifications when prompted +4. REBOOT the system: sudo reboot +5. System will auto-start in kiosk mode + +The installation uses a privileged Docker container to make the +necessary system changes. This is intentional and required. + +USAGE +----- +After installation and reboot: +- System boots directly to kiosk display +- No keyboard/mouse needed for normal operation +- Browser runs in fullscreen kiosk mode +- Automatic recovery from crashes (if watchdog enabled) + +COMMANDS +-------- +* ./install.sh - Install and configure kiosk +* ./status.sh - Check kiosk and configuration status +* ./configure.sh - Update kiosk settings (URL, display, etc.) +* ./logs.sh - View setup and system logs +* ./uninstall.sh - Remove Docker container (not system changes) +* ./start.sh - Re-run setup (rarely needed) +* ./stop.sh - Stop setup container + +MANUAL TESTING +-------------- +To test the kiosk without rebooting: + sudo -u squash startx /home/squash/kiosk.sh + +To exit kiosk mode during testing: + Alt+F4 or Ctrl+Alt+Backspace + +TROUBLESHOOTING +--------------- +1. Black screen after reboot: + - Check X server: ps aux | grep X + - View logs: journalctl -u getty@tty1 + - Check script: cat /home/squash/kiosk.sh + +2. Browser won't start: + - Test manually: chromium-browser + - Check logs: ./logs.sh + - Verify packages: dpkg -l | grep chromium + +3. Wrong resolution: + - Check available modes: xrandr + - Update settings: ./configure.sh + - Verify HDMI connection + +4. Page doesn't load: + - Check network: ping google.com + - Test URL: curl YOUR_URL + - Verify in browser: chromium-browser YOUR_URL + +5. Screen goes to sleep: + - Check power settings: xset q + - Verify HDMI service: systemctl status hdmi-keep-alive + +CUSTOMIZATION +------------- +To modify kiosk behavior: +1. Edit /home/squash/kiosk.sh for browser options +2. Edit /home/squash/.bashrc for startup behavior +3. Use ./configure.sh to update URL and display settings + +SECURITY NOTES +-------------- +* Kiosk mode disables many browser security features +* No authentication required for physical access +* Consider network isolation for public displays +* Regular updates still recommended for security + +UNINSTALLING +------------ +The uninstall.sh script only removes the Docker container. +To fully remove kiosk configuration: + +1. Remove auto-login: + sudo rm /etc/systemd/system/getty@tty1.service.d/autologin.conf + +2. Remove kiosk scripts: + rm /home/squash/kiosk.sh /home/squash/watchdog.sh + +3. Re-enable updates: + sudo systemctl enable apt-daily.service apt-daily.timer + +4. Remove packages (optional): + sudo apt remove chromium-browser xorg xinit unclutter + +5. Remove user (optional): + sudo userdel -r squash \ No newline at end of file diff --git a/squashdisplay/config/.template_info.env b/squashdisplay/config/.template_info.env new file mode 100644 index 0000000..77db7c3 --- /dev/null +++ b/squashdisplay/config/.template_info.env @@ -0,0 +1,28 @@ +# DO NOT EDIT THIS FILE FOR YOUR SERVICE! +# This file is replaced from the template whenever there is an update. +# Edit the service.env file to make changes. + +# Template to use - always required! +TEMPLATE=squashdisplay +REQUIRES_HOST_ROOT=true +REQUIRES_DOCKER=true +REQUIRES_DOCKER_ROOT=true + +# Service settings +CONTAINER_NAME=squashdisplay + +# Image settings - using Alpine for lightweight host configuration +IMAGE_REGISTRY="docker.io" +IMAGE_REPO="alpine" +IMAGE_TAG="latest" + +# Kiosk Configuration Defaults +KIOSK_URL="https://squash.kiwi/court/otog" +KIOSK_USER="squash" +DISPLAY_WIDTH="1920" +DISPLAY_HEIGHT="1080" +DISPLAY_REFRESH="60" +GPU_MEM="256" +ENABLE_WATCHDOG="true" +ENABLE_AUTO_LOGIN="true" +ENABLE_HDMI_KEEP_ALIVE="true" \ No newline at end of file diff --git a/squashdisplay/config/service.env b/squashdisplay/config/service.env new file mode 100644 index 0000000..41035e8 --- /dev/null +++ b/squashdisplay/config/service.env @@ -0,0 +1,24 @@ +# Service settings for Squash Display Kiosk +# (can also override anything in the .template_info.env file in the template to make it specific to this server) + +# REQUIRED: URL to display in kiosk mode +KIOSK_URL="https://squash.kiwi/court/otog" + +# User account that will run the kiosk (must exist on the system) +KIOSK_USER="squash" + +# Display settings +DISPLAY_WIDTH="1920" +DISPLAY_HEIGHT="1080" +DISPLAY_REFRESH="60" + +# GPU memory allocation (MB) - higher values improve browser performance +GPU_MEM="256" + +# Enable features (true/false) +ENABLE_WATCHDOG="true" # Auto-restart browser if it crashes +ENABLE_AUTO_LOGIN="true" # Auto-login on boot +ENABLE_HDMI_KEEP_ALIVE="true" # Prevent HDMI from sleeping + +# Server Settings +SSH_USER="dropshell" \ No newline at end of file diff --git a/squashdisplay/configure.sh b/squashdisplay/configure.sh new file mode 100755 index 0000000..0370cbb --- /dev/null +++ b/squashdisplay/configure.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# shellcheck disable=SC1091 +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "KIOSK_USER" "KIOSK_URL" + +# Squash Display Configure Script - Update kiosk settings + +echo "Squash Display Configuration Update" +echo "====================================" + +echo "" +echo "This will update the kiosk configuration with current settings:" +echo " URL: ${KIOSK_URL}" +echo " Display: ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}@${DISPLAY_REFRESH}Hz" +echo "" + +# Update kiosk.sh script +if [ -f "/home/${KIOSK_USER}/kiosk.sh" ]; then + echo "Updating kiosk script..." + + # Create updated script + cat <<'EOF' | sudo tee /home/${KIOSK_USER}/kiosk.sh.new > /dev/null +#!/bin/bash + +# Disable screen blanking and power management +xset s noblank +xset s off +xset -dpms + +# Hide cursor after 1 second of inactivity +unclutter -idle 1 & + +# Force display resolution +xrandr --output HDMI-1 --mode DISPLAY_WIDTH_PLACEHOLDERxDISPLAY_HEIGHT_PLACEHOLDER --rate DISPLAY_REFRESH_PLACEHOLDER 2>/dev/null || \ +xrandr --output HDMI-2 --mode DISPLAY_WIDTH_PLACEHOLDERxDISPLAY_HEIGHT_PLACEHOLDER --rate DISPLAY_REFRESH_PLACEHOLDER 2>/dev/null || \ +xrandr --output default --mode DISPLAY_WIDTH_PLACEHOLDERxDISPLAY_HEIGHT_PLACEHOLDER --rate DISPLAY_REFRESH_PLACEHOLDER 2>/dev/null || true + +# Start Chromium in kiosk mode +chromium-browser \ + --window-size=DISPLAY_WIDTH_PLACEHOLDER,DISPLAY_HEIGHT_PLACEHOLDER \ + --window-position=0,0 \ + --noerrdialogs \ + --disable-infobars \ + --disable-features=TranslateUI \ + --disable-extensions \ + --disable-plugins \ + --disable-web-security \ + --disable-features=VizDisplayCompositor \ + --start-fullscreen \ + --kiosk \ + --incognito \ + --no-first-run \ + --fast \ + --fast-start \ + --disable-default-apps \ + --disable-translate \ + --disable-background-timer-throttling \ + --disable-renderer-backgrounding \ + --disable-backgrounding-occluded-windows \ + --disable-component-extensions-with-background-pages \ + --autoplay-policy=no-user-gesture-required \ + "KIOSK_URL_PLACEHOLDER" +EOF + + # Replace placeholders with actual values + sudo sed -i "s|DISPLAY_WIDTH_PLACEHOLDER|${DISPLAY_WIDTH}|g" /home/${KIOSK_USER}/kiosk.sh.new + sudo sed -i "s|DISPLAY_HEIGHT_PLACEHOLDER|${DISPLAY_HEIGHT}|g" /home/${KIOSK_USER}/kiosk.sh.new + sudo sed -i "s|DISPLAY_REFRESH_PLACEHOLDER|${DISPLAY_REFRESH}|g" /home/${KIOSK_USER}/kiosk.sh.new + sudo sed -i "s|KIOSK_URL_PLACEHOLDER|${KIOSK_URL}|g" /home/${KIOSK_USER}/kiosk.sh.new + + # Replace old script + sudo mv /home/${KIOSK_USER}/kiosk.sh.new /home/${KIOSK_USER}/kiosk.sh + sudo chmod +x /home/${KIOSK_USER}/kiosk.sh + sudo chown ${KIOSK_USER}:${KIOSK_USER} /home/${KIOSK_USER}/kiosk.sh + + echo "✓ Kiosk script updated" +else + echo "✗ Kiosk script not found at /home/${KIOSK_USER}/kiosk.sh" + echo " Run installation first: ./install.sh" + exit 1 +fi + +# Update GPU memory if on Raspberry Pi +if [ -f "/boot/firmware/config.txt" ] || [ -f "/boot/config.txt" ]; then + echo "Updating GPU memory allocation..." + CONFIG_FILE="/boot/firmware/config.txt" + [ -f "/boot/config.txt" ] && CONFIG_FILE="/boot/config.txt" + + if ! grep -q "^gpu_mem=" ${CONFIG_FILE}; then + echo "gpu_mem=${GPU_MEM}" | sudo tee -a ${CONFIG_FILE} > /dev/null + else + sudo sed -i "s/^gpu_mem=.*/gpu_mem=${GPU_MEM}/" ${CONFIG_FILE} + fi + echo "✓ GPU memory set to ${GPU_MEM}MB" +fi + +# Restart kiosk if it's running +if pgrep -f "chromium.*--kiosk" >/dev/null 2>&1; then + echo "" + echo "Restarting kiosk with new configuration..." + + # Kill existing Chromium process + pkill -f "chromium.*--kiosk" + + # Give it a moment + sleep 2 + + # If watchdog is enabled, it will restart automatically + if [ "${ENABLE_WATCHDOG}" = "true" ]; then + echo "Watchdog will restart the kiosk automatically..." + else + # Manual restart + echo "Starting kiosk manually..." + sudo -u ${KIOSK_USER} DISPLAY=:0 /home/${KIOSK_USER}/kiosk.sh & + fi + + echo "✓ Kiosk restarted with new configuration" +else + echo "" + echo "Kiosk is not currently running." + echo "Configuration will be applied on next start." +fi + +echo "" +echo "Configuration update complete!" +echo "" +echo "Current settings:" +echo " URL: ${KIOSK_URL}" +echo " Display: ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}@${DISPLAY_REFRESH}Hz" +echo " GPU Memory: ${GPU_MEM}MB" +echo "" +echo "To apply all changes, you may need to reboot: sudo reboot" \ No newline at end of file diff --git a/squashdisplay/install.sh b/squashdisplay/install.sh new file mode 100755 index 0000000..f98563a --- /dev/null +++ b/squashdisplay/install.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# shellcheck disable=SC1091 +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" "IMAGE_REGISTRY" "IMAGE_REPO" "IMAGE_TAG" "KIOSK_URL" "KIOSK_USER" + +# Check if URL is set +if [ -z "$KIOSK_URL" ] || [ "$KIOSK_URL" = "" ]; then + _die "KIOSK_URL is not set in config/service.env! Please set the URL to display." +fi + +# Check if user is set +if [ -z "$KIOSK_USER" ] || [ "$KIOSK_USER" = "" ]; then + _die "KIOSK_USER is not set in config/service.env! Please set the user account for the kiosk." +fi + +_check_docker_installed || _die "Docker test failed, aborting installation..." + +echo "Installing Squash Display kiosk service..." +echo "" +echo "WARNING: This will make system-level changes to configure kiosk mode." +echo "Changes include:" +echo " - Installing Chromium browser and X server packages" +echo " - Configuring auto-login for user: ${KIOSK_USER}" +echo " - Setting up kiosk scripts" +echo " - Disabling automatic updates" +echo " - Configuring display settings" +echo "" +read -p "Do you want to continue? (yes/no): " confirmation + +if [ "$confirmation" != "yes" ]; then + echo "Installation cancelled." + exit 0 +fi + +echo "Pulling Docker image..." +docker pull "$IMAGE_REGISTRY/$IMAGE_REPO:$IMAGE_TAG" || _die "Failed to pull image $IMAGE_REGISTRY/$IMAGE_REPO:$IMAGE_TAG" + +# Stop and remove existing container if it exists +if _is_container_exists "$CONTAINER_NAME"; then + echo "Removing existing container..." + bash ./stop.sh 2>/dev/null || true + _remove_container "$CONTAINER_NAME" || true +fi + +# Make scripts executable +chmod +x ${SERVICE_PATH}/scripts/*.sh + +# Start the setup container +bash ./start.sh || _die "Failed to start Squash Display setup" + +echo "" +echo "==========================================" +echo "Squash Display installation complete!" +echo "==========================================" +echo "" +echo "Next steps:" +echo "1. REBOOT THE SYSTEM for all changes to take effect" +echo " sudo reboot" +echo "" +echo "2. After reboot, the system will:" +echo " - Auto-login as user: ${KIOSK_USER}" +echo " - Start X server automatically" +echo " - Launch Chromium in kiosk mode" +echo " - Display: ${KIOSK_URL}" +echo "" +echo "3. To check status: ds status [server] squashdisplay" +echo "4. To reconfigure: ds exec [server] squashdisplay configure" +echo "" +echo "Troubleshooting:" +echo "- Check logs: journalctl -u getty@tty1" +echo "- View X server logs: cat /home/${KIOSK_USER}/.local/share/xorg/Xorg.0.log" +echo "- Manual test: sudo -u ${KIOSK_USER} startx /home/${KIOSK_USER}/kiosk.sh" \ No newline at end of file diff --git a/squashdisplay/logs.sh b/squashdisplay/logs.sh new file mode 100755 index 0000000..a09ab1a --- /dev/null +++ b/squashdisplay/logs.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# shellcheck disable=SC1091 +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" "KIOSK_USER" + +# Squash Display Logs Script + +echo "Squash Display Logs" +echo "===================" + +# Check if we should follow logs +FOLLOW="" +if [ "$1" = "-f" ] || [ "$1" = "--follow" ]; then + FOLLOW="-f" +fi + +# Show setup container logs if it exists +if _is_container_exists "$CONTAINER_NAME"; then + echo "" + echo "Setup Container Logs:" + echo "--------------------" + docker logs ${FOLLOW} ${CONTAINER_NAME} 2>&1 +fi + +# Show system logs related to kiosk +echo "" +echo "System Kiosk Logs:" +echo "-----------------" +echo "Auto-login service (getty@tty1):" +if [ -n "$FOLLOW" ]; then + echo "Following logs (Ctrl+C to stop)..." + journalctl -u getty@tty1 -f +else + journalctl -u getty@tty1 -n 50 --no-pager + + echo "" + echo "X server logs (if available):" + if [ -f "/home/${KIOSK_USER}/.local/share/xorg/Xorg.0.log" ]; then + tail -50 /home/${KIOSK_USER}/.local/share/xorg/Xorg.0.log + else + echo "No X server logs found" + fi + + echo "" + echo "Watchdog logs (if available):" + if [ -f "/home/${KIOSK_USER}/watchdog.log" ]; then + tail -20 /home/${KIOSK_USER}/watchdog.log + else + echo "No watchdog logs found" + fi + + echo "" + echo "Tip: Use './logs.sh -f' to follow logs in real-time" +fi \ No newline at end of file diff --git a/squashdisplay/scripts/kiosk.sh b/squashdisplay/scripts/kiosk.sh new file mode 100755 index 0000000..448b183 --- /dev/null +++ b/squashdisplay/scripts/kiosk.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# Kiosk startup script for Chromium browser + +# Disable screen blanking and power management +xset s noblank +xset s off +xset -dpms + +# Hide cursor after 1 second of inactivity +unclutter -idle 1 & + +# Force display resolution +xrandr --output HDMI-1 --mode ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT} --rate ${DISPLAY_REFRESH} 2>/dev/null || \ +xrandr --output HDMI-2 --mode ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT} --rate ${DISPLAY_REFRESH} 2>/dev/null || \ +xrandr --output default --mode ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT} --rate ${DISPLAY_REFRESH} 2>/dev/null || true + +# Start Chromium in kiosk mode +chromium-browser \ + --window-size=${DISPLAY_WIDTH},${DISPLAY_HEIGHT} \ + --window-position=0,0 \ + --noerrdialogs \ + --disable-infobars \ + --disable-features=TranslateUI \ + --disable-extensions \ + --disable-plugins \ + --disable-web-security \ + --disable-features=VizDisplayCompositor \ + --start-fullscreen \ + --kiosk \ + --incognito \ + --no-first-run \ + --fast \ + --fast-start \ + --disable-default-apps \ + --disable-translate \ + --disable-background-timer-throttling \ + --disable-renderer-backgrounding \ + --disable-backgrounding-occluded-windows \ + --disable-component-extensions-with-background-pages \ + --autoplay-policy=no-user-gesture-required \ + "${KIOSK_URL}" \ No newline at end of file diff --git a/squashdisplay/scripts/setup-host.sh b/squashdisplay/scripts/setup-host.sh new file mode 100755 index 0000000..407237e --- /dev/null +++ b/squashdisplay/scripts/setup-host.sh @@ -0,0 +1,180 @@ +#!/bin/sh +# Host setup script - runs inside privileged container to configure the host + +set -e + +echo "Starting Squash Display kiosk setup..." + +# Function to run commands on the host +host_exec() { + nsenter -t 1 -m -u -i -n -p -- "$@" +} + +# Install required packages +echo "Installing required packages..." +host_exec apt-get update +host_exec apt-get install -y chromium-browser xorg xinit x11-xserver-utils unclutter || \ +host_exec apt-get install -y chromium xorg xinit x11-xserver-utils unclutter + +# Create kiosk user if it doesn't exist +if ! host_exec id -u ${KIOSK_USER} >/dev/null 2>&1; then + echo "Creating user ${KIOSK_USER}..." + host_exec useradd -m -s /bin/bash ${KIOSK_USER} + host_exec usermod -aG video,audio ${KIOSK_USER} +fi + +# Setup auto-login if enabled +if [ "${ENABLE_AUTO_LOGIN}" = "true" ]; then + echo "Configuring auto-login for ${KIOSK_USER}..." + + # Create systemd override for getty@tty1 + host_exec mkdir -p /etc/systemd/system/getty@tty1.service.d + cat </dev/null || \ +xrandr --output HDMI-2 --mode ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT} --rate ${DISPLAY_REFRESH} 2>/dev/null || \ +xrandr --output default --mode ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT} --rate ${DISPLAY_REFRESH} 2>/dev/null || true + +# Start Chromium in kiosk mode +chromium-browser \ + --window-size=${DISPLAY_WIDTH},${DISPLAY_HEIGHT} \ + --window-position=0,0 \ + --noerrdialogs \ + --disable-infobars \ + --disable-features=TranslateUI \ + --disable-extensions \ + --disable-plugins \ + --disable-web-security \ + --disable-features=VizDisplayCompositor \ + --start-fullscreen \ + --kiosk \ + --incognito \ + --no-first-run \ + --fast \ + --fast-start \ + --disable-default-apps \ + --disable-translate \ + --disable-background-timer-throttling \ + --disable-renderer-backgrounding \ + --disable-backgrounding-occluded-windows \ + --disable-component-extensions-with-background-pages \ + --autoplay-policy=no-user-gesture-required \ + "${KIOSK_URL}" +EOF + +# Substitute environment variables +host_exec sed -i "s|\${DISPLAY_WIDTH}|${DISPLAY_WIDTH}|g" /home/${KIOSK_USER}/kiosk.sh +host_exec sed -i "s|\${DISPLAY_HEIGHT}|${DISPLAY_HEIGHT}|g" /home/${KIOSK_USER}/kiosk.sh +host_exec sed -i "s|\${DISPLAY_REFRESH}|${DISPLAY_REFRESH}|g" /home/${KIOSK_USER}/kiosk.sh +host_exec sed -i "s|\${KIOSK_URL}|${KIOSK_URL}|g" /home/${KIOSK_USER}/kiosk.sh + +host_exec chmod +x /home/${KIOSK_USER}/kiosk.sh +host_exec chown ${KIOSK_USER}:${KIOSK_USER} /home/${KIOSK_USER}/kiosk.sh + +# Setup watchdog if enabled +if [ "${ENABLE_WATCHDOG}" = "true" ]; then + echo "Setting up watchdog script..." + cat <<'EOF' | host_exec tee /home/${KIOSK_USER}/watchdog.sh +#!/bin/bash +while true; do + if ! pgrep chromium > /dev/null; then + echo "$(date): Chromium not running, restarting..." >> /home/${KIOSK_USER}/watchdog.log + DISPLAY=:0 /home/${KIOSK_USER}/kiosk.sh & + fi + sleep 30 +done +EOF + host_exec sed -i "s|\${KIOSK_USER}|${KIOSK_USER}|g" /home/${KIOSK_USER}/watchdog.sh + host_exec chmod +x /home/${KIOSK_USER}/watchdog.sh + host_exec chown ${KIOSK_USER}:${KIOSK_USER} /home/${KIOSK_USER}/watchdog.sh +fi + +# Configure .bashrc for auto-start +echo "Configuring auto-start..." +if ! host_exec grep -q "Auto-start X server" /home/${KIOSK_USER}/.bashrc 2>/dev/null; then + cat <<'EOF' | host_exec tee -a /home/${KIOSK_USER}/.bashrc + +# Auto-start X server and kiosk on login +if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]; then + exec startx ~/kiosk.sh +fi + +# Start watchdog in background +if [ "${ENABLE_WATCHDOG}" = "true" ]; then + ~/watchdog.sh & +fi +EOF + host_exec sed -i "s|\${ENABLE_WATCHDOG}|${ENABLE_WATCHDOG}|g" /home/${KIOSK_USER}/.bashrc +fi + +# Disable automatic updates +echo "Disabling automatic updates..." +host_exec systemctl disable apt-daily.service 2>/dev/null || true +host_exec systemctl disable apt-daily.timer 2>/dev/null || true +host_exec systemctl disable apt-daily-upgrade.timer 2>/dev/null || true +host_exec systemctl disable apt-daily-upgrade.service 2>/dev/null || true + +# Configure GPU memory split (Raspberry Pi specific) +if host_exec test -f /boot/firmware/config.txt || host_exec test -f /boot/config.txt; then + echo "Configuring GPU memory split..." + CONFIG_FILE="/boot/firmware/config.txt" + host_exec test -f /boot/config.txt && CONFIG_FILE="/boot/config.txt" + + if ! host_exec grep -q "^gpu_mem=" ${CONFIG_FILE}; then + echo "gpu_mem=${GPU_MEM}" | host_exec tee -a ${CONFIG_FILE} + else + host_exec sed -i "s/^gpu_mem=.*/gpu_mem=${GPU_MEM}/" ${CONFIG_FILE} + fi +fi + +# Setup HDMI keep-alive service if enabled +if [ "${ENABLE_HDMI_KEEP_ALIVE}" = "true" ]; then + echo "Setting up HDMI keep-alive service..." + cat <<'EOF' | host_exec tee /etc/systemd/system/hdmi-keep-alive.service +[Unit] +Description=Keep HDMI active +After=graphical.target + +[Service] +Type=simple +ExecStart=/bin/sh -c 'while true; do tvservice -p 2>/dev/null || true; sleep 60; done' +Restart=always +RestartSec=10 + +[Install] +WantedBy=graphical.target +EOF + host_exec systemctl daemon-reload + host_exec systemctl enable hdmi-keep-alive.service 2>/dev/null || true +fi + +echo "Squash Display kiosk setup complete!" +echo "" +echo "Configuration:" +echo " URL: ${KIOSK_URL}" +echo " User: ${KIOSK_USER}" +echo " Display: ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}@${DISPLAY_REFRESH}Hz" +echo " Watchdog: ${ENABLE_WATCHDOG}" +echo " Auto-login: ${ENABLE_AUTO_LOGIN}" +echo "" +echo "Please reboot the system for all changes to take effect." \ No newline at end of file diff --git a/squashdisplay/scripts/watchdog.sh b/squashdisplay/scripts/watchdog.sh new file mode 100755 index 0000000..9277ef1 --- /dev/null +++ b/squashdisplay/scripts/watchdog.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Watchdog script to restart Chromium if it crashes + +while true; do + if ! pgrep chromium > /dev/null; then + echo "$(date): Chromium not running, restarting..." + DISPLAY=:0 /home/${KIOSK_USER}/kiosk.sh & + fi + sleep 30 +done \ No newline at end of file diff --git a/squashdisplay/start.sh b/squashdisplay/start.sh new file mode 100755 index 0000000..0e265bd --- /dev/null +++ b/squashdisplay/start.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# shellcheck disable=SC1091 +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" "IMAGE_REGISTRY" "IMAGE_REPO" "IMAGE_TAG" + +echo "Starting Squash Display setup container..." + +# Build the docker run command - needs privileged access to configure host +DOCKER_RUN_CMD="docker run -d \ + --restart no \ + --name ${CONTAINER_NAME} \ + --privileged \ + --pid=host \ + --network=host \ + -v /:/host \ + -v ${SERVICE_PATH}/scripts:/scripts:ro \ + -e KIOSK_URL=\"${KIOSK_URL}\" \ + -e KIOSK_USER=\"${KIOSK_USER}\" \ + -e DISPLAY_WIDTH=\"${DISPLAY_WIDTH}\" \ + -e DISPLAY_HEIGHT=\"${DISPLAY_HEIGHT}\" \ + -e DISPLAY_REFRESH=\"${DISPLAY_REFRESH}\" \ + -e GPU_MEM=\"${GPU_MEM}\" \ + -e ENABLE_WATCHDOG=\"${ENABLE_WATCHDOG}\" \ + -e ENABLE_AUTO_LOGIN=\"${ENABLE_AUTO_LOGIN}\" \ + -e ENABLE_HDMI_KEEP_ALIVE=\"${ENABLE_HDMI_KEEP_ALIVE}\" \ + ${IMAGE_REGISTRY}/${IMAGE_REPO}:${IMAGE_TAG} \ + sh /scripts/setup-host.sh" + +# Create and start the container +if ! _create_and_start_container "$DOCKER_RUN_CMD" "$CONTAINER_NAME"; then + _die "Failed to start Squash Display setup container" +fi + +# Wait for setup to complete +echo "Running kiosk setup..." +echo "This may take a few minutes as packages are installed..." + +# Follow the container logs until it exits +docker logs -f ${CONTAINER_NAME} 2>&1 + +# Check if setup completed successfully +EXIT_CODE=$(docker inspect ${CONTAINER_NAME} --format='{{.State.ExitCode}}') +if [ "$EXIT_CODE" != "0" ]; then + echo "Setup failed with exit code: $EXIT_CODE" + echo "Check logs for details: docker logs ${CONTAINER_NAME}" + exit 1 +fi + +echo "" +echo "Squash Display setup completed successfully!" +echo "Container: ${CONTAINER_NAME}" \ No newline at end of file diff --git a/squashdisplay/status.sh b/squashdisplay/status.sh new file mode 100755 index 0000000..2423522 --- /dev/null +++ b/squashdisplay/status.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# shellcheck disable=SC1091 +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" "KIOSK_USER" + +# Squash Display Status Script + +echo "Squash Display Kiosk Status" +echo "============================" + +# Check setup container status +echo "" +echo "Setup Container Status:" +echo "-----------------------" +if ! _is_container_exists "$CONTAINER_NAME"; then + echo "Status: Not Found" + echo "The setup container does not exist." + echo "Run installation to configure the kiosk: ./install.sh" +else + if _is_container_running "$CONTAINER_NAME"; then + echo "Status: Running (Setup in progress)" + else + EXIT_CODE=$(docker inspect ${CONTAINER_NAME} --format='{{.State.ExitCode}}' 2>/dev/null) + if [ "$EXIT_CODE" = "0" ]; then + echo "Status: Completed Successfully" + else + echo "Status: Failed (Exit code: $EXIT_CODE)" + echo "Check logs: docker logs ${CONTAINER_NAME}" + fi + fi +fi + +# Check host kiosk configuration +echo "" +echo "Host Kiosk Configuration:" +echo "-------------------------" + +# Check if kiosk user exists +if id -u ${KIOSK_USER} >/dev/null 2>&1; then + echo "✓ Kiosk user exists: ${KIOSK_USER}" +else + echo "✗ Kiosk user not found: ${KIOSK_USER}" +fi + +# Check if kiosk script exists +if [ -f "/home/${KIOSK_USER}/kiosk.sh" ]; then + echo "✓ Kiosk script installed" +else + echo "✗ Kiosk script not found" +fi + +# Check if auto-login is configured +if [ -f "/etc/systemd/system/getty@tty1.service.d/autologin.conf" ]; then + echo "✓ Auto-login configured" +else + echo "✗ Auto-login not configured" +fi + +# Check if Chromium is installed +if command -v chromium-browser >/dev/null 2>&1 || command -v chromium >/dev/null 2>&1; then + echo "✓ Chromium browser installed" +else + echo "✗ Chromium browser not installed" +fi + +# Check if X server is installed +if command -v xinit >/dev/null 2>&1; then + echo "✓ X server installed" +else + echo "✗ X server not installed" +fi + +# Check for running Chromium process +echo "" +echo "Kiosk Process Status:" +echo "--------------------" +if pgrep -f "chromium.*--kiosk" >/dev/null 2>&1; then + echo "✓ Chromium kiosk is running" + CHROMIUM_PID=$(pgrep -f "chromium.*--kiosk" | head -1) + echo " PID: ${CHROMIUM_PID}" + + # Try to get the URL being displayed + if [ -n "$CHROMIUM_PID" ]; then + CMDLINE=$(ps -p ${CHROMIUM_PID} -o args= 2>/dev/null | grep -oE 'https?://[^ ]+' | head -1) + [ -n "$CMDLINE" ] && echo " URL: ${CMDLINE}" + fi +else + echo "✗ Chromium kiosk is not running" + echo " This is normal if the system hasn't been rebooted after installation" +fi + +# Check X server +if pgrep -x "Xorg" >/dev/null 2>&1 || pgrep -x "X" >/dev/null 2>&1; then + echo "✓ X server is running" +else + echo "✗ X server is not running" +fi + +# Display current configuration +echo "" +echo "Current Configuration:" +echo "---------------------" +echo "Kiosk URL: ${KIOSK_URL}" +echo "Kiosk User: ${KIOSK_USER}" +echo "Display: ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}@${DISPLAY_REFRESH}Hz" +echo "Watchdog Enabled: ${ENABLE_WATCHDOG}" +echo "Auto-login Enabled: ${ENABLE_AUTO_LOGIN}" +echo "HDMI Keep-Alive: ${ENABLE_HDMI_KEEP_ALIVE}" + +echo "" +echo "Tips:" +echo "-----" +echo "- If kiosk is not running, reboot the system: sudo reboot" +echo "- To test manually: sudo -u ${KIOSK_USER} startx /home/${KIOSK_USER}/kiosk.sh" +echo "- View logs: journalctl -u getty@tty1 -f" +echo "- Reconfigure: ./configure.sh" + +exit 0 \ No newline at end of file diff --git a/squashdisplay/stop.sh b/squashdisplay/stop.sh new file mode 100755 index 0000000..8869e21 --- /dev/null +++ b/squashdisplay/stop.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# shellcheck disable=SC1091 +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" + +echo "Stopping Squash Display container..." + +if _is_container_running "$CONTAINER_NAME"; then + if _stop_container "$CONTAINER_NAME"; then + echo "Squash Display container stopped successfully." + else + _die "Failed to stop Squash Display container" + fi +else + echo "Squash Display container is not running." +fi + +# Note: This only stops the Docker container used for setup. +# The kiosk itself runs directly on the host and is not affected. \ No newline at end of file diff --git a/squashdisplay/uninstall.sh b/squashdisplay/uninstall.sh new file mode 100755 index 0000000..c21d857 --- /dev/null +++ b/squashdisplay/uninstall.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# shellcheck disable=SC1091 +source "${AGENT_PATH}/common.sh" +_check_required_env_vars "CONTAINER_NAME" + +# Squash Display Uninstallation Script + +echo "Uninstalling Squash Display service..." +echo "" +echo "WARNING: This will remove the Docker container but will NOT undo" +echo "the system-level changes made during installation, including:" +echo " - Installed packages (Chromium, X server, etc.)" +echo " - Auto-login configuration" +echo " - Kiosk scripts in /home/${KIOSK_USER}/" +echo " - System service configurations" +echo "" +echo "To fully remove the kiosk setup, you would need to manually:" +echo " 1. Remove auto-login: sudo rm /etc/systemd/system/getty@tty1.service.d/autologin.conf" +echo " 2. Remove kiosk scripts: rm /home/${KIOSK_USER}/kiosk.sh /home/${KIOSK_USER}/watchdog.sh" +echo " 3. Re-enable updates: sudo systemctl enable apt-daily.service apt-daily.timer" +echo " 4. Remove HDMI service: sudo systemctl disable hdmi-keep-alive.service" +echo "" + +# Stop the container if it's running +if _is_container_running "$CONTAINER_NAME"; then + echo "Stopping Squash Display container..." + _stop_container "$CONTAINER_NAME" +fi + +# Remove the container +if _is_container_exists "$CONTAINER_NAME"; then + echo "Removing Squash Display container..." + _remove_container "$CONTAINER_NAME" +fi + +echo "Squash Display container has been uninstalled." +echo "Note: System configurations remain in place. See above for manual removal steps." \ No newline at end of file diff --git a/versions.json b/versions.json index 9cc4abe..370eba0 100644 --- a/versions.json +++ b/versions.json @@ -3,6 +3,7 @@ "cloudflare-tunnel": "1.0.0", "gitea-runner-docker": "1.0.0", "simple-object-server": "1.0.0", + "squashdisplay": "1.0.0", "static-website": "1.0.0", "tailscale": "1.0.0", "watchtower": "1.0.0"