From 90510bd8eaf63b1a2362aac46db8b639927072b0 Mon Sep 17 00:00:00 2001 From: "Josh.5" Date: Wed, 6 Sep 2023 00:06:18 +1200 Subject: [PATCH] Add a WoL Manager service --- Dockerfile.debian | 8 +- overlay/etc/cont-init.d/30-configure_dbus.sh | 44 +++++----- .../cont-init.d/50-configure_pulseaudio.sh | 4 + .../etc/cont-init.d/70-configure_desktop.sh | 12 +++ overlay/etc/cont-init.d/70-configure_xorg.sh | 3 + overlay/etc/cont-init.d/90-configure_steam.sh | 1 + overlay/etc/cont-init.d/90-configure_vnc.sh | 6 +- .../etc/cont-init.d/95-configure_secondary.sh | 34 -------- overlay/etc/cont-init.d/95-setup_wol.sh | 34 ++++++++ .../etc/supervisor.d/wol-power-manager.ini | 15 ++++ .../usr/bin/steam-headless-wol-power-manager | 84 +++++++++++++++++++ 11 files changed, 190 insertions(+), 55 deletions(-) create mode 100644 overlay/etc/cont-init.d/70-configure_desktop.sh delete mode 100644 overlay/etc/cont-init.d/95-configure_secondary.sh create mode 100644 overlay/etc/cont-init.d/95-setup_wol.sh create mode 100644 overlay/etc/supervisor.d/wol-power-manager.ini create mode 100755 overlay/usr/bin/steam-headless-wol-power-manager diff --git a/Dockerfile.debian b/Dockerfile.debian index 7e52123..f697c2c 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -296,6 +296,11 @@ RUN \ && sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/thunar-bulk-rename.desktop \ && sed -i 's/^Categories=.*$/Categories=System;/' /usr/share/applications/org.gnome.gedit.desktop \ && \ + echo "**** Install WoL Manager requirements ****" \ + && apt-get install -y \ + tcpdump \ + xprintidle \ + && \ echo "**** Section cleanup ****" \ && apt-get clean autoclean -y \ && apt-get autoremove -y \ @@ -551,7 +556,8 @@ ENV \ ENABLE_STEAM="true" \ STEAM_ARGS="-silent" \ ENABLE_SUNSHINE="true" \ - ENABLE_EVDEV_INPUTS="false" + ENABLE_EVDEV_INPUTS="false" \ + ENABLE_WOL_POWER_MANAGER="false" # Configure required ports ENV \ diff --git a/overlay/etc/cont-init.d/30-configure_dbus.sh b/overlay/etc/cont-init.d/30-configure_dbus.sh index ac41bdd..9a2a7c2 100644 --- a/overlay/etc/cont-init.d/30-configure_dbus.sh +++ b/overlay/etc/cont-init.d/30-configure_dbus.sh @@ -1,26 +1,32 @@ # Configure dbus echo "**** Configure container dbus ****"; -if [[ "${HOST_DBUS}" == "true" ]]; then - echo "Container configured to use the host dbus"; - # Disable supervisord script - sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini + +if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then + if [[ "${HOST_DBUS}" == "true" ]]; then + echo "Container configured to use the host dbus"; + # Disable supervisord script + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini + else + echo "Container configured to run its own dbus"; + # Enable supervisord script + sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/dbus.ini + # Configure dbus to run as USER + sed -i "/ /c\ ${USER}" /usr/share/dbus-1/system.conf + # Remove old dbus session + rm -rf ${USER_HOME}/.dbus/session-bus/* 2> /dev/null + # Remove old dbus pids + mkdir -p /var/run/dbus + chown -R ${PUID}:${PGID} /var/run/dbus/ + chmod -R 770 /var/run/dbus/ + # Generate a dbus machine ID + dbus-uuidgen > /var/lib/dbus/machine-id + # Remove old lockfiles + find /var/run/dbus -name "pid" -exec rm -f {} \; + fi else - echo "Container configured to run its own dbus"; - # Enable supervisord script - sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/dbus.ini - # Configure dbus to run as USER - sed -i "/ /c\ ${USER}" /usr/share/dbus-1/system.conf - # Remove old dbus session - rm -rf ${USER_HOME}/.dbus/session-bus/* 2> /dev/null - # Remove old dbus pids - mkdir -p /var/run/dbus - chown -R ${PUID}:${PGID} /var/run/dbus/ - chmod -R 770 /var/run/dbus/ - # Generate a dbus machine ID - dbus-uuidgen > /var/lib/dbus/machine-id - # Remove old lockfiles - find /var/run/dbus -name "pid" -exec rm -f {} \; + echo "Dbus service not available when container is run in 'secondary' mode." + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini fi echo "DONE" diff --git a/overlay/etc/cont-init.d/50-configure_pulseaudio.sh b/overlay/etc/cont-init.d/50-configure_pulseaudio.sh index 3cdb5ae..ab9dd06 100644 --- a/overlay/etc/cont-init.d/50-configure_pulseaudio.sh +++ b/overlay/etc/cont-init.d/50-configure_pulseaudio.sh @@ -1,6 +1,10 @@ echo "**** Configure pulseaudio ****" +# Always enable the pulseaudio service +echo "Enable pulseaudio service." +sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/pulseaudio.ini + if [ "${MODE}" == "s" ] | [ "${MODE}" == "secondary" ]; then echo "Configure pulseaudio as simple dummy audio" sed -i 's|^; autospawn.*$|autospawn = no|' /etc/pulse/client.conf diff --git a/overlay/etc/cont-init.d/70-configure_desktop.sh b/overlay/etc/cont-init.d/70-configure_desktop.sh new file mode 100644 index 0000000..56b3c7d --- /dev/null +++ b/overlay/etc/cont-init.d/70-configure_desktop.sh @@ -0,0 +1,12 @@ + +echo "**** Configure Desktop ****" + +if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then + echo "Enable Desktop service." + sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/desktop.ini +else + echo "Desktop service not available when container is run in 'secondary' mode." + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/desktop.ini +fi + +echo "DONE" diff --git a/overlay/etc/cont-init.d/70-configure_xorg.sh b/overlay/etc/cont-init.d/70-configure_xorg.sh index 7adc0f8..e75cb8c 100644 --- a/overlay/etc/cont-init.d/70-configure_xorg.sh +++ b/overlay/etc/cont-init.d/70-configure_xorg.sh @@ -94,6 +94,9 @@ function configure_x_server { sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini # Enable xvfb supervisord script sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/xvfb.ini + else + echo "Configure container with no X server" + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini fi # Enable KB/Mouse input capture with Xorg if configured diff --git a/overlay/etc/cont-init.d/90-configure_steam.sh b/overlay/etc/cont-init.d/90-configure_steam.sh index 3f0202a..8f332be 100644 --- a/overlay/etc/cont-init.d/90-configure_steam.sh +++ b/overlay/etc/cont-init.d/90-configure_steam.sh @@ -25,6 +25,7 @@ if [ "${ENABLE_STEAM:-}" = "true" ]; then echo "Enable Steam auto-start script" mkdir -p "${USER_HOME:?}/.config/autostart" echo "${steam_autostart_desktop:?}" > "${USER_HOME:?}/.config/autostart/Steam.desktop" + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/steam.ini fi else echo "Disable Steam service" diff --git a/overlay/etc/cont-init.d/90-configure_vnc.sh b/overlay/etc/cont-init.d/90-configure_vnc.sh index e6c1ccd..060c375 100644 --- a/overlay/etc/cont-init.d/90-configure_vnc.sh +++ b/overlay/etc/cont-init.d/90-configure_vnc.sh @@ -29,7 +29,7 @@ echo "Configure pulseaudio encoded stream port '${PORT_AUDIO_STREAM}'" if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then - if [ ${WEB_UI_MODE} = "vnc" ]; then + if [ "${WEB_UI_MODE:-}" = "vnc" ]; then echo "Enable VNC server" sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/vnc.ini @@ -72,9 +72,13 @@ if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then fi else echo "Disable VNC server" + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc.ini + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini fi else echo "VNC server not available when container is run in 'secondary' mode" + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc.ini + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini fi echo "DONE" diff --git a/overlay/etc/cont-init.d/95-configure_secondary.sh b/overlay/etc/cont-init.d/95-configure_secondary.sh deleted file mode 100644 index d4cd334..0000000 --- a/overlay/etc/cont-init.d/95-configure_secondary.sh +++ /dev/null @@ -1,34 +0,0 @@ -if [ "${MODE}" == "s" ] | [ "${MODE}" == "secondary" ]; then - echo "Configure container as secondary" - # Disable dbus - echo " - Disable dbus" - sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/dbus.ini - # Disable desktop - echo " - Disable desktop" - sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/desktop.ini - # Disable vnc - echo " - Disable vnc" - sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc.ini - # Disable vnc - echo " - Disable vnc" - sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc.ini - # Disable vnc-audio - echo " - Disable vnc audio stream" - echo " - Disable vnc audio websock" - sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/vnc-audio.ini - # Disable xorg - echo " - Disable xorg" - sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/xorg.ini - - # Enable pulseaudio - echo " - Enable pulseaudio" - sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/pulseaudio.ini - # Enable steam - echo " - Enable steam" - sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/steam.ini - # Enable udev - echo " - Enable udev" - sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/udev.ini -fi - -echo "DONE" diff --git a/overlay/etc/cont-init.d/95-setup_wol.sh b/overlay/etc/cont-init.d/95-setup_wol.sh new file mode 100644 index 0000000..7b8a485 --- /dev/null +++ b/overlay/etc/cont-init.d/95-setup_wol.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +### +# File: 10-setup_user.sh +# Project: cont-init.d +# File Created: Tuesday, 5th September 2023 6:15:12 pm +# Author: Josh.5 (jsunnex@gmail.com) +# ----- +# Last Modified: Tuesday, 5th September 2023 6:39:32 pm +# Modified By: Josh.5 (jsunnex@gmail.com) +### + +echo "**** Configure WoL Manager ****" + +if ([ "${MODE}" != "s" ] && [ "${MODE}" != "secondary" ]); then + if [ "${ENABLE_WOL_POWER_MANAGER:-}" = "true" ]; then + if [ -f "/tmp/.wol-monitor" ]; then + echo "Container started in WoL Manager mode. Disabling all other services." + for init_config in /etc/supervisor.d/*.ini ; do + init_config_basename=$(basename "${init_config:?}") + init_name="${init_config_basename%.*}" + [ "${init_name:?}" = "wol-power-manager" ] && continue + echo " - Disable ${init_name:?}" + sed -i 's|^autostart.*=.*$|autostart=false|' "${init_config:?}" + done + fi + echo "Enable WoL Manager service." + sed -i 's|^autostart.*=.*$|autostart=true|' /etc/supervisor.d/wol-power-manager.ini + else + echo "Disable WoL Manager service." + sed -i 's|^autostart.*=.*$|autostart=false|' /etc/supervisor.d/wol-power-manager.ini + fi +else + echo "WoL Manager service not available when container is run in 'secondary' mode." +fi diff --git a/overlay/etc/supervisor.d/wol-power-manager.ini b/overlay/etc/supervisor.d/wol-power-manager.ini new file mode 100644 index 0000000..a1eff7d --- /dev/null +++ b/overlay/etc/supervisor.d/wol-power-manager.ini @@ -0,0 +1,15 @@ + +[program:wol-power-manager] +priority=60 +autostart=false +autorestart=true +user=root +command=/usr/bin/steam-headless-wol-power-manager +environment=HOME="/home/%(ENV_USER)s",USER="%(ENV_USER)s" +stopsignal=INT +stdout_logfile=/home/%(ENV_USER)s/.cache/log/wol-power-manager.log +stdout_logfile_maxbytes=10MB +stdout_logfile_backups=7 +stderr_logfile=/home/%(ENV_USER)s/.cache/log/wol-power-manager.err.log +stderr_logfile_maxbytes=10MB +stderr_logfile_backups=7 diff --git a/overlay/usr/bin/steam-headless-wol-power-manager b/overlay/usr/bin/steam-headless-wol-power-manager new file mode 100755 index 0000000..9e35db7 --- /dev/null +++ b/overlay/usr/bin/steam-headless-wol-power-manager @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +### +# File: steam-headless-wol-power-manager +# Project: bin +# File Created: Tuesday, 5th September 2023 5:35:38 pm +# Author: Josh.5 (jsunnex@gmail.com) +# ----- +# Last Modified: Tuesday, 5th September 2023 5:35:38 pm +# Modified By: Josh.5 (jsunnex@gmail.com) +### +set -e + +# Function to execute restart to WoL monitor +restart_to_wol_monitor() { + # Create WoL monitor lock file. This will be read during the next restart and will trigger a singluar WoL monitor service. + touch /tmp/.wol-monitor + + # Stop all processes inside the container by sending a SIGINT to the main supervisord process (PID 1) + kill -2 1 + + # Exit script + exit 0 +} + +# Function to execute restart to Desktop +restart_to_desktop_mode() { + # Remove WoL monitor lock file. + rm -f /tmp/.wol-monitor + + # Stop all processes inside the container by sending a SIGINT to the main supervisord process (PID 1) + kill -2 1 + + # Exit script + exit 0 +} + +# Function to monitor for no user input +start_idle_monitor() { + # Set the idle timeout in milliseconds (60 minutes = 3600000 milliseconds) + local idle_timeout=3600000 + + # Monitor input. After an hour of no input + echo "Starting idle inputs monitor service..." + while true; do + # Sleep for a short interval (e.g., 1 minute) before checking + sleep 60 + + # Get the current idle time in milliseconds using xprintidle + idle_time=$(xprintidle) + + # Check if the idle time exceeds the specified timeout + if [ "${idle_time:?}" -ge "${idle_timeout:?}" ]; then + # TODO: Check if any sessions exist in sunshine + + # Execute restart to WoL monitor function + echo "No user activity for over 60 minutes. Entering WoL Monitor Mode." + restart_to_wol_monitor + fi + done +} + +# Function to monitor for WoL events +start_wol_monitor() { + # Specify port to listen to (9 is the default WoL port). + listen_port=9 + + # Start the WoL monitor service + echo "Starting WoL monitor service..." + + while true; do + # Listen for WoL magic packets on the specified port + tcpdump -i any -n -l -c 1 -q "udp port $listen_port and (udp[8:4] = 0xFFFFFFFF)" + + # Execute restart to desktop function + echo "WoL event received. Entering Desktop Mode." + restart_to_desktop_mode + done +} + +if [ -f "/tmp/.wol-monitor" ]; then + start_wol_monitor +else + start_idle_monitor +fi