Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ and on top of that:

- Managing game servers using `Linux Gameservers`_:

- Downloads newest version during first boot to ensure best possible game
support.
- Wrapper for `LinuxGSM`_ with support for up to 100 games.
- Installs a verified game catalog and LinuxGSM stable release.
- Wrapper for `LinuxGSM`_ with support for more than 100 game servers.
- ``turnkey-gameserver-update`` checks or applies verified catalog and
LinuxGSM updates. Individual game servers retain their LinuxGSM update
command.

- Fully automatic or interactive game server selection:

Expand All @@ -31,7 +33,7 @@ and on top of that:
Credentials *(passwords set at first boot)*
-------------------------------------------

- Webmin, SSH, Shellinabox: username **root**
- Webmin, SSH: username **root**
- Game server: username **gameuser**

.. _TurnKey GNU/Linux: https://www.turnkeylinux.org/
Expand Down
14 changes: 14 additions & 0 deletions changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
turnkey-gameserver-19.0 (1) turnkey; urgency=low

* Port the appliance to Debian 13 (Trixie).

* Pin the official game catalog wrapper and LinuxGSM v26.2.0 bootstrap with
verified source records.

* Add a supervised updater for the wrapper master and LinuxGSM stable tags.

* Preserve interactive and unattended game selection, Configuration Console
management, non-root game processes, and systemd service lifecycle.

-- TurnKey Linux release engineering <release-engineering@turnkeylinux.org> Tue, 25 Aug 2026 22:30:00 +0000

turnkey-gameserver-18.1 (1) turnkey; urgency=low

* v18.1 rebuild - includes latest Debian & TurnKey packages.
Expand Down
27 changes: 27 additions & 0 deletions conf.d/downloads
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash -e

set -o pipefail
set -x

SRC=/usr/local/src
WRAPPER_COMMIT=d2017be9f56db0da2a1c45651e656f47bc7ce42a
WRAPPER_ARCHIVE=linux-gameservers-$WRAPPER_COMMIT.zip
WRAPPER_SHA256=302b859632e34715f88b6f3455b7925efe822fb0b6b4a04514af12c1143cb983
LINUXGSM_VERSION=v26.2.0
LINUXGSM_BOOTSTRAP=linuxgsm-$LINUXGSM_VERSION.sh
LINUXGSM_SHA256=0a17b88b4d6a272ce8494d55fc0c2748f3187057c15b801d71991428aa8f79bd

proxy_args=()
if [ -n "${FAB_HTTP_PROXY:-}" ]; then
proxy_args=(--proxy "$FAB_HTTP_PROXY")
fi

curl -LfsS "${proxy_args[@]}" \
"https://github.com/jesinmat/linux-gameservers/archive/$WRAPPER_COMMIT.zip" \
-o "$SRC/$WRAPPER_ARCHIVE"
curl -LfsS "${proxy_args[@]}" \
"https://raw.githubusercontent.com/GameServerManagers/LinuxGSM/$LINUXGSM_VERSION/linuxgsm.sh" \
-o "$SRC/$LINUXGSM_BOOTSTRAP"

printf '%s %s\n' "$WRAPPER_SHA256" "$SRC/$WRAPPER_ARCHIVE" | sha256sum -c -
printf '%s %s\n' "$LINUXGSM_SHA256" "$SRC/$LINUXGSM_BOOTSTRAP" | sha256sum -c -
95 changes: 69 additions & 26 deletions conf.d/main
Original file line number Diff line number Diff line change
@@ -1,37 +1,80 @@
#!/bin/sh -ex
#!/bin/bash -e

GAMEUSER="gameuser"
GAME_REPO_DIR="/root/gameservers"
GAME_REPO_URL="https://github.com/jesinmat/linux-gameservers.git"
set -o pipefail
set -x

# Add i386 arch (common for lots of games) and install lib32gcc1
dpkg --add-architecture i386
dir=/etc/apt/sources.list.d
for list in $dir/sources.list $dir/security.sources.list; do
sed -i "\|turnkeylinux.org| s|\[|\[arch=amd64, |" $list
GAMEUSER=gameuser
GAME_REPO_DIR=/root/gameservers
SRC=/usr/local/src
WRAPPER_COMMIT=d2017be9f56db0da2a1c45651e656f47bc7ce42a
WRAPPER_ARCHIVE=linux-gameservers-$WRAPPER_COMMIT.zip
WRAPPER_SHA256=302b859632e34715f88b6f3455b7925efe822fb0b6b4a04514af12c1143cb983
LINUXGSM_VERSION=v26.2.0
LINUXGSM_TAG_COMMIT=bded3376bc44d20b89fcc6c32f23a66347fffec6
LINUXGSM_BOOTSTRAP=linuxgsm-$LINUXGSM_VERSION.sh
LINUXGSM_SHA256=0a17b88b4d6a272ce8494d55fc0c2748f3187057c15b801d71991428aa8f79bd

# Older game servers still need i386 libraries. Restrict TurnKey package
# sources to amd64 before enabling Debian multiarch.
for source_file in /etc/apt/sources.list.d/*; do
[ -f "$source_file" ] || continue
grep -q 'turnkeylinux.org' "$source_file" || continue
if grep -q '^Types:' "$source_file"; then
if grep -q '^Architectures:' "$source_file"; then
sed -i 's/^Architectures:.*/Architectures: amd64/' "$source_file"
else
sed -i '/^Types:/a Architectures: amd64' "$source_file"
fi
else
sed -i -E '/turnkeylinux\.org/ { /\[[^]]*arch=/! s|^deb[[:space:]]+|deb [arch=amd64] |; }' "$source_file"
fi
done
dpkg --add-architecture i386
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y lib32gcc-s1

# Create GAMEUSER as (limited) sudo user (initially commented out - running
# gameserver-init will enable it; then disable it afterwards).
useradd -m -s /bin/bash "$GAMEUSER"
match="# Cmnd alias specification"
line1="Cmnd_Alias APT_GET = /usr/bin/apt-get"
line2="Cmnd_Alias TRUE = /usr/bin/true"
line3="#$GAMEUSER ALL=(ALL) NOPASSWD: APT_GET, TRUE"
for line in "$line1" "$line2"; do
sed -i "\|$match| a $line" /etc/sudoers
done
echo >> /etc/sudoers
echo "$line3" >> /etc/sudoers
cat > /etc/sudoers.d/gameserver-install <<EOF
Cmnd_Alias GAMESERVER_APT_GET = /usr/bin/apt-get
Cmnd_Alias GAMESERVER_TRUE = /usr/bin/true
#$GAMEUSER ALL=(ALL) NOPASSWD: GAMESERVER_APT_GET, GAMESERVER_TRUE
EOF
chmod 0440 /etc/sudoers.d/gameserver-install
visudo -cf /etc/sudoers.d/gameserver-install

install -d -m 0755 /etc/ssh/sshd_config.d
printf 'DenyUsers %s\n' "$GAMEUSER" > /etc/ssh/sshd_config.d/turnkey-gameserver.conf

unzip -q "$SRC/$WRAPPER_ARCHIVE" -d /root
mv "/root/linux-gameservers-$WRAPPER_COMMIT" "$GAME_REPO_DIR"
rm -f "$SRC/$WRAPPER_ARCHIVE"

install -d -m 0755 /usr/local/share/turnkey-gameserver
install -m 0755 "$SRC/$LINUXGSM_BOOTSTRAP" \
/usr/local/share/turnkey-gameserver/linuxgsm.sh
rm -f "$SRC/$LINUXGSM_BOOTSTRAP"

# Keep the wrapper on Debian package names and the verified LinuxGSM release.
sed -i 's/bsdmainutils/bsdextrautils/' "$GAME_REPO_DIR/auto_install.sh"
sed -i '\|run_as_user "wget -O .*https://linuxgsm.sh"|c\ install -o "$GAMEUSER" -g "$GAMEUSER" -m 0755 /usr/local/share/turnkey-gameserver/linuxgsm.sh "$LGSM_PATH"' \
"$GAME_REPO_DIR/auto_install.sh"
grep -q 'install -o "$GAMEUSER".*turnkey-gameserver/linuxgsm.sh' \
"$GAME_REPO_DIR/auto_install.sh"

# disable SSH login for GAMEUSER
echo "DenyUsers $GAMEUSER" >> /etc/ssh/sshd_config
# Mumble was removed from LinuxGSM and can no longer be installed.
rm -rf "$GAME_REPO_DIR/games/mumble"

git clone --depth=1 "$GAME_REPO_URL" "$GAME_REPO_DIR"
cat > /usr/local/share/turnkey-gameserver/source <<EOF
wrapper_channel=official jesinmat/linux-gameservers master
wrapper_commit=$WRAPPER_COMMIT
wrapper_archive_sha256=$WRAPPER_SHA256
linuxgsm_channel=official stable tags
linuxgsm_version=$LINUXGSM_VERSION
linuxgsm_tag_commit=$LINUXGSM_TAG_COMMIT
linuxgsm_bootstrap_sha256=$LINUXGSM_SHA256
EOF

mkdir -p /var/log/gameserver
install -d -m 0755 /var/log/gameserver

# remove unused/unneeded images
rm -f /var/www/images/{adminer.png,shell.png}
# The landing page supplied by tkl-webcp does not use these icons.
rm -f /var/www/images/adminer.png /var/www/images/shell.png
43 changes: 13 additions & 30 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ using a graphical interface.
During the installation, you will be asked to provide basic server settings for
the game server.

If for some reason the install is interupted or fails, but reports success;
please remove /etc/gameserver/installation.done and retry. I.e.::
If an installation is interrupted or fails, retry it with::

rm /etc/gameserver/installation.done
gameserver-init
Expand Down Expand Up @@ -59,9 +58,10 @@ later by logging into the appliance and following the guide in `Manual headless
installation`_.

Update gameserver list
----------------------------
----------------------

If a game on the `supported games <https://github.com/jesinmat/linux-gameservers/tree/master#supported-games>`_ list is missing, you need to update the gameserver list. There are two methods to update the gameserver list, through the Configuration Console or updating the repo from the CLI.
The Configuration Console and CLI use the same verified update channel for the
game catalog and LinuxGSM bootstrap.



Expand All @@ -81,26 +81,16 @@ Method 1:
Method 2:
^^^^^^^^^^^

#. SSH into the appliance and stop the service::

~# systemctl stop gameserver

#. Change to gameservers directory::

~# cd /root/gameservers/
#. SSH into the appliance and check the official channels::

#. Pull down the latest from the git repo::
~# turnkey-gameserver-update --check

~/gameservers# git pull origin master
#. Apply the verified catalog and LinuxGSM release::

#. Start the gameserver service::

~/gameservers# systemctl start gameserver

Done!
~# turnkey-gameserver-update --apply

Update game server version
----------------------------
--------------------------
If there is an update to the game after deploying your server, you may need to update the server to allow clients with the newer version to connect. Like with updating the game server list, this can either be done through the GUI or manually. Here are instructions for the two methods:

Method 1:
Expand All @@ -127,21 +117,14 @@ Method 2:

~# systemctl stop gameserver

#. Change to gameservers directory::

~# cd /root/gameservers/

#. Update your game server (replace ``<CODE>`` with the Code from step 1)::

~# ./auto_install.sh -g <CODE> -u gameuser -p /home/gameuser/gameserver

e.g. for a Satisfactory server (code ``sf``)
#. Check and update your game server (replace ``<CODE>`` with its code)::

``~# ./auto_install.sh -g sf -u gameuser -p /home/gameuser/gameserver``
~# sudo -H -u gameuser /home/gameuser/gameserver/<CODE>server check-update
~# sudo -H -u gameuser /home/gameuser/gameserver/<CODE>server update

#. Start the game server back up::

~# ./sfserver start
~# systemctl start gameserver

The server should now be updated to the latest version of the game.

Expand Down
81 changes: 81 additions & 0 deletions docs/v19.0-testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# GameServer v19 migration evidence

## Source and state boundaries

Debian supplies Nginx, the 32-bit compatibility library, and all management
dependencies. The game catalog wrapper and LinuxGSM are application sources
that Debian does not package for this appliance contract.

The build uses these exact official upstream sources:

- `jesinmat/linux-gameservers` master commit
`d2017be9f56db0da2a1c45651e656f47bc7ce42a`
- Wrapper archive SHA256
`302b859632e34715f88b6f3455b7925efe822fb0b6b4a04514af12c1143cb983`
- LinuxGSM `v26.2.0` tag commit
`bded3376bc44d20b89fcc6c32f23a66347fffec6`
- LinuxGSM bootstrap SHA256
`0a17b88b4d6a272ce8494d55fc0c2748f3187057c15b801d71991428aa8f79bd`

LinuxGSM v26.2.0 includes Debian 13 dependency metadata and explicit handling
for game servers whose vendor binaries do not support newer distributions.
LinuxGSM accepts private vulnerability reports through its GitHub security
advisory form. The wrapper has no separate published security process, so its
official repository issue and maintainer channels are the available route.

The default source record binds both upstreams. Selecting a custom wrapper
repository at first boot changes that record to the custom channel, and the
official updater then stops with an explicit custom-source boundary instead of
overwriting it.

## Acceptance crosswalk

| Appliance contract | `tests/v19.sh` evidence |
| --- | --- |
| Management UI | Loads the Nginx GameServer landing page, its Webmin link, the selector command, and the Configuration Console update action. |
| Supported server list | Runs the installed wrapper list, requires at least 100 entries, checks a known lightweight definition, and rejects the removed Mumble entry. |
| Catalog and LinuxGSM update | Resolves the official wrapper master and latest stable LinuxGSM tag, verifies exact candidate artifacts, and exercises the apply dry run. |
| Service lifecycle | Starts and stops the systemd unit against a disposable non-root fixture and observes both actions. |
| Non-root server boundary | Runs the fixture through the same `runuser` start and stop scripts used by installed servers. |
| Automatic and interactive selection | Runs `gameserver-init` with the catalog's lightweight TeamSpeak target, requires LinuxGSM installation completion, and verifies the server through LinuxGSM's monitor command. |
| TurnKey platform surfaces | Core supplies SSH, Webmin, TLS, backups, and first-boot integration. The appliance test covers GameServer-specific behavior. |

The runtime test emits exactly the seven Wave 2 result keys: package source,
installed version, runtime checks, updater command, updater result, updater
channel, and integrity evidence.

## Candidate status

Candidate `a57d42a3f90562d241ec9f85aa00d2856eae3e0c` passed the exact container
acceptance command:

```sh
/sandboxed-git/turnkey/tools/test-v19-appliance gameserver \
--source /home/agent/.local/worktrees/turnkey-apps/gameserver/wish-gameserver-v19-trixie
```

Run `20260826t130005z-2603-3322` built and imported the Trixie rootfs, reached
multi-user state with inithooks complete, and passed every application check in
the crosswalk. The retained report is
`/home/agent/.local/state/turnkey-v19-harness/runs/gameserver/20260826t130005z-2603-3322/report.txt`
with SHA256
`70bc728761c5d0515e5ff95467ba06feda0bfc09e14d672b8a5b3c871c8579a9`.

Product-fix accounting is 2 of 3. The first loop made installer failures
propagate through the logging pipeline. The second removed the Mumble choice
after exact acceptance proved that LinuxGSM v26.2.0 no longer supports its
server identifier. Test-only HTTP acceptance corrections did not consume a
product loop.

## Deferred issues

- MEDIUM: The upstream wrapper has 120 definitions, but some lag the current
LinuxGSM catalog. The known broken Mumble choice is excluded. The updater
checks both channels independently, but other additions and removals still
need matching wrapper catalog changes before the selector reflects them.
- MEDIUM: Acceptance installs the lightweight TeamSpeak target through the real
catalog and LinuxGSM path. Other game downloads differ substantially in size,
licensing, authentication, and network behavior, so this does not prove every
vendor-specific installer.
- LOW: The test checks the real landing page and Configuration Console action
boundary without automating the terminal dialog renderer.
Loading