From 77fd5be9dc1a35a7a35b3dbfe088619106c3f7f1 Mon Sep 17 00:00:00 2001 From: thelamer Date: Thu, 9 Apr 2026 12:58:21 -0400 Subject: [PATCH] update ingestion to use github --- .github/workflows/external_trigger.yml | 6 +- Dockerfile | 6 +- Jenkinsfile | 205 +++++++++-------- README.md | 302 ++++++++++++++----------- jenkins-vars.yml | 7 +- 5 files changed, 291 insertions(+), 235 deletions(-) diff --git a/.github/workflows/external_trigger.yml b/.github/workflows/external_trigger.yml index a1b89c6..8fe08b1 100644 --- a/.github/workflows/external_trigger.yml +++ b/.github/workflows/external_trigger.yml @@ -29,8 +29,8 @@ jobs: echo "> [!NOTE]" >> $GITHUB_STEP_SUMMARY echo "> External trigger running off of master branch. To disable this trigger, add \`scummvm_master\` into the Github organizational variable \`SKIP_EXTERNAL_TRIGGER\`." >> $GITHUB_STEP_SUMMARY printf "\n## Retrieving external version\n\n" >> $GITHUB_STEP_SUMMARY - EXT_RELEASE=$(curl -s https://downloads.scummvm.org/frs/scummvm/ | awk -F'()' '{print $2}'| grep -B 1 'daily' |head -n1) - echo "Type is \`custom_version_command\`" >> $GITHUB_STEP_SUMMARY + EXT_RELEASE=$(curl -u "${{ secrets.CR_USER }}:${{ secrets.CR_PAT }}" -sX GET "https://api.github.com/repos/scummvm/scummvm/releases/latest" | jq -r '. | .tag_name') + echo "Type is \`github_stable\`" >> $GITHUB_STEP_SUMMARY if grep -q "^scummvm_master_${EXT_RELEASE}" <<< "${SKIP_EXTERNAL_TRIGGER}"; then echo "> [!WARNING]" >> $GITHUB_STEP_SUMMARY echo "> Github organizational variable \`SKIP_EXTERNAL_TRIGGER\` matches current external release; skipping trigger." >> $GITHUB_STEP_SUMMARY @@ -110,7 +110,7 @@ jobs: echo "New version \`${EXT_RELEASE}\` found; but there already seems to be an active build on Jenkins; exiting" >> $GITHUB_STEP_SUMMARY exit 0 else - if curl -IfSsL "https://downloads.scummvm.org/frs/scummvm/${EXT_RELEASE}/scummvm_${EXT_RELEASE}-1_ubuntu24_04_amd64.deb" > /dev/null 2>&1; then + if curl -IfSsL "https://downloads.scummvm.org/frs/scummvm/$(echo ${EXT_RELEASE}| sed 's/^v//g')/scummvm_$(echo ${EXT_RELEASE}| sed 's/^v//g')-1_ubuntu24_04_amd64.deb" > /dev/null 2>&1; then artifacts_found="true" else artifacts_found="false" diff --git a/Dockerfile b/Dockerfile index e7fbef9..1d1bbac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,12 +18,12 @@ RUN \ https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/scummvm-logo.png && \ echo "**** install packages ****" && \ if [ -z "${SCUMMVM_VERSION+x}" ]; then \ - SCUMMVM_VERSION=$(curl -s https://downloads.scummvm.org/frs/scummvm/ \ - | awk -F'()' '{print $2}'| grep -B 1 'daily' |head -n1); \ + SCUMMVM_VERSION=$(curl -sX GET "https://api.github.com/repos/scummvm/scummvm/releases/latest" \ + | awk '/tag_name/{print $4;exit}' FS='[""]'); \ fi && \ curl -o \ /tmp/scummvm.deb -L \ - "https://downloads.scummvm.org/frs/scummvm/${SCUMMVM_VERSION}/scummvm_${SCUMMVM_VERSION}-1_ubuntu24_04_amd64.deb" && \ + "https://downloads.scummvm.org/frs/scummvm/$(echo ${SCUMMVM_VERSION} | sed 's/^v//g')/scummvm_$(echo ${SCUMMVM_VERSION} | sed 's/^v//g')-1_ubuntu24_04_amd64.deb" && \ apt-get update && \ apt-get install -y \ /tmp/scummvm.deb && \ diff --git a/Jenkinsfile b/Jenkinsfile index c9701b1..38ac751 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -19,6 +19,8 @@ pipeline { DOCKERHUB_TOKEN=credentials('docker-hub-ci-pat') QUAYIO_API_TOKEN=credentials('quayio-repo-api-token') GIT_SIGNING_KEY=credentials('484fbca6-9a4f-455e-b9e3-97ac98785f5f') + EXT_USER = 'scummvm' + EXT_REPO = 'scummvm' BUILD_VERSION_ARG = 'SCUMMVM_VERSION' LS_USER = 'linuxserver' LS_REPO = 'docker-scummvm' @@ -75,6 +77,7 @@ pipeline { ''' script{ env.EXIT_STATUS = '' + env.CI_TEST_ATTEMPTED = '' env.LS_RELEASE = sh( script: '''docker run --rm quay.io/skopeo/stable:v1 inspect docker://ghcr.io/${LS_USER}/${CONTAINER_NAME}:latest 2>/dev/null | jq -r '.Labels.build_version' | awk '{print $3}' | grep '\\-ls' || : ''', returnStdout: true).trim() @@ -142,16 +145,23 @@ pipeline { /* ######################## External Release Tagging ######################## */ - // If this is a custom command to determine version use that command - stage("Set tag custom bash"){ - steps{ - script{ - env.EXT_RELEASE = sh( - script: ''' curl -s https://downloads.scummvm.org/frs/scummvm/ | awk -F'()' '{print $2}'| grep -B 1 'daily' |head -n1 ''', - returnStdout: true).trim() - env.RELEASE_LINK = 'custom_command' - } - } + // If this is a stable github release use the latest endpoint from github to determine the ext tag + stage("Set ENV github_stable"){ + steps{ + script{ + env.EXT_RELEASE = sh( + script: '''curl -H "Authorization: token ${GITHUB_TOKEN}" -s https://api.github.com/repos/${EXT_USER}/${EXT_REPO}/releases/latest | jq -r '. | .tag_name' ''', + returnStdout: true).trim() + } + } + } + // If this is a stable or devel github release generate the link for the build message + stage("Set ENV github_link"){ + steps{ + script{ + env.RELEASE_LINK = 'https://github.com/' + env.EXT_USER + '/' + env.EXT_REPO + '/releases/tag/' + env.EXT_RELEASE + } + } } // Sanitize the release tag and strip illegal docker or github characters stage("Sanitize tag"){ @@ -283,7 +293,7 @@ pipeline { -v ${WORKSPACE}:/mnt \ -e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \ -e AWS_SECRET_ACCESS_KEY=\"${S3_SECRET}\" \ - ghcr.io/linuxserver/baseimage-alpine:3 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\ + ghcr.io/linuxserver/baseimage-alpine:3.23 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\ apk add --no-cache python3 && \ python3 -m venv /lsiopy && \ pip install --no-cache-dir -U pip && \ @@ -871,6 +881,7 @@ pipeline { script{ env.CI_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/index.html' env.CI_JSON_URL = 'https://ci-tests.linuxserver.io/' + env.IMAGE + '/' + env.META_TAG + '/report.json' + env.CI_TEST_ATTEMPTED = 'true' } sh '''#! /bin/bash set -e @@ -1020,7 +1031,7 @@ pipeline { "type": "commit",\ "tagger": {"name": "LinuxServer-CI","email": "ci@linuxserver.io","date": "'${GITHUB_DATE}'"}}' echo "Pushing New release for Tag" - echo "Updating to ${EXT_RELEASE_CLEAN}" > releasebody.json + curl -H "Authorization: token ${GITHUB_TOKEN}" -s https://api.github.com/repos/${EXT_USER}/${EXT_REPO}/releases/latest | jq -r '. |.body' > releasebody.json jq -n \ --arg tag_name "$META_TAG" \ --arg target_commitish "master" \ @@ -1073,98 +1084,13 @@ EOF ) ''' } } - // If this is a Pull request send the CI link as a comment on it - stage('Pull Request Comment') { - when { - not {environment name: 'CHANGE_ID', value: ''} - environment name: 'EXIT_STATUS', value: '' - } - steps { - sh '''#! /bin/bash - # Function to retrieve JSON data from URL - get_json() { - local url="$1" - local response=$(curl -s "$url") - if [ $? -ne 0 ]; then - echo "Failed to retrieve JSON data from $url" - return 1 - fi - local json=$(echo "$response" | jq .) - if [ $? -ne 0 ]; then - echo "Failed to parse JSON data from $url" - return 1 - fi - echo "$json" - } - - build_table() { - local data="$1" - - # Get the keys in the JSON data - local keys=$(echo "$data" | jq -r 'to_entries | map(.key) | .[]') - - # Check if keys are empty - if [ -z "$keys" ]; then - echo "JSON report data does not contain any keys or the report does not exist." - return 1 - fi - - # Build table header - local header="| Tag | Passed |\\n| --- | --- |\\n" - - # Loop through the JSON data to build the table rows - local rows="" - for build in $keys; do - local status=$(echo "$data" | jq -r ".[\\"$build\\"].test_success") - if [ "$status" = "true" ]; then - status="✅" - else - status="❌" - fi - local row="| "$build" | "$status" |\\n" - rows="${rows}${row}" - done - - local table="${header}${rows}" - local escaped_table=$(echo "$table" | sed 's/\"/\\\\"/g') - echo "$escaped_table" - } - - if [[ "${CI}" = "true" ]]; then - # Retrieve JSON data from URL - data=$(get_json "$CI_JSON_URL") - # Create table from JSON data - table=$(build_table "$data") - echo -e "$table" - - curl -X POST -H "Authorization: token $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \ - -d "{\\"body\\": \\"I am a bot, here are the test results for this PR: \\n${CI_URL}\\n${SHELLCHECK_URL}\\n${table}\\"}" - else - curl -X POST -H "Authorization: token $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \ - -d "{\\"body\\": \\"I am a bot, here is the pushed image/manifest for this PR: \\n\\n\\`${GITHUBIMAGE}:${META_TAG}\\`\\"}" - fi - ''' - - } - } } /* ###################### - Send status to Discord + Comment on PR and Send status to Discord ###################### */ post { always { - sh '''#!/bin/bash - rm -rf /config/.ssh/id_sign - rm -rf /config/.ssh/id_sign.pub - git config --global --unset gpg.format - git config --global --unset user.signingkey - git config --global --unset commit.gpgsign - ''' - script{ + script { env.JOB_DATE = sh( script: '''date '+%Y-%m-%dT%H:%M:%S%:z' ''', returnStdout: true).trim() @@ -1207,6 +1133,87 @@ EOF "username": "Jenkins"}' ${BUILDS_DISCORD} ''' } } + script { + if (env.GITHUBIMAGE =~ /lspipepr/){ + if (env.CI_TEST_ATTEMPTED == "true"){ + sh '''#! /bin/bash + # Function to retrieve JSON data from URL + get_json() { + local url="$1" + local response=$(curl -s "$url") + if [ $? -ne 0 ]; then + echo "Failed to retrieve JSON data from $url" + return 1 + fi + local json=$(echo "$response" | jq .) + if [ $? -ne 0 ]; then + echo "Failed to parse JSON data from $url" + return 1 + fi + echo "$json" + } + + build_table() { + local data="$1" + + # Get the keys in the JSON data + local keys=$(echo "$data" | jq -r 'to_entries | map(.key) | .[]') + + # Check if keys are empty + if [ -z "$keys" ]; then + echo "JSON report data does not contain any keys or the report does not exist." + return 1 + fi + + # Build table header + local header="| Tag | Passed |\\n| --- | --- |\\n" + + # Loop through the JSON data to build the table rows + local rows="" + for build in $keys; do + local status=$(echo "$data" | jq -r ".[\\"$build\\"].test_success") + if [ "$status" = "true" ]; then + status="✅" + else + status="❌" + fi + local row="| "$build" | "$status" |\\n" + rows="${rows}${row}" + done + + local table="${header}${rows}" + local escaped_table=$(echo "$table" | sed 's/\"/\\\\"/g') + echo "$escaped_table" + } + + if [[ "${CI}" = "true" ]]; then + # Retrieve JSON data from URL + data=$(get_json "$CI_JSON_URL") + # Create table from JSON data + table=$(build_table "$data") + echo -e "$table" + + curl -X POST -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \ + -d "{\\"body\\": \\"I am a bot, here are the test results for this PR: \\n${CI_URL}\\n${SHELLCHECK_URL}\\n${table}\\"}" + else + curl -X POST -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$LS_USER/$LS_REPO/issues/$PULL_REQUEST/comments" \ + -d "{\\"body\\": \\"I am a bot, here is the pushed image/manifest for this PR: \\n\\n\\`${GITHUBIMAGE}:${META_TAG}\\`\\"}" + fi + ''' + } + } + } + sh '''#!/bin/bash + rm -rf /config/.ssh/id_sign + rm -rf /config/.ssh/id_sign.pub + git config --global --unset gpg.format + git config --global --unset user.signingkey + git config --global --unset commit.gpgsign + ''' } cleanup { sh '''#! /bin/bash diff --git a/README.md b/README.md index 7465bae..e932f38 100644 --- a/README.md +++ b/README.md @@ -82,21 +82,136 @@ The web interface includes a terminal with passwordless `sudo` access. Any user While not generally recommended, certain legacy environments specifically those with older hardware or outdated Linux distributions may require the deactivation of the standard seccomp profile to get containerized desktop software to run. This can be achieved by utilizing the `--security-opt seccomp=unconfined` parameter. It is critical to use this option only when absolutely necessary as it disables a key security layer of Docker, elevating the potential for container escape vulnerabilities. +### Hardware Acceleration & The Move to Wayland + +We are currently transitioning our desktop containers from X11 to Wayland. While X11 is still the default, we strongly encourage users to test the new Wayland mode. + +**Important:** GPU acceleration support for X11 is being deprecated. Future development for hardware acceleration will focus entirely on the Wayland stack. + +To enable Wayland mode, set the following environment variable: + +* `-e PIXELFLUX_WAYLAND=true` + +**Why use Wayland?** + +* **Zero Copy Encoding:** When configured correctly with a GPU, the frame is rendered and encoded on the video card without ever being copied to the system RAM. This drastically lowers CPU usage and latency. +* **Modern Stack:** Single-application containers utilize **Labwc** (replacing Openbox) and full desktop containers use **KDE Plasma Wayland**, providing a more modern and secure compositing environment while retaining the same user experience. + +#### GPU Configuration + +To use hardware acceleration in Wayland mode, we distinguish between the card used for **Rendering** (3D apps/Desktops) and **Encoding** (Video Stream). + +**Configuration Variables:** + +* `DRINODE`: The path to the GPU used for **Rendering** (EGL). +* `DRI_NODE`: The path to the GPU used for **Encoding** (VAAPI/NVENC). + +If both variables point to the same device, the container will automatically enable **Zero Copy** encoding, significantly reducing CPU usage and latency. If they are set to different devices one will be used for **Rendering** and one for **Encoding** with a cpu readback. + +You can also use the environment variable `AUTO_GPU=true`, with this set the first card detected in the container (IE `/dev/dri/renderD128`) will be used and configured for **Zero Copy**. + +##### Intel & AMD (Open Source Drivers) + +For Intel and AMD GPUs. + +```yaml + devices: + - /dev/dri:/dev/dri + environment: + - PIXELFLUX_WAYLAND=true + # Optional: Specify device if multiple exist (IE: /dev/dri/renderD129) + - DRINODE=/dev/dri/renderD128 + - DRI_NODE=/dev/dri/renderD128 +``` + +##### Nvidia (Proprietary Drivers) + +**Note: Nvidia support is currently considered experimental, driver changes can break it at any time.** + +**Note: Nvidia support is not available for Alpine-based images.** + +**Note: Nvidia frames have issues with hardware decoders in Chromium browsers you need to navigate to `chrome://flags/#disable-accelerated-video-decode` and toggle it to `Disabled` for smooth playback** + +**Prerequisites:** + +1. **Driver:** Proprietary drivers **580 or higher** are required. **Crucially, you should install the driver using the `.run` file downloaded directly from the Nvidia website.** + * **Unraid:** Use the production branch from the Nvidia Driver Plugin. + +2. **Kernel Parameter:** You must set `nvidia-drm.modeset=1 nvidia_drm.fbdev=1` in your host bootloader. + * **Standard Linux (GRUB):** Edit `/etc/default/grub` and add the parameter to your existing `GRUB_CMDLINE_LINUX_DEFAULT` line: + + ```text + GRUB_CMDLINE_LINUX_DEFAULT=" nvidia-drm.modeset=1 nvidia_drm.fbdev=1" + ``` + + Then apply the changes by running: + + ```bash + sudo update-grub + ``` + + * **Unraid (Syslinux):** Edit the file `/boot/syslinux/syslinux.cfg` and add `nvidia-drm.modeset=1 nvidia_drm.fbdev=1` to the end of the `append` line for the Unraid OS boot entry. + +3. **Hardware Initialization:** **On headless systems, the Nvidia video card requires a physical dummy plug inserted into the GPU so that DRM initializes properly.** + +4. **Docker Runtime:** Configure the host docker daemon to use the Nvidia runtime: + + ```bash + sudo nvidia-ctk runtime configure --runtime=docker + sudo systemctl restart docker + ``` + +**Compose Configuration:** + +```yaml +--- +services: + scummvm: + image: lscr.io/linuxserver/scummvm:latest + environment: + - PIXELFLUX_WAYLAND=true + # Ensure these point to the rendered node injected by the runtime (usually renderD128) + - DRINODE=/dev/dri/renderD128 + - DRI_NODE=/dev/dri/renderD128 + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [compute,video,graphics,utility] +``` + +* **Unraid:** Ensure you're properly setting the DRINODE/DRI_NODE and adding `--gpus all --runtime nvidia` to your extra parameters. + +### SealSkin Compatibility + +This container is compatible with [SealSkin](https://sealskin.app). + +SealSkin is a self-hosted, client-server platform that provides secure authentication and collaboration features while using a browser extension to intercept user actions such as clicking a link or downloading a file and redirect them to a secure, isolated application environment running on a remote server. + +* **SealSkin Server:** [Get it Here](https://github.com/linuxserver/docker-sealskin) +* **Browser Extension:** [Chrome](https://chromewebstore.google.com/detail/sealskin-isolation/lclgfmnljgacfdpmmmjmfpdelndbbfhk) and [Firefox](https://addons.mozilla.org/en-US/firefox/addon/sealskin-isolation/). +* **Mobile App:** [iOS](https://apps.apple.com/us/app/sealskin/id6758210210) and [Android](https://play.google.com/store/apps/details?id=io.linuxserver.sealskin) + ### Options in all Selkies-based GUI containers -This container is based on [Docker Baseimage Selkies](https://github.com/linuxserver/docker-baseimage-selkies), which provides the following environment variables and run configurations to customize its functionality. +This container is based on [Docker Baseimage Selkies](https://github.com/linuxserver/docker-baseimage-selkies). -#### Optional Environment Variables +
+Click to expand: Optional Environment Variables | Variable | Description | | :----: | --- | | PIXELFLUX_WAYLAND | **Experimental** If set to true the container will initialize in Wayland mode running [Smithay](https://github.com/Smithay/smithay) and Labwc while enabling zero copy encoding with a GPU | +| SELKIES_DESKTOP | If set to true and in Wayland mode, a simple panel will be initialized with labwc | | CUSTOM_PORT | Internal port the container listens on for http if it needs to be swapped from the default `3000` | | CUSTOM_HTTPS_PORT | Internal port the container listens on for https if it needs to be swapped from the default `3001` | | CUSTOM_WS_PORT | Internal port the container listens on for websockets if it needs to be swapped from the default 8082 | | CUSTOM_USER | HTTP Basic auth username, abc is default. | -| DRI_NODE | Enable VAAPI stream encoding and use the specified device IE `/dev/dri/renderD128` | -| DRINODE | Specify which GPU to use for DRI3 acceleration IE `/dev/dri/renderD129` | +| DRI_NODE | **Encoding GPU**: Enable VAAPI/NVENC stream encoding and use the specified device IE `/dev/dri/renderD128` | +| DRINODE | **Rendering GPU**: Specify which GPU to use for EGL/3D acceleration IE `/dev/dri/renderD129` | +| AUTO_GPU | If set to true and in Wayland mode, we will automatically use the first GPU available for encoding and rendering IE `/dev/dri/renderD128` | | PASSWORD | HTTP Basic auth password, abc is default. If unset there will be no auth | | SUBFOLDER | Subfolder for the application if running a subfolder reverse proxy, need both slashes IE `/subfolder/` | | TITLE | The page title displayed on the web browser, default "Selkies" | @@ -115,112 +230,60 @@ This container is based on [Docker Baseimage Selkies](https://github.com/linuxse | WATERMARK_LOCATION | Where to paint the image over the stream integer options below | **`WATERMARK_LOCATION` Options:** -- **1**: Top Left -- **2**: Top Right -- **3**: Bottom Left -- **4**: Bottom Right -- **5**: Centered -- **6**: Animated -#### Optional Run Configurations +* **1**: Top Left +* **2**: Top Right +* **3**: Bottom Left +* **4**: Bottom Right +* **5**: Centered +* **6**: Animated + +
+ +
+Click to expand: Optional Run Configurations (DinD & GPU Mounts) | Argument | Description | | :----: | --- | | `--privileged` | Starts a Docker-in-Docker (DinD) environment. For better performance, mount the Docker data directory from the host, e.g., `-v /path/to/docker-data:/var/lib/docker`. | | `-v /var/run/docker.sock:/var/run/docker.sock` | Mounts the host's Docker socket to manage host containers from within this container. | -| `--device /dev/dri:/dev/dri` | Mount a GPU into the container, this can be used in conjunction with the `DRINODE` environment variable to leverage a host video card for GPU accelerated applications. Only **Open Source** drivers are supported IE (Intel,AMDGPU,Radeon,ATI,Nouveau) | - -### Language Support - Internationalization - -To launch the desktop session in a different language, set the `LC_ALL` environment variable. For example: - -* `-e LC_ALL=zh_CN.UTF-8` - Chinese -* `-e LC_ALL=ja_JP.UTF-8` - Japanese -* `-e LC_ALL=ko_KR.UTF-8` - Korean -* `-e LC_ALL=ar_AE.UTF-8` - Arabic -* `-e LC_ALL=ru_RU.UTF-8` - Russian -* `-e LC_ALL=es_MX.UTF-8` - Spanish (Latin America) -* `-e LC_ALL=de_DE.UTF-8` - German -* `-e LC_ALL=fr_FR.UTF-8` - French -* `-e LC_ALL=nl_NL.UTF-8` - Netherlands -* `-e LC_ALL=it_IT.UTF-8` - Italian +| `--device /dev/dri:/dev/dri` | Mount a GPU into the container, this can be used in conjunction with the `DRINODE` environment variable to leverage a host video card for GPU accelerated applications. | -### SealSkin Compatibility - -This container is compatible with [SealSkin](https://github.com/linuxserver/docker-sealskin). - -SealSkin is a self-hosted, client-server platform that provides secure authentication and collaboration features while using a browser extension to intercept user actions such as clicking a link or downloading a file and redirect them to a secure, isolated application environment running on a remote server. +
-* **SealSkin Server:** [Get it Here](https://github.com/linuxserver/docker-sealskin) -* **Browser Extension:** [Install Here](https://chromewebstore.google.com/detail/sealskin-isolation/lclgfmnljgacfdpmmmjmfpdelndbbfhk) +
+Click to expand: Legacy X11 Resolution & Acceleration -### All GPU Acceleration - use sane resolutions +**Note:** This section applies only if you are **NOT** using `PIXELFLUX_WAYLAND=true`. -When using 3d acceleration via Nvidia DRM or DRI3 it is important to clamp the virtual display to a reasonable max resolution. This can be achieved with the environment setting: +When using 3d acceleration via Nvidia DRM or DRI3 in X11 mode, it is important to clamp the virtual display to a reasonable max resolution to avoid memory exhaustion or poor performance. * `-e MAX_RESOLUTION=3840x2160` -This will set the total virtual framebuffer to 4K, you can also set a manual resolution to achieve this. -By default the virtual monitor in the session is 16K to support large monitors and dual display configurations. Leaving it this large has no impact on CPU based performance but costs GPU memory usage and memory bandwidth when leveraging one for acceleration. If you have performance issues in an accelerated session, try clamping the resolution to 1080p and work up from there: +This will set the total virtual framebuffer to 4K. By default, the virtual monitor is 16K. If you have performance issues in an accelerated X11 session, try clamping the resolution to 1080p and work up from there: -``` +```bash -e SELKIES_MANUAL_WIDTH=1920 -e SELKIES_MANUAL_HEIGHT=1080 -e MAX_RESOLUTION=1920x1080 ``` -### DRI3 GPU Acceleration - -For accelerated apps or games, render devices can be mounted into the container and leveraged by applications using: - -`--device /dev/dri:/dev/dri` +
-This feature only supports **Open Source** GPU drivers: - -| Driver | Description | -| :----: | --- | -| Intel | i965 and i915 drivers for Intel iGPU chipsets | -| AMD | AMDGPU, Radeon, and ATI drivers for AMD dedicated or APU chipsets | -| NVIDIA | nouveau2 drivers only, closed source NVIDIA drivers lack DRI3 support | - -The `DRINODE` environment variable can be used to point to a specific GPU. - -DRI3 will work on aarch64 given the correct drivers are installed inside the container for your chipset. - -### Nvidia GPU Support - -**Note: Nvidia support is not available for Alpine-based images.** - -Nvidia GPU support is available by leveraging Zink for OpenGL. When a compatible Nvidia GPU is passed through, it will also be **automatically utilized for hardware-accelerated video stream encoding** (using the `x264enc` full-frame profile), significantly reducing CPU load. - -Enable Nvidia support with the following runtime flags: - -| Flag | Description | -| :----: | --- | -| `--gpus all` | Passes all available host GPUs to the container. This can be filtered to specific GPUs. | -| `--runtime nvidia` | Specifies the Nvidia runtime, which provides the necessary drivers and tools from the host. | - -For Docker Compose, you must first configure the Nvidia runtime as the default on the host: - -``` -sudo nvidia-ctk runtime configure --runtime=docker --set-as-default -sudo systemctl restart docker -``` +### Language Support - Internationalization -Then, assign the GPU to the service in your `compose.yaml`: +To launch the desktop session in a different language, set the `LC_ALL` environment variable. For example: -``` -services: - scummvm: - image: lscr.io/linuxserver/scummvm:latest - deploy: - resources: - reservations: - devices: - - driver: nvidia - count: 1 - capabilities: [compute,video,graphics,utility] -``` +* `-e LC_ALL=zh_CN.UTF-8` - Chinese +* `-e LC_ALL=ja_JP.UTF-8` - Japanese +* `-e LC_ALL=ko_KR.UTF-8` - Korean +* `-e LC_ALL=ar_AE.UTF-8` - Arabic +* `-e LC_ALL=ru_RU.UTF-8` - Russian +* `-e LC_ALL=es_MX.UTF-8` - Spanish (Latin America) +* `-e LC_ALL=de_DE.UTF-8` - German +* `-e LC_ALL=fr_FR.UTF-8` - French +* `-e LC_ALL=nl_NL.UTF-8` - Netherlands +* `-e LC_ALL=it_IT.UTF-8` - Italian ### Application Management @@ -232,7 +295,7 @@ Natively installed packages (e.g., via `apt-get install`) will not persist if th To install an application, use the command line inside the container: -``` +```bash proot-apps install filezilla ``` @@ -248,20 +311,19 @@ You can install packages from the system's native repository using the [universa - INSTALL_PACKAGES=libfuse2|git|gdb ``` -#### Hardening - -These variables can be used to lock down the desktop environment for single-application use cases or to restrict user capabilities. +### Advanced Configuration -##### Meta Variables +
+Click to expand: Hardening Options -These variables act as presets, enabling multiple hardening options at once. Individual options can still be set to override the preset. +These variables can be used to lock down the desktop environment for single-application use cases or to restrict user capabilities. | Variable | Description | | :----: | --- | | **`HARDEN_DESKTOP`** | Enables `DISABLE_OPEN_TOOLS`, `DISABLE_SUDO`, and `DISABLE_TERMINALS`. Also sets related Selkies UI settings (`SELKIES_FILE_TRANSFERS`, `SELKIES_COMMAND_ENABLED`, `SELKIES_UI_SIDEBAR_SHOW_FILES`, `SELKIES_UI_SIDEBAR_SHOW_APPS`) if they are not explicitly set by the user. | | **`HARDEN_OPENBOX`** | Enables `DISABLE_CLOSE_BUTTON`, `DISABLE_MOUSE_BUTTONS`, and `HARDEN_KEYBINDS`. It also flags `RESTART_APP` if not set by the user, ensuring the primary application is automatically restarted if closed. | -##### Individual Hardening Variables +**Individual Hardening Variables:** | Variable | Description | | :--- | --- | @@ -273,46 +335,30 @@ These variables act as presets, enabling multiple hardening options at once. Ind | **`HARDEN_KEYBINDS`** | If true, disables default Openbox keybinds that can bypass other hardening options (e.g., `Alt+F4` to close windows, `Alt+Escape` to show the root menu). | | **`RESTART_APP`** | If true, enables a watchdog service that automatically restarts the main application if it is closed. The user's autostart script is made read-only and root owned to prevent tampering. | -#### Selkies application settings +
-Using environment variables every facet of the application can be configured. - -##### Booleans and Locking -Boolean settings accept `true` or `false`. You can also prevent the user from changing a boolean setting in the UI by appending `|locked`. The UI toggle for this setting will be hidden. +
+Click to expand: Selkies Application Settings -* **Example**: To force CPU encoding on and prevent the user from disabling it: - ```bash - -e SELKIES_USE_CPU="true|locked" - ``` +Using environment variables every facet of the application can be configured. -##### Enums and Lists -These settings accept a comma-separated list of values. Their behavior depends on the number of items provided: +**Booleans and Locking:** +Boolean settings accept `true` or `false`. You can also prevent the user from changing a boolean setting in the UI by appending `|locked`. -* **Multiple Values**: The first item in the list becomes the default selection, and all items in the list become the available options in the UI dropdown. -* **Single Value**: The provided value becomes the default, and the UI dropdown is hidden because the choice is locked. +* Example: `-e SELKIES_USE_CPU="true|locked"` -* **Example**: Force the encoder to be `jpeg` with no other options available to the user: - ```bash - -e SELKIES_ENCODER="jpeg" - ``` +**Enums and Lists:** +These settings accept a comma-separated list of values. The first item becomes default. If only one item is provided, the UI dropdown is hidden. -##### Ranges -Range settings define a minimum and maximum for a value (e.g., framerate). +* Example: `-e SELKIES_ENCODER="jpeg"` -* **To set a range**: Use a hyphen-separated `min-max` format. The UI will show a slider. -* **To set a fixed value**: Provide a single number. This will lock the value and hide the UI slider. +**Ranges:** +Use a hyphen-separated `min-max` format for a slider, or a single number to lock the value. -* **Example**: Lock the framerate to exactly 60 FPS. - ```bash - -e SELKIES_FRAMERATE="60" - ``` - -##### Manual Resolution Mode -The server can be forced to use a single, fixed resolution for all connecting clients. This mode is automatically activated if `SELKIES_MANUAL_WIDTH`, `SELKIES_MANUAL_HEIGHT`, or `SELKIES_IS_MANUAL_RESOLUTION_MODE` is set. +* Example: `-e SELKIES_FRAMERATE="60"` -* If `SELKIES_MANUAL_WIDTH` and/or `SELKIES_MANUAL_HEIGHT` are set, the resolution is locked to those values. -* If `SELKIES_IS_MANUAL_RESOLUTION_MODE` is set to `true` without specifying width or height, the resolution defaults to **1024x768**. -* When this mode is active, the client UI for changing resolution is disabled. +**Manual Resolution Mode:** +If `SELKIES_MANUAL_WIDTH` or `SELKIES_MANUAL_HEIGHT` are set, the resolution is locked to those values. | Environment Variable | Default Value | Description | | --- | --- | --- | @@ -373,12 +419,14 @@ The server can be forced to use a single, fixed resolution for all connecting cl | `SELKIES_ENABLE_PLAYER3` | `True` | Enable sharing link for gamepad player 3. | | `SELKIES_ENABLE_PLAYER4` | `True` | Enable sharing link for gamepad player 4. | +
+ ## Usage To help you get started creating a container from this image you can either use docker-compose or the docker cli. >[!NOTE] ->Unless a parameter is flaged as 'optional', it is *mandatory* and a value must be provided. +>Unless a parameter is flagged as 'optional', it is *mandatory* and a value must be provided. ### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose)) diff --git a/jenkins-vars.yml b/jenkins-vars.yml index 156c59c..b7a01ce 100644 --- a/jenkins-vars.yml +++ b/jenkins-vars.yml @@ -2,10 +2,9 @@ # jenkins variables project_name: docker-scummvm -external_type: na -custom_version_command: "curl -s https://downloads.scummvm.org/frs/scummvm/ | awk -F'(
)' '{print $2}'| grep -B 1 'daily' |head -n1" +external_type: github_stable external_artifact_check: | - if curl -IfSsL "https://downloads.scummvm.org/frs/scummvm/${EXT_RELEASE}/scummvm_${EXT_RELEASE}-1_ubuntu24_04_amd64.deb" > /dev/null 2>&1; then + if curl -IfSsL "https://downloads.scummvm.org/frs/scummvm/$(echo ${EXT_RELEASE}| sed 's/^v//g')/scummvm_$(echo ${EXT_RELEASE}| sed 's/^v//g')-1_ubuntu24_04_amd64.deb" > /dev/null 2>&1; then artifacts_found="true" else artifacts_found="false" @@ -15,6 +14,8 @@ release_tag: latest ls_branch: master build_armhf: false repo_vars: + - EXT_USER = 'scummvm' + - EXT_REPO = 'scummvm' - BUILD_VERSION_ARG = 'SCUMMVM_VERSION' - LS_USER = 'linuxserver' - LS_REPO = 'docker-scummvm'