diff --git a/ansible/roles/sunshine/templates/docker-compose.yml b/ansible/roles/sunshine/templates/docker-compose.yml index ac12c2ed..1bb9c140 100644 --- a/ansible/roles/sunshine/templates/docker-compose.yml +++ b/ansible/roles/sunshine/templates/docker-compose.yml @@ -46,6 +46,7 @@ services: - "47989:47989/tcp" # HTTP - "47990:47990/tcp" # Web - "48010:48010/tcp" # RTSP + - "59999:59999/tcp" # MoonDeckBuddy - "47998:47998/udp" # Video - "47999:47999/udp" # Control diff --git a/containers/sunshine/Dockerfile b/containers/sunshine/Dockerfile index 93ba2791..0547afe7 100644 --- a/containers/sunshine/Dockerfile +++ b/containers/sunshine/Dockerfile @@ -28,7 +28,13 @@ FROM download-base AS download-heroic ARG HEROIC_VERSION="2.18.1" RUN curl -L -o /app/heroic.deb "https://github.com/Heroic-Games-Launcher/HeroicGamesLauncher/releases/download/v${HEROIC_VERSION}/Heroic-${HEROIC_VERSION}-linux-amd64.deb" -# +# MoonDeckBuddy +# https://github.com/FrogTheFrog/moondeck-buddy/releases +FROM download-base AS download-moondeckbuddy +ARG MOONDECKBUDDY_VERSION="1.9.2" +RUN curl -L -o /app/MoonDeckBuddy.AppImage "https://github.com/FrogTheFrog/moondeck-buddy/releases/download/v${MOONDECKBUDDY_VERSION}/MoonDeckBuddy-${MOONDECKBUDDY_VERSION}-x86_64.AppImage" + +# # Sunshine image based on Ubuntu 24.04 # with desktop environment, game launchers and dependencies # @@ -38,9 +44,9 @@ ENV DEBIAN_FRONTEND=noninteractive RUN --mount=type=cache,target=/var/cache --mount=type=tmpfs,target=/var/log <<_MAIN_PACKAGES -set -e +set -e -# Required for some Steam packages +# Required for some Steam packages dpkg --add-architecture i386 apt update @@ -84,6 +90,8 @@ apt install -y \ xz-utils \ zenity \ bubblewrap \ + fuse3 \ + libfuse2t64 \ software-properties-common \ nano \ unzip \ @@ -272,7 +280,21 @@ ENV DBUS_SYSTEM_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/dbus" # TODO use host UID/GID for better portability and usage from host ? RUN useradd -m -d $CLOUDYPAD_USER_HOME -s /bin/bash -u 1001 $CLOUDYPAD_USER -# Copy overlay files: startup scripts, default config, etc. +# Install MoonDeckBuddy AppImage +RUN --mount=type=bind,from=download-moondeckbuddy,source=/app,target=/app <<_MOONDECKBUDDY + +set -e + +MOONDECKBUDDY_APP_DIR="/opt/MoonDeckBuddy" +MOONDECKBUDDY_APPIMAGE_PATH="${MOONDECKBUDDY_APP_DIR}/MoonDeckBuddy.AppImage" + +install -d -o "${CLOUDYPAD_USER}" -g "${CLOUDYPAD_USER}" "${MOONDECKBUDDY_APP_DIR}" +install -m 0755 -o "${CLOUDYPAD_USER}" -g "${CLOUDYPAD_USER}" /app/MoonDeckBuddy.AppImage "${MOONDECKBUDDY_APPIMAGE_PATH}" +ln -sf "${MOONDECKBUDDY_APPIMAGE_PATH}" /usr/local/bin/MoonDeckBuddy + +_MOONDECKBUDDY + +# Copy overlay files: startup scripts, default config, etc. COPY overlay / # Run healthcheck using script diff --git a/containers/sunshine/overlay/cloudy/bin/moondeckstream-start.sh b/containers/sunshine/overlay/cloudy/bin/moondeckstream-start.sh new file mode 100644 index 00000000..804feeab --- /dev/null +++ b/containers/sunshine/overlay/cloudy/bin/moondeckstream-start.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +wait-x-availability.sh + +MOONDECKBUDDY_APPIMAGE_PATH="/opt/MoonDeckBuddy/MoonDeckBuddy.AppImage" + +if [ ! -x "$MOONDECKBUDDY_APPIMAGE_PATH" ]; then + echo "MoonDeckBuddy AppImage not found at $MOONDECKBUDDY_APPIMAGE_PATH" + exit 1 +fi + +cd "$CLOUDYPAD_USER_HOME" + +"$MOONDECKBUDDY_APPIMAGE_PATH" --exec MoonDeckStream & + +MOONDECKSTREAM_PID=$! +echo $MOONDECKSTREAM_PID > /tmp/moondeckstream.pid +echo "MoonDeckStream started with PID: $MOONDECKSTREAM_PID" + +wait $MOONDECKSTREAM_PID diff --git a/containers/sunshine/overlay/cloudy/bin/moondeckstream-stop.sh b/containers/sunshine/overlay/cloudy/bin/moondeckstream-stop.sh new file mode 100644 index 00000000..0f5130e4 --- /dev/null +++ b/containers/sunshine/overlay/cloudy/bin/moondeckstream-stop.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +echo "Stopping MoonDeckStream..." + +if [ ! -f /tmp/moondeckstream.pid ]; then + echo "No MoonDeckStream PID found at /tmp/moondeckstream.pid... Not stopping." + exit 0 +fi + +MOONDECKSTREAM_PID=$(cat /tmp/moondeckstream.pid) + +echo "Killing MoonDeckStream with PID: $MOONDECKSTREAM_PID" + +# Kill MoonDeckStream processes +kill $MOONDECKSTREAM_PID + +echo "MoonDeckStream stopped" diff --git a/containers/sunshine/overlay/cloudy/bin/start-moondeckbuddy.sh b/containers/sunshine/overlay/cloudy/bin/start-moondeckbuddy.sh new file mode 100755 index 00000000..510e2482 --- /dev/null +++ b/containers/sunshine/overlay/cloudy/bin/start-moondeckbuddy.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +wait-x-availability.sh + +MOONDECKBUDDY_APPIMAGE_PATH="/opt/MoonDeckBuddy/MoonDeckBuddy.AppImage" + +if [ ! -x "$MOONDECKBUDDY_APPIMAGE_PATH" ]; then + echo "MoonDeckBuddy AppImage not found at $MOONDECKBUDDY_APPIMAGE_PATH" + exit 1 +fi + +cd "$CLOUDYPAD_USER_HOME" + +exec "$MOONDECKBUDDY_APPIMAGE_PATH" diff --git a/containers/sunshine/overlay/cloudy/conf/sunshine/apps.json b/containers/sunshine/overlay/cloudy/conf/sunshine/apps.json index b9bc2a92..819d60c5 100644 --- a/containers/sunshine/overlay/cloudy/conf/sunshine/apps.json +++ b/containers/sunshine/overlay/cloudy/conf/sunshine/apps.json @@ -142,6 +142,23 @@ "wait-all": "true", "exit-timeout": "5", "cmd": "" + }, + { + "name": "MoonDeckStream", + "prep-cmd": [ + { + "do": "sh -c \"sunshine-app-startup.sh > \/tmp\/sunshine-session-start.log 2>&1\"", + "undo": "sh -c \"moondeckstream-stop.sh > \/tmp\/moondeckstream-stop.log 2>&1\"" + } + ], + "detached": [ + "MOONDECKBUDDY_EXEC_STREAM=1 sh -c \"moondeckstream-start.sh > \/tmp\/moondeckstream-start.log 2>&1\"" + ], + "exclude-global-prep-cmd": "false", + "auto-detach": "true", + "wait-all": "true", + "exit-timeout": "5", + "cmd": "" } ] } \ No newline at end of file diff --git a/containers/sunshine/overlay/cloudy/conf/supervisor/supervisord.conf b/containers/sunshine/overlay/cloudy/conf/supervisor/supervisord.conf index a6b2d38b..c44c095c 100644 --- a/containers/sunshine/overlay/cloudy/conf/supervisor/supervisord.conf +++ b/containers/sunshine/overlay/cloudy/conf/supervisor/supervisord.conf @@ -70,6 +70,21 @@ stopsignal=TERM stdout_logfile=%(ENV_CLOUDYPAD_LOG_DIR)s/sunshine.log stderr_logfile=%(ENV_CLOUDYPAD_LOG_DIR)s/sunshine.err.log +[program:moondeckbuddy] +priority=50 +autostart=true +autorestart=true +user=%(ENV_CLOUDYPAD_USER)s +command=/cloudy/bin/start-moondeckbuddy.sh +environment= + HOME="%(ENV_CLOUDYPAD_USER_HOME)s", + USER="%(ENV_CLOUDYPAD_USER)s", + DISPLAY="%(ENV_DISPLAY)s", + XDG_RUNTIME_DIR="%(ENV_XDG_RUNTIME_DIR)s" +stopsignal=TERM +stdout_logfile=%(ENV_CLOUDYPAD_LOG_DIR)s/moondeckbuddy.log +stderr_logfile=%(ENV_CLOUDYPAD_LOG_DIR)s/moondeckbuddy.err.log + [program:pulseaudio] priority=20 autostart=true diff --git a/containers/sunshine/overlay/cloudy/conf/xfce4-default/xfconf/xfce-perchannel-xml/xfce4-panel.xml b/containers/sunshine/overlay/cloudy/conf/xfce4-default/xfconf/xfce-perchannel-xml/xfce4-panel.xml index 47d64ce2..5e68f480 100644 --- a/containers/sunshine/overlay/cloudy/conf/xfce4-default/xfconf/xfce-perchannel-xml/xfce4-panel.xml +++ b/containers/sunshine/overlay/cloudy/conf/xfce4-default/xfconf/xfce-perchannel-xml/xfce4-panel.xml @@ -17,6 +17,7 @@ + @@ -76,6 +77,8 @@ + + diff --git a/src/core/const.ts b/src/core/const.ts index 599daf0d..220ff8f2 100644 --- a/src/core/const.ts +++ b/src/core/const.ts @@ -116,6 +116,7 @@ export const CLOUDYPAD_SUNSHINE_PORTS: SimplePortDefinition[] = [ { port: 47989, protocol: 'tcp' }, // HTTP { port: 47990, protocol: 'tcp' }, // Web { port: 48010, protocol: 'tcp' }, // RTSP + { port: 59999, protocol: "tcp" }, // MoonDeckBuddy { port: 47998, protocol: 'udp' }, // Video { port: 47999, protocol: 'udp' }, // Control