mirror of
https://github.com/GTNewHorizons/GTNH-Actions-Workflows.git
synced 2026-07-15 12:29:55 +02:00
119 lines
3.6 KiB
Bash
119 lines
3.6 KiB
Bash
#!/usr/bin/env bash
|
|
# Server side of the integration run: starts the server, lets it settle, then
|
|
# stops it cleanly and records the exit code for later verification.
|
|
#
|
|
# This script does not decide whether a run was good. That is verified later by
|
|
# verify_server.sh, which reads the outputs produced here (server.log and the
|
|
# exit-code flag).
|
|
#
|
|
# Base logic moved here from https://github.com/MalTeeez/packscripts-auto-builds/blob/gtnh-daily/packaging/scripts/entrypoint.sh
|
|
|
|
set -euo pipefail
|
|
|
|
SERVER_DIR="${SERVER_DIR:-/home/gtnh}"
|
|
RUN_DIR="${RUN_DIR:-$SERVER_DIR}"
|
|
|
|
SERVER_LOG="$RUN_DIR/server.log"
|
|
SERVER_EXIT_FLAG="${SERVER_EXIT_FLAG:-$RUN_DIR/server.exit}"
|
|
SERVER_READY_FLAG="${SERVER_READY_FLAG:-$RUN_DIR/server.ready}"
|
|
|
|
RCON_HOST="${RCON_HOST:-localhost}"
|
|
RCON_PORT="${RCON_PORT:-25575}"
|
|
RCON_PASSWORD="${RCON_PASSWORD:-whoahaplaintextpassword}"
|
|
|
|
SERVER_JAVA_ARGS="${SERVER_JAVA_ARGS:--Xms1G -Xmx2G -Dfml.readTimeout=5 @java9args.txt -jar lwjgl3ify-forgePatches.jar nogui}"
|
|
|
|
START_TIMEOUT="${SERVER_START_TIMEOUT:-240}"
|
|
SETTLE_DURATION="${SERVER_SETTLE_DURATION:-30}"
|
|
STOP_TIMEOUT="${SERVER_STOP_TIMEOUT:-20}"
|
|
|
|
SERVER_PID=""
|
|
TAIL_PID=""
|
|
|
|
cleanup() {
|
|
[ -n "$TAIL_PID" ] && kill "$TAIL_PID" 2>/dev/null
|
|
# If we still hold the JVM (e.g. an early failure), don't leak it into the runner.
|
|
[ -n "$SERVER_PID" ] && kill -0 "$SERVER_PID" 2>/dev/null && kill "$SERVER_PID" 2>/dev/null
|
|
return 0
|
|
}
|
|
|
|
stop_and_reap() {
|
|
( sleep "$STOP_TIMEOUT"; kill -9 "$SERVER_PID" 2>/dev/null ) &
|
|
local killer=$!
|
|
local code=0
|
|
wait "$SERVER_PID" || code=$?
|
|
kill "$killer" 2>/dev/null
|
|
SERVER_PID=""
|
|
echo "$code" > "$SERVER_EXIT_FLAG"
|
|
echo "server exited with code $code"
|
|
}
|
|
|
|
trap cleanup EXIT INT TERM
|
|
|
|
run() {
|
|
# SERVER_JAVA_ARGS can arrive as a multi-line string. Split it on whitespace
|
|
# into a proper argv array so the launch below stays happy.
|
|
local java_args=()
|
|
local arg
|
|
for arg in $SERVER_JAVA_ARGS; do
|
|
java_args+=("$arg")
|
|
done
|
|
|
|
mkdir -p "$RUN_DIR"
|
|
rm -f "$SERVER_EXIT_FLAG" "$SERVER_READY_FLAG"
|
|
|
|
cd "$SERVER_DIR"
|
|
sed -i 's|eula=false|eula=true|g' eula.txt
|
|
sed -i "s|enable-rcon=false|enable-rcon=true\nrcon.password=${RCON_PASSWORD}\nrcon.port=${RCON_PORT}|" server.properties
|
|
sed -i 's|online-mode=true|online-mode=false|' server.properties
|
|
|
|
# Backgrounded and logged to a file so we can watch startup while the JVM runs.
|
|
java "${java_args[@]}" > "$SERVER_LOG" 2>&1 &
|
|
SERVER_PID=$!
|
|
|
|
tail -n +1 -F "$SERVER_LOG" 2>/dev/null &
|
|
TAIL_PID=$!
|
|
|
|
local waited=0
|
|
while [ "$waited" -lt "$START_TIMEOUT" ]; do
|
|
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
|
|
echo "server exited unexpectedly during startup"
|
|
return
|
|
fi
|
|
if grep -q 'Done.*For help, type' "$SERVER_LOG" 2>/dev/null; then
|
|
echo "server started after ${waited}s"
|
|
: > "$SERVER_READY_FLAG"
|
|
break
|
|
fi
|
|
sleep 5
|
|
waited=$((waited + 5))
|
|
done
|
|
|
|
if [ ! -e "$SERVER_READY_FLAG" ]; then
|
|
echo "server did not become ready within ${START_TIMEOUT}s"
|
|
return
|
|
fi
|
|
|
|
echo "waiting ${SETTLE_DURATION}s for server to settle..."
|
|
sleep "$SETTLE_DURATION"
|
|
|
|
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
|
|
echo "server exited during settling"
|
|
return
|
|
fi
|
|
|
|
echo "stopping server via rcon"
|
|
rcon-cli --host "$RCON_HOST" --port "$RCON_PORT" --password "$RCON_PASSWORD" stop
|
|
|
|
stop_and_reap
|
|
}
|
|
|
|
# Run the lifecycle without aborting on a server-side failure - capturing the
|
|
# exit code is the whole point, so verify_server.sh can judge the run.
|
|
run || true
|
|
|
|
# run bailed early with the JVM still up so stop it too
|
|
if [ -n "$SERVER_PID" ]; then
|
|
kill "$SERVER_PID" 2>/dev/null || true
|
|
stop_and_reap
|
|
fi |