#!/bin/sh # Exit immediately if a command exits with a non-zero status. # We disable this ('+e') temporarily during the nomodeset check. set -u # --- Configuration --- # Set the URL you want the signage to display KIOSK_URL="https://example.com" # Set the user account to run the signage under SIGNAGE_USER="signage" # --- End Configuration --- echo "Starting Alpine Linux Signage Setup (Using greetd)..." echo "Target URL: $KIOSK_URL" echo "Signage User: $SIGNAGE_USER" echo "-------------------------------------" # 1. Check if running as root if [ "$(id -u)" -ne 0 ]; then echo "ERROR: This script must be run as root" 1>&2 exit 1 fi # 2. Update repositories echo "[Step 3/11] Updating package repositories..." apk update echo "-------------------------------------" # 3. Setup base Wayland environment (includes enabling community repo) echo "[Step 4/11] Setting up base Wayland environment (elogind, eudev)..." apk add --no-cache alpine-conf setup-wayland-base echo "-------------------------------------" # 4. Install necessary packages (Add greetd) echo "[Step 5/11] Installing Weston, Chromium, Mesa, D-Bus, Fonts, Firmware, Greetd..." apk add \ weston \ weston-backend-drm \ weston-shell-desktop \ chromium \ mesa-dri-gallium \ mesa-va-gallium \ dbus \ font-dejavu \ ttf-freefont \ util-linux \ linux-firmware \ greetd \ greetd-agreety # Console greeter echo "-------------------------------------" # 5. Enable & Start D-Bus service (elogind/polkit handled by setup-wayland-base) echo "[Step 6/11] Enabling and starting D-Bus service..." if ! rc-service dbus status > /dev/null 2>&1; then rc-update add dbus default rc-service dbus start else echo "D-Bus service already running or enabled." fi echo "-------------------------------------" # 6. Create the signage user echo "[Step 7/11] Creating signage user '$SIGNAGE_USER'..." if ! id -u "$SIGNAGE_USER" >/dev/null 2>&1; then echo "Creating group '$SIGNAGE_USER'..." addgroup "$SIGNAGE_USER" echo "Creating user '$SIGNAGE_USER' with shell /bin/sh..." # Use /bin/sh shell for better compatibility with login/profile execution adduser -D -G "$SIGNAGE_USER" -s /bin/sh -h "/home/$SIGNAGE_USER" "$SIGNAGE_USER" echo "User '$SIGNAGE_USER' created." else echo "User '$SIGNAGE_USER' already exists. Ensuring shell is /bin/sh..." usermod -s /bin/sh "$SIGNAGE_USER" if ! getent group "$SIGNAGE_USER" >/dev/null 2>&1; then echo "Group '$SIGNAGE_USER' not found, creating it." addgroup "$SIGNAGE_USER" adduser "$SIGNAGE_USER" "$SIGNAGE_USER" # Ensure user is in their group fi fi SIGNAGE_HOME="/home/$SIGNAGE_USER" if [ ! -d "$SIGNAGE_HOME" ]; then echo "Creating home directory '$SIGNAGE_HOME'..." mkdir -p "$SIGNAGE_HOME" fi chown "$SIGNAGE_USER:$SIGNAGE_USER" "$SIGNAGE_HOME" chmod 750 "$SIGNAGE_HOME" # Slightly more secure default echo "-------------------------------------" # 7. Configure Weston echo "[Step 8/11] Configuring Weston..." SIGNAGE_CONFIG_DIR="$SIGNAGE_HOME/.config" SIGNAGE_WESTON_CONFIG="$SIGNAGE_CONFIG_DIR/weston.ini" WESTON_LOG_DIR="$SIGNAGE_HOME/.local/share/weston" echo "Creating configuration directories..." mkdir -p "$SIGNAGE_CONFIG_DIR" mkdir -p "$WESTON_LOG_DIR" # Attempt chown, ignore errors if run multiple times chown -R "$SIGNAGE_USER:$SIGNAGE_USER" "$SIGNAGE_HOME/.config" || true chown -R "$SIGNAGE_USER:$SIGNAGE_USER" "$SIGNAGE_HOME/.local" || true echo "Creating $SIGNAGE_WESTON_CONFIG..." cat > "$SIGNAGE_WESTON_CONFIG" << EOF [core] # Use drm backend explicitly if needed, usually auto-detected. # Default backend is drm-backend.so when run outside another compositor # backend=drm-backend.so # idle-time=0 prevents screen blanking/DPMS idle-time=0 [shell] # locking=false disables the screen lock/shield locking=false # Set the background to black (optional) # background-color=0xff000000 # Start Chromium in kiosk mode as the main client # Use --no-sandbox as it's often needed in minimal/containerized envs # Explicitly tell Chromium to use Wayland backend client=/usr/bin/chromium --enable-features=UseOzonePlatform --ozone-platform=wayland --kiosk --no-first-run --disable-infobars --disable-session-crashed-bubble --disable-component-update --disable-pinch --app=$KIOSK_URL --no-sandbox # --- Optional Output Configuration --- # Find your output name (e.g., HDMI-A-1, DP-1) via weston log or 'weston --scan-outputs' # Then uncomment and configure the [output] section if needed. #[output] #name=HDMI-A-1 #mode=1920x1080@60 #transform=rotate-90 # Options: normal, 90, 180, 270, flipped, flipped-90, etc. EOF chown "$SIGNAGE_USER:$SIGNAGE_USER" "$SIGNAGE_WESTON_CONFIG" chmod 600 "$SIGNAGE_WESTON_CONFIG" echo "-------------------------------------" # 8. Configure greetd for Autologin and Weston Session echo "[Step 9/11] Configuring greetd..." GREETD_CONFIG_DIR="/etc/greetd" GREETD_CONFIG_FILE="$GREETD_CONFIG_DIR/config.toml" mkdir -p "$GREETD_CONFIG_DIR" # Create greetd config for autologin with agreety launching weston cat > "$GREETD_CONFIG_FILE" << EOF # Greetd configuration for signage kiosk [terminal] # Use agreety on the specified TTY. Switch VT if desired. vt = 1 # command line REMOVED from here - specified in default_session [default_session] # Automatically log in the specified user. user = "$SIGNAGE_USER" # The command to run for the default session user. # Launch weston directly. elogind grants permissions via PAM integration with greetd. command = "/usr/bin/weston --log=/home/$SIGNAGE_USER/.local/share/weston/weston.log" EOF chmod 644 "$GREETD_CONFIG_FILE" echo "greetd config written to $GREETD_CONFIG_FILE" echo "-------------------------------------" # 9. Configure inittab to start greetd echo "[Step 10/11] Configuring autologin via greetd in /etc/inittab..." if [ -f "/etc/inittab" ]; then # Backup original inittab first only if it exists cp /etc/inittab /etc/inittab.bak.$(date +%s) # Disable getty on other TTYs (optional, saves resources) echo "Commenting out ttys 2-6 in /etc/inittab..." sed -i -e '/^tty[2-6]:/s/^/#/' /etc/inittab # Configure tty1 to start greetd echo "Modifying tty1 entry in /etc/inittab to start greetd..." GREETD_INITTAB_LINE="tty1::respawn:/usr/sbin/greetd" # Check if the line already exists to prevent duplicates if ! grep -Fxq "$GREETD_INITTAB_LINE" /etc/inittab; then # Replace the default getty/agetty/login line with the greetd line sed -i "s|^tty1::respawn:.*|$GREETD_INITTAB_LINE|" /etc/inittab else echo "greetd line already seems to be present in /etc/inittab." fi else echo "Warning: /etc/inittab not found. Cannot configure greetd startup." fi echo "-------------------------------------" # 10. Attempt to Enable elogind PAM module for session management echo "[Step 11/11] Attempting to configure PAM for elogind session..." PAM_GREETD_FILE="/etc/pam.d/greetd" PAM_SYSTEM_AUTH="/etc/pam.d/system-auth" PAM_TARGET_FILE="" PAM_MODULE="pam_elogind.so" # Prefer greetd's specific PAM file if it exists if [ -f "$PAM_GREETD_FILE" ]; then PAM_TARGET_FILE="$PAM_GREETD_FILE" echo "Using $PAM_TARGET_FILE for PAM configuration." elif [ -f "$PAM_SYSTEM_AUTH" ]; then PAM_TARGET_FILE="$PAM_SYSTEM_AUTH" echo "Using $PAM_SYSTEM_AUTH for PAM configuration (greetd PAM file not found)." else echo "Warning: Neither $PAM_GREETD_FILE nor $PAM_SYSTEM_AUTH found!" fi if [ -n "$PAM_TARGET_FILE" ]; then # Check if the module is already present if ! grep -q "$PAM_MODULE" "$PAM_TARGET_FILE"; then echo "Adding '$PAM_MODULE' to $PAM_TARGET_FILE..." # Use awk to insert after the first line starting with 'session' # Create backup before modifying cp "$PAM_TARGET_FILE" "$PAM_TARGET_FILE.bak.$(date +%s)" awk '/^session/{if(!p++) print; print "session optional pam_elogind.so"; next} 1' "$PAM_TARGET_FILE" > "$PAM_TARGET_FILE.tmp" && mv "$PAM_TARGET_FILE.tmp" "$PAM_TARGET_FILE" echo "PAM module added." else echo "'$PAM_MODULE' already present in $PAM_TARGET_FILE." fi else echo "Warning: Could not find suitable PAM file to modify." echo " System relies on default PAM includes for elogind session setup." echo " XDG_RUNTIME_DIR creation might fail if not handled by defaults." fi echo "-------------------------------------" # 11. Check for 'nomodeset' kernel parameter # Temporarily disable exit-on-error ('+e') for the check set +e KERNEL_CMDLINE=$(cat /proc/cmdline) echo "[Step 2/11] Checking kernel command line for 'nomodeset'..." echo "Command line: $KERNEL_CMDLINE" if echo "$KERNEL_CMDLINE" | grep -q -w 'nomodeset'; then echo "" echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" echo "!! WARNING: Kernel parameter 'nomodeset' detected in /proc/cmdline!" echo "!! This PREVENTS Weston's DRM backend from working correctly." echo "!! You MUST remove 'nomodeset' from your bootloader configuration" echo "!! (e.g., /etc/default/grub or /boot/extlinux.conf) and update/reboot" echo "!! for the graphical kiosk to function." echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" echo "" # Allow script to continue, but it will fail graphically later else echo "'nomodeset' not found. Proceeding..." fi # Re-enable exit-on-error set -e echo "-------------------------------------" echo "-----------------------------------------------------" echo " Alpine Linux Signage Setup Script Finished!" echo "-----------------------------------------------------" echo " SUMMARY:" echo " * Packages installed (Weston, Chromium, elogind, greetd, etc.)." echo " * User '$SIGNAGE_USER' created/configured with shell /bin/sh." echo " * Weston configured in $SIGNAGE_WESTON_CONFIG." echo " * Autologin configured via greetd ($GREETD_CONFIG_FILE)." echo " * /etc/inittab modified to launch greetd on tty1." echo " * Attempted to configure PAM for elogind." echo "" echo " !!! IMPORTANT !!!" echo " If you saw a WARNING about 'nomodeset' earlier, the graphical kiosk" echo " WILL NOT WORK until you remove 'nomodeset' from your bootloader config" echo " (e.g., /etc/default/grub or /boot/extlinux.conf) and reboot." echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" echo "" echo " Please REBOOT the system for changes to take effect." echo " Command: reboot" echo "" echo " TROUBLESHOOTING AFTER REBOOT (if it doesn't work):" echo " 1. Log in as root on another TTY (Alt+F2) or via SSH." echo " 2. Check greetd status/logs:" echo " * cat /var/log/messages | grep greetd" echo " * Check greetd config: cat $GREETD_CONFIG_FILE" echo " 3. Check the Weston log: cat $WESTON_LOG_DIR/weston.log" echo " 4. Check XDG_RUNTIME_DIR: ls -ld /run/user/\$(id -u $SIGNAGE_USER)" echo " (Should be created by elogind via PAM)." echo " 5. Check service status: rc-service elogind status && rc-service dbus status" echo " 6. Check /etc/inittab for the tty1 line: grep ^tty1 /etc/inittab (should show greetd)" echo " 7. Check system messages for graphics/DRM errors: dmesg | tail -n 50" echo " 8. Verify Chromium Wayland flags in: cat $SIGNAGE_WESTON_CONFIG" echo "-----------------------------------------------------" exit 0