Skip to content

Fixed the CAP_NET_RAW capabilities were not inherited. #936

Fixed the CAP_NET_RAW capabilities were not inherited.

Fixed the CAP_NET_RAW capabilities were not inherited. #936

Workflow file for this run

---
name: Unit-test
on: # yamllint disable-line rule:truthy
pull_request:
workflow_call:
concurrency:
group: '${{ github.workflow }} @ ${{ github.ref }}'
cancel-in-progress: true
jobs:
unit-test-amd64-steamcmd:
name: Docker - Test (amd64-steamcmd)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Test negative delta recovery setting
run: ./tests/test-negative-delta-recovery.sh
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build and export to Docker
uses: docker/build-push-action@v7
with:
file: ./Dockerfile
load: true
tags: ${{ github.run_id }}
platforms: linux/amd64
- name: Reject invalid negative delta recovery setting
run: |
set +e
output="$(timeout --signal=TERM --kill-after=5s 30s docker run --rm \
--name palworld-server-invalid-${{ github.run_id }} \
--env-file .env.example \
-e PALWORLD_ALLOW_NEGATIVE_DELTA_TIME=invalid \
${{ github.run_id }} 2>&1)"
status=$?
set -e
docker rm -f palworld-server-invalid-${{ github.run_id }} >/dev/null 2>&1 || true
if [ "${status}" -ne 1 ]; then
echo "Expected exit code 1 for invalid setting, got ${status}."
exit 1
fi
if ! grep -Fq \
"PALWORLD_ALLOW_NEGATIVE_DELTA_TIME must be true or false." \
<<< "${output}"; then
echo "Expected invalid-setting error was not logged."
exit 1
fi
- name: Reject empty negative delta recovery setting
run: |
set +e
output="$(timeout --signal=TERM --kill-after=5s 30s docker run --rm \
--name palworld-server-empty-${{ github.run_id }} \
--env-file .env.example \
-e PALWORLD_ALLOW_NEGATIVE_DELTA_TIME= \
${{ github.run_id }} 2>&1)"
status=$?
set -e
docker rm -f palworld-server-empty-${{ github.run_id }} >/dev/null 2>&1 || true
if [ "${status}" -ne 1 ]; then
echo "Expected exit code 1 for empty setting, got ${status}."
exit 1
fi
if ! grep -Fq \
"PALWORLD_ALLOW_NEGATIVE_DELTA_TIME must be true or false." \
<<< "${output}"; then
echo "Expected empty-setting error was not logged."
exit 1
fi
- name: Run server
run: |
docker run -d \
--name palworld-server \
-p 8211:8211/udp \
-p 27015:27015/udp \
-p 25575:25575/tcp \
-v ./palworld:/palworld/ \
--env-file .env.example \
--restart unless-stopped \
--stop-timeout 30 \
${{ github.run_id }}
- name: Wait for server to start
run: |
TIMEOUT_SECONDS=240
START_TIME=$(date +%s)
while ! docker logs palworld-server 2>&1 | grep -q "Setting breakpad minidump AppID"; do
CURRENT_TIME=$(date +%s)
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
if [ $ELAPSED_TIME -gt $TIMEOUT_SECONDS ]; then
echo "Timeout reached. Server failed to start within $TIMEOUT_SECONDS seconds."
printf "\e[0;32m%s\e[0m\n" "*****Container LOGS*****"
docker logs palworld-server
exit 1
fi
echo "Waiting for server to start..."
sleep 5
done
- name: Test negative delta recovery is disabled by default
run: |
docker exec palworld-server bash -c '
pal_pid="$(pidof PalServer-Linux-Shipping)"
pal_pid="${pal_pid%% *}"
if [ -z "${pal_pid}" ]; then
echo "PalServer process is missing."
exit 1
fi
mapfile -d "" -t arguments < "/proc/${pal_pid}/cmdline"
for argument in "${arguments[@]}"; do
if [ "${argument}" = "-ini:Engine:[ConsoleVariables]:Pal.AllowNegativeDeltaTime=1" ]; then
echo "Negative delta recovery was unexpectedly enabled."
exit 1
fi
done
'
# - name: Test if rcon.yaml is valid
# run: |
# printf "\e[0;32m%s\e[0m\n" "*****RCON.YAML*****"
# docker exec palworld-server cat /home/steam/server/rcon.yaml
# RCON_PORT=$(docker exec palworld-server env | grep RCON_PORT | cut -d'=' -f2)
# ADMIN_PASSWORD=$(docker exec palworld-server env | grep ADMIN_PASSWORD | cut -d'=' -f2)
# YAML_PORT=$(docker exec palworld-server cat /home/steam/server/rcon.yaml | grep "^ address:" | awk '{print $2}' | cut -d ':' -f2 | tr -d '"')
# YAML_PASSWORD=$(docker exec palworld-server cat /home/steam/server/rcon.yaml | grep "^ password:" | awk '{print $2}' | tr -d '"')
# if [ ! $RCON_PORT == $YAML_PORT ]; then
# echo "Error: $RCON_PORT in .env.example does not match $YAML_PORT in rcon.yaml."
# exit 2
# fi
# if [ ! "$ADMIN_PASSWORD" == "$YAML_PASSWORD" ]; then
# echo "Error: $ADMIN_PASSWORD in .env.example does not match $YAML_PASSWORD in rcon.yaml."
# exit 3
# fi
# - name: Test if rcon works
# run: |
# sleep 5
# if ! docker exec palworld-server rcon-cli Info | grep -q "Welcome to Pal Server"; then
# echo "Server may not have started successfully."
# exit 4
# fi
# OUTPUT=$(docker exec palworld-server rcon-cli "Broadcast test" 2>&1)
# if [[ $OUTPUT != *"Broadcasted: test"* ]]; then
# echo "Error: Unexpected output - $OUTPUT"
# exit 5
# fi
# OUTPUT=$(docker exec palworld-server rcon-cli save 2>&1)
# if [[ $OUTPUT != *"Complete Save"* ]]; then
# echo "Error: Unexpected output - $OUTPUT"
# exit 6
# fi
- name: Test if the REST API works
run: |
sleep 100
if ! docker exec palworld-server rest-cli info | grep -q "\"version\"\:"; then
echo "Server may not have started successfully."
exit 4
fi
docker exec palworld-server rest-cli announce "Hello, Palworld!"
if docker logs palworld-server 2>&1 | grep -q "REST accessed endpoint /v1/api/announce OK"; then
echo "Announce OK — continuing."
else
echo "Required log entry not found — exiting with code 5."
exit 5
fi
docker exec palworld-server rest-cli save
if docker logs palworld-server 2>&1 | grep -q "REST accessed endpoint /v1/api/save OK"; then
echo "Save OK — continuing."
else
echo "Required log entry not found — exiting with code 5."
exit 5
fi
- name: Test if port 8211, 27015, 25575 and 8212 are listening
run: |
nc -z -u -v 127.0.0.1 8211 || exit 7
nc -z -u -v 127.0.0.1 27015 || exit 8
nc -z -v 127.0.0.1 25575 || exit 9
- name: Test the backup script
run: |
docker exec palworld-server backup
if [ ! -f ./palworld/backups/palworld-save-*.tar.gz ]; then
echo "Backup file not found. Backup command may have failed."
exit 10
fi
- name: Test if PalWorldSettings.ini is valid
run: |
if [ ! -f ./palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini ]; then
echo "Error: PalWorldSettings.ini file is missing."
exit 11
fi
if ! grep -q "\[\/Script\/Pal.PalGameWorldSettings\]" ./palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini; then
echo "Error: PalWorldSettings.ini is missing the required section [/Script/Pal.PalGameWorldSettings]."
exit 12
fi
if ! grep -q "^OptionSettings=\(.*\)" ./palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini; then
echo "Error: PalWorldSettings.ini is missing or has an invalid OptionSettings section."
exit 13
fi
# unit-test-amd64-depotdownloader:
# name: Docker - Test (amd64-depotdownloader)
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v7
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v4
# - name: Build and export to Docker
# uses: docker/build-push-action@v7
# with:
# file: ./Dockerfile
# load: true
# tags: ${{ github.run_id }}
# platforms: linux/amd64
# - name: Run server
# run: |
# sed -i 's/^USE_DEPOT_DOWNLOADER=False/USE_DEPOT_DOWNLOADER=True/' .env.example && \
# docker run -d \
# --name palworld-server \
# -p 8211:8211/udp \
# -p 27015:27015/udp \
# -p 25575:25575/tcp \
# -v ./palworld:/palworld/ \
# --env-file .env.example \
# --restart unless-stopped \
# --stop-timeout 30 \
# ${{ github.run_id }}
# - name: Wait for server to start
# run: |
# TIMEOUT_SECONDS=180
# START_TIME=$(date +%s)
# while ! docker logs palworld-server 2>&1 | grep -q "Setting breakpad minidump AppID"; do
# CURRENT_TIME=$(date +%s)
# ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
# if [ $ELAPSED_TIME -gt $TIMEOUT_SECONDS ]; then
# echo "Timeout reached. Server failed to start within $TIMEOUT_SECONDS seconds."
# printf "\e[0;32m%s\e[0m\n" "*****Container LOGS*****"
# docker logs palworld-server
# exit 1
# fi
# echo "Waiting for server to start..."
# sleep 5
# done
# # - name: Test if rcon.yaml is valid
# # run: |
# # printf "\e[0;32m%s\e[0m\n" "*****RCON.YAML*****"
# # docker exec palworld-server cat /home/steam/server/rcon.yaml
# # RCON_PORT=$(docker exec palworld-server env | grep RCON_PORT | cut -d'=' -f2)
# # ADMIN_PASSWORD=$(docker exec palworld-server env | grep ADMIN_PASSWORD | cut -d'=' -f2)
# # YAML_PORT=$(docker exec palworld-server cat /home/steam/server/rcon.yaml | grep "^ address:" | awk '{print $2}' | cut -d ':' -f2 | tr -d '"')
# # YAML_PASSWORD=$(docker exec palworld-server cat /home/steam/server/rcon.yaml | grep "^ password:" | awk '{print $2}' | tr -d '"')
# # if [ ! $RCON_PORT == $YAML_PORT ]; then
# # echo "Error: $RCON_PORT in .env.example does not match $YAML_PORT in rcon.yaml."
# # exit 2
# # fi
# # if [ ! "$ADMIN_PASSWORD" == "$YAML_PASSWORD" ]; then
# # echo "Error: $ADMIN_PASSWORD in .env.example does not match $YAML_PASSWORD in rcon.yaml."
# # exit 3
# # fi
# # - name: Test if rcon works
# # run: |
# # sleep 5
# # if ! docker exec palworld-server rcon-cli Info | grep -q "Welcome to Pal Server"; then
# # echo "Server may not have started successfully."
# # exit 4
# # fi
# # OUTPUT=$(docker exec palworld-server rcon-cli "Broadcast test" 2>&1)
# # if [[ $OUTPUT != *"Broadcasted: test"* ]]; then
# # echo "Error: Unexpected output - $OUTPUT"
# # exit 5
# # fi
# # OUTPUT=$(docker exec palworld-server rcon-cli save 2>&1)
# # if [[ $OUTPUT != *"Complete Save"* ]]; then
# # echo "Error: Unexpected output - $OUTPUT"
# # exit 6
# # fi
# - name: Test if the REST API works
# run: |
# sleep 10
# if ! docker exec palworld-server rest-cli info | grep -q "\"version\"\:"; then
# echo "Server may not have started successfully."
# exit 4
# fi
# docker exec palworld-server rest-cli announce "Hello, Palworld!"
# if docker logs palworld-server 2>&1 | grep -q "REST accessed endpoint /v1/api/announce OK"; then
# echo "Announce OK — continuing."
# else
# echo "Required log entry not found — exiting with code 5."
# exit 5
# fi
# docker exec palworld-server rest-cli save
# if docker logs palworld-server 2>&1 | grep -q "REST accessed endpoint /v1/api/save OK"; then
# echo "Save OK — continuing."
# else
# echo "Required log entry not found — exiting with code 5."
# exit 5
# fi
# - name: Test if port 8211, 27015, 25575 and 8212 are listening
# run: |
# nc -z -u -v 127.0.0.1 8211 || exit 7
# nc -z -u -v 127.0.0.1 27015 || exit 8
# nc -z -v 127.0.0.1 25575 || exit 9
# - name: Test the backup script
# run: |
# docker exec palworld-server backup
# if [ ! -f ./palworld/backups/palworld-save-*.tar.gz ]; then
# echo "Backup file not found. Backup command may have failed."
# exit 10
# fi
# - name: Test if PalWorldSettings.ini is valid
# run: |
# if [ ! -f ./palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini ]; then
# echo "Error: PalWorldSettings.ini file is missing."
# exit 11
# fi
# if ! grep -q "\[\/Script\/Pal.PalGameWorldSettings\]" ./palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini; then
# echo "Error: PalWorldSettings.ini is missing the required section [/Script/Pal.PalGameWorldSettings]."
# exit 12
# fi
# if ! grep -q "^OptionSettings=\(.*\)" ./palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini; then
# echo "Error: PalWorldSettings.ini is missing or has an invalid OptionSettings section."
# exit 13
# fi
unit-test-arm64:
name: Docker - Test (arm64)
runs-on: [self-hosted, ARM64]
steps:
- name: Checkout
uses: actions/checkout@v7
# - name: Set up QEMU
# uses: docker/setup-qemu-action@v3
# with:
# image: tonistiigi/binfmt:qemu-v8.1.5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build and export to Docker
uses: docker/build-push-action@v7
with:
file: ./Dockerfile
load: true
tags: ${{ github.run_id }}:arm64
platforms: linux/arm64
- name: Run server
run: |
sed -i 's/^USE_DEPOT_DOWNLOADER=False/USE_DEPOT_DOWNLOADER=true/' .env.example && \
docker run -d \
--name palworld-server-${{ github.run_id }} \
--platform linux/arm64 \
-p 8211:8211/udp \
-p 27015:27015/udp \
-p 25575:25575/tcp \
-v ./palworld-${{ github.run_id }}:/palworld/ \
--env-file .env.example \
-e PALWORLD_ALLOW_NEGATIVE_DELTA_TIME=true \
--restart unless-stopped \
--stop-timeout 30 \
${{ github.run_id }}:arm64
- name: Wait for server to start
run: |
TIMEOUT_SECONDS=660
START_TIME=$(date +%s)
while ! docker logs palworld-server-${{ github.run_id }} 2>&1 | grep -q "Setting breakpad minidump AppID"; do
CURRENT_TIME=$(date +%s)
ELAPSED_TIME=$((CURRENT_TIME - START_TIME))
if [ $ELAPSED_TIME -gt $TIMEOUT_SECONDS ]; then
echo "Timeout reached. Server failed to start within $TIMEOUT_SECONDS seconds."
printf "\e[0;32m%s\e[0m\n" "*****Container LOGS*****"
docker logs palworld-server-${{ github.run_id }}
exit 1
fi
echo "Waiting for server to start..."
sleep 5
done
- name: Test negative delta recovery process argument
run: |
docker exec palworld-server-${{ github.run_id }} bash -c '
pal_pid="$(pidof PalServer-Linux-Shipping)"
pal_pid="${pal_pid%% *}"
if [ -z "${pal_pid}" ]; then
echo "PalServer process is missing."
exit 1
fi
mapfile -d "" -t arguments < "/proc/${pal_pid}/cmdline"
count=0
for argument in "${arguments[@]}"; do
if [ "${argument}" = "-ini:Engine:[ConsoleVariables]:Pal.AllowNegativeDeltaTime=1" ]; then
count=$((count + 1))
fi
done
if [ "${count}" -ne 1 ]; then
echo "Expected exactly one negative delta recovery process argument."
exit 1
fi
'
# RCON is deprecated, so skipping this test for now
# - name: Test if rcon.yaml is valid
# run: |
# printf "\e[0;32m%s\e[0m\n" "*****RCON.YAML*****"
# docker exec palworld-server-${{ github.run_id }} cat /home/steam/server/rcon.yaml
# RCON_PORT=$(docker exec palworld-server-${{ github.run_id }} env | grep RCON_PORT | cut -d'=' -f2)
# ADMIN_PASSWORD=$(docker exec palworld-server-${{ github.run_id }} env | grep ADMIN_PASSWORD | cut -d'=' -f2)
# YAML_PORT=$(docker exec palworld-server-${{ github.run_id }} cat /home/steam/server/rcon.yaml | grep "^ address:" | awk '{print $2}' | cut -d ':' -f2 | tr -d '"')
# YAML_PASSWORD=$(docker exec palworld-server-${{ github.run_id }} cat /home/steam/server/rcon.yaml | grep "^ password:" | awk '{print $2}' | tr -d '"')
# if [ ! $RCON_PORT == $YAML_PORT ]; then
# echo "Error: $RCON_PORT in .env.example does not match $YAML_PORT in rcon.yaml."
# exit 2
# fi
# if [ ! "$ADMIN_PASSWORD" == "$YAML_PASSWORD" ]; then
# echo "Error: $ADMIN_PASSWORD in .env.example does not match $YAML_PASSWORD in rcon.yaml."
# exit 3
# fi
# - name: Test if rcon works
# run: |
# sleep 100
# if ! docker exec palworld-server-${{ github.run_id }} rcon-cli Info | grep -q "Welcome to Pal Server"; then
# echo "Server may not have started successfully."
# exit 4
# fi
# OUTPUT=$(docker exec palworld-server-${{ github.run_id }} rcon-cli "Broadcast test" 2>&1)
# if [[ $OUTPUT != *"Broadcasted: test"* ]]; then
# echo "Error: Unexpected output - $OUTPUT"
# exit 5
# fi
# OUTPUT=$(docker exec palworld-server-${{ github.run_id }} rcon-cli save 2>&1)
# if [[ $OUTPUT != *"Complete Save"* ]]; then
# echo "Error: Unexpected output - $OUTPUT"
# exit 6
# fi
- name: Test if the REST API works
run: |
sleep 180
if ! docker exec palworld-server-${{ github.run_id }} rest-cli info | grep -q "\"version\"\:"; then
echo "Server may not have started successfully."
exit 4
fi
docker exec palworld-server-${{ github.run_id }} rest-cli announce "Hello, Palworld!"
if docker logs palworld-server-${{ github.run_id }} 2>&1 | grep -q "REST accessed endpoint /v1/api/announce OK"; then
echo "Announce OK — continuing."
else
echo "Required log entry not found — exiting with code 5."
exit 5
fi
docker exec palworld-server-${{ github.run_id }} rest-cli save
if docker logs palworld-server-${{ github.run_id }} 2>&1 | grep -q "REST accessed endpoint /v1/api/save OK"; then
echo "Save OK — continuing."
else
echo "Required log entry not found — exiting with code 5."
exit 5
fi
- name: Test if port 8211, 27015, 25575 and 8212 are listening
run: |
nc -z -u -v 127.0.0.1 8211 || exit 7
nc -z -u -v 127.0.0.1 27015 || exit 8
nc -z -v 127.0.0.1 25575 || exit 9
- name: Test the backup script
run: |
docker exec palworld-server-${{ github.run_id }} backup
if [ ! -f ./palworld-${{ github.run_id }}/backups/palworld-save-*.tar.gz ]; then
echo "Backup file not found. Backup command may have failed."
exit 10
fi
- name: Test if PalWorldSettings.ini is valid
run: |
if [ ! -f ./palworld-${{ github.run_id }}/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini ]; then
echo "Error: PalWorldSettings.ini file is missing."
exit 11
fi
if ! grep -q "\[\/Script\/Pal.PalGameWorldSettings\]" ./palworld-${{ github.run_id }}/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini; then
echo "Error: PalWorldSettings.ini is missing the required section [/Script/Pal.PalGameWorldSettings]."
exit 12
fi
if ! grep -q "^OptionSettings=\(.*\)" ./palworld-${{ github.run_id }}/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini; then
echo "Error: PalWorldSettings.ini is missing or has an invalid OptionSettings section."
exit 13
fi
- name: Stop server
if: always()
run: |
docker stop palworld-server-${{ github.run_id }}
docker rm palworld-server-${{ github.run_id }}