Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Supervisord to manage processes #402

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
09f0359
use supervisord
Luatan Feb 3, 2024
d9bad75
change palserver to service with supervisord
Luatan Feb 10, 2024
8793281
Merge branch 'main' of https://github.com/Luatan/palworld-server-dock…
Luatan Feb 16, 2024
ef7c885
use path for config of supervisord and add listener
Luatan Feb 16, 2024
a916544
remove discord notification and change run command in supervisord config
Luatan Feb 16, 2024
0a9fa3e
remove http_server
Luatan Feb 16, 2024
ecf762b
set dockerfile apt get version from before merge
Luatan Feb 16, 2024
eb95e7f
add processname var to comment
Luatan Feb 16, 2024
d8e313a
Merge branch 'thijsvanloef:main' into palworld-service
Luatan Feb 16, 2024
2b1f178
update supervisord config
Luatan Feb 16, 2024
5713e3c
mv supervisord config to default location
Luatan Feb 16, 2024
dc5f6b4
remove unused cases and use env variables for the message
Luatan Feb 16, 2024
880a4da
start supercronic with supervisord
Luatan Feb 16, 2024
b5f7e64
copy instead of moving conf file
Luatan Feb 17, 2024
4185774
enable loggin to console from handler
Luatan Feb 17, 2024
1430cec
Merge branch 'main' of https://github.com/Luatan/palworld-server-dock…
Luatan Feb 17, 2024
0533e03
use helper method for discord notifications
Luatan Feb 17, 2024
6049682
add gracefull server shutdown
Luatan Feb 17, 2024
96f9c7c
ignore starting event and logerrors to stderr
Luatan Feb 17, 2024
ef3dff8
fixed version for wget
Luatan Feb 18, 2024
8fb3e3d
fix duplicated code
Luatan Feb 18, 2024
6c042d6
Merge branch 'main' of https://github.com/Luatan/palworld-server-dock…
Luatan Feb 19, 2024
e6ed097
rm wget version from dockerfile due to arm
Luatan Feb 19, 2024
947bab8
do not run start in the background
Luatan Feb 19, 2024
583ac59
create methods for getting the arch and Creating the start command
Luatan Feb 19, 2024
1c5258c
removed sed so we can use the server start script directly
Luatan Feb 19, 2024
555a4a8
change the way to get the arch since dpkg can cause permission errors
Luatan Feb 19, 2024
45820ee
run server start in background
Luatan Feb 19, 2024
dda36c7
Merge branch 'main' of https://github.com/Luatan/palworld-server-dock…
Luatan Feb 21, 2024
a985eca
move creation of arm file back to start.sh
Luatan Feb 21, 2024
2baf42f
remove sed comment
Luatan Feb 21, 2024
9e31a4b
add backoff and fatal case
Luatan Feb 22, 2024
f431517
move install check above arm script creation
Luatan Feb 22, 2024
74f16b7
Merge branch 'main' of https://github.com/Luatan/palworld-server-dock…
Luatan Feb 22, 2024
c21e1da
rename startcommand var
Luatan Feb 22, 2024
e9825bd
removed getArchitecutre function and added ARCH to docker ENV
Luatan Feb 22, 2024
57a0fed
remove logs dir
Luatan Feb 22, 2024
5f5abfd
include files from conf.d dir
Luatan Feb 22, 2024
7f8941d
add player logger service dynamicly
Luatan Feb 22, 2024
58cb71e
change dynamic service. Only add to supervisord if valid via filesystem
Luatan Feb 23, 2024
a248271
add function to get Process Status via supervisord
Luatan Feb 23, 2024
4ab65f1
fix player logging service and change supervisord config
Luatan Feb 24, 2024
f332b7c
add function to get service pid from supervisord
Luatan Feb 24, 2024
28a2632
fix player_logging service to not run if rcon is not enabled
Luatan Feb 24, 2024
5d90f55
only wait for server if rcon enabled. If not continue stopping
Luatan Feb 25, 2024
e93d755
change rcon-cli to shutdown_server
Luatan Feb 25, 2024
50e9115
move program to seperate conf files
Luatan Feb 25, 2024
6ba455f
Merge branch 'main' of https://github.com/Luatan/palworld-server-dock…
Luatan Feb 26, 2024
86bb7d7
Merge branch 'main' of https://github.com/Luatan/palworld-server-dock…
Luatan Mar 5, 2024
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
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
xdg-user-dirs=0.18-1 \
jo=1.9-1 \
netcat-traditional=1.10-47 \
supervisor=4.2.5-1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

Expand All @@ -71,6 +72,7 @@ RUN case ${TARGETARCH} in \
&& mv supercronic /usr/local/bin/supercronic

ENV HOME=/home/steam \
ARCH=${TARGETARCH} \
PORT= \
PUID=1000 \
PGID=1000 \
Expand Down Expand Up @@ -115,8 +117,9 @@ ENV HOME=/home/steam \
DISABLE_GENERATE_ENGINE=true

COPY ./scripts /home/steam/server/
COPY ./services /home/steam/server/services/

RUN chmod +x /home/steam/server/*.sh && \
RUN chmod +x /home/steam/server/*.sh /home/steam/server/services/listener/*.sh && \
mv /home/steam/server/backup.sh /usr/local/bin/backup && \
mv /home/steam/server/update.sh /usr/local/bin/update && \
mv /home/steam/server/restore.sh /usr/local/bin/restore
Expand All @@ -133,4 +136,4 @@ HEALTHCHECK --start-period=5m \
CMD pgrep "PalServer-Linux" > /dev/null || exit 1

EXPOSE ${PORT} ${RCON_PORT}
ENTRYPOINT ["/home/steam/server/init.sh"]
ENTRYPOINT [ "/home/steam/server/init.sh" ]
31 changes: 31 additions & 0 deletions scripts/helper_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,37 @@ get_player_count() {
return "$return_val"
}

# Gets the status of a service via supervisorctl
# Returns 0 if successfull
# Returns 1 if the service was not found
getServiceStatus() {
local processName="$1"
local status
status=$(supervisorctl status "$processName" | awk '{print $2}')
if [ -z "$status" ] || [ "$status" = "ERROR" ]; then
return 1
fi
echo "$status"
return 0
}

# Gets the PID of a service via supervisorctl
# Returns 0 if successfull
# Returns 1 if the service was not found or is not running
getServicePID() {
local processName="$1"
local pid
if [ "$(getServiceStatus "$processName")" != "RUNNING" ]; then
return 1
fi
pid=$(supervisorctl status "$processName" | awk '{print $4}' | sed 's/,\+$//')
if [ -z "$pid" ] || [ "$pid" = "ERROR" ]; then
return 1
fi
echo "$pid"
return 0
}

#
# Log Definitions
#
Expand Down
42 changes: 42 additions & 0 deletions scripts/helper_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,45 @@ InstallServer() {
CreateACFFile "$targetManifest"
DiscordMessage "Install" "${DISCORD_POST_UPDATE_BOOT_MESSAGE}" "success"
}

# Builds the start command of the palworld server
# Returns 0 and outputs the start command if everything is ok
# Returns 1 if the Server is not found or has the wrong permissions
BuildStartCommand() {
local command
# Check if the architecture is arm64
if [ "${ARCH}" == "arm64" ]; then
command=("/palworld/PalServer-arm64.sh")
else
command=("/palworld/PalServer.sh")
fi

#Validate Installation
if ! fileExists "${command[0]}"; then
LogError "Server Not Installed Properly"
return 1
fi

isReadable "${command[0]}" || return 1
isExecutable "${command[0]}" || return 1

# Prepare Arguments
if [ -n "${PORT}" ]; then
command+=("-port=${PORT}")
fi

if [ -n "${QUERY_PORT}" ]; then
command+=("-queryport=${QUERY_PORT}")
fi

if [ "${COMMUNITY,,}" = true ]; then
command+=("EpicApp=PalServer")
fi

if [ "${MULTITHREADING,,}" = true ]; then
command+=("-useperfthreads" "-NoAsyncLoadingThread" "-UseMultithreadForDS")
fi

echo "${command[*]}"
return 0
}
39 changes: 4 additions & 35 deletions scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,42 +23,11 @@ if ! [ -w "/palworld" ]; then
fi

mkdir -p /palworld/backups

# shellcheck disable=SC2317
term_handler() {
DiscordMessage "Shutdown" "${DISCORD_PRE_SHUTDOWN_MESSAGE}" "in-progress"

if ! shutdown_server; then
# Does not save
kill -SIGTERM "$(pidof PalServer-Linux-Test)"
fi

tail --pid="$killpid" -f 2>/dev/null
}

trap 'term_handler' SIGTERM

if [[ "$(id -u)" -eq 0 ]]; then
su steam -c ./start.sh &
su steam -c ./start.sh
else
./start.sh &
fi
# Process ID of su
killpid="$!"
wait "$killpid"

mapfile -t backup_pids < <(pgrep backup)
if [ "${#backup_pids[@]}" -ne 0 ]; then
LogInfo "Waiting for backup to finish"
for pid in "${backup_pids[@]}"; do
tail --pid="$pid" -f 2>/dev/null
done
./start.sh
fi

mapfile -t restore_pids < <(pgrep restore)
if [ "${#restore_pids[@]}" -ne 0 ]; then
LogInfo "Waiting for restore to finish"
for pid in "${restore_pids[@]}"; do
tail --pid="$pid" -f 2>/dev/null
done
fi
cp /home/steam/server/services/supervisord.conf /etc/supervisor/supervisord.conf
exec /usr/bin/supervisord --configuration=/etc/supervisor/supervisord.conf
26 changes: 26 additions & 0 deletions scripts/server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
# shellcheck source=scripts/helper_functions.sh
source "/home/steam/server/helper_functions.sh"

# shellcheck source=scripts/helper_install.sh
source "/home/steam/server/helper_install.sh"

graceful_shutdown() {
if [ "${RCON_ENABLED,,}" = true ]; then
shutdown_server
wait "$PID"
fi
exit 0
}

trap 'graceful_shutdown' TERM INT

STARTCOMMAND=$(BuildStartCommand)
if [ "$!" == 1 ]; then
LogWarn "Server Not Installed Properly"
exit 1
fi

${STARTCOMMAND} &
PID=$!
wait "$PID"
57 changes: 21 additions & 36 deletions scripts/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ isExecutable "/palworld" || exit

cd /palworld || exit

# Get the architecture using dpkg
architecture=$(dpkg --print-architecture)

if [ "$architecture" == "arm64" ] && [ "${ARM_COMPATIBILITY_MODE,,}" = true ]; then
if [ "${ARCH}" == "arm64" ] && [ "${ARM_COMPATIBILITY_MODE,,}" = true ]; then
LogInfo "ARM compatibility mode enabled"
export DEBUGGER="/usr/bin/qemu-i386-static"

Expand All @@ -31,18 +28,7 @@ if [ "$ServerInstalled" == 1 ]; then
InstallServer
fi

# Update Only If Already Installed
if [ "$ServerInstalled" == 0 ] && [ "${UPDATE_ON_BOOT,,}" == true ]; then
UpdateRequired
IsUpdateRequired=$?
if [ "$IsUpdateRequired" == 0 ]; then
LogAction "Starting Update"
InstallServer
fi
fi

# Check if the architecture is arm64
if [ "$architecture" == "arm64" ]; then
if [ "${ARCH}" == "arm64" ]; then
# create an arm64 version of ./PalServer.sh
cp ./PalServer.sh ./PalServer-arm64.sh

Expand Down Expand Up @@ -72,6 +58,18 @@ else
fi


# Update Only If Already Installed
if [ "$ServerInstalled" == 0 ] && [ "${UPDATE_ON_BOOT,,}" == true ]; then
UpdateRequired
IsUpdateRequired=$?
if [ "$IsUpdateRequired" == 0 ]; then
LogAction "Starting Update"
InstallServer
fi
fi



#Validate Installation
if ! fileExists "${STARTCOMMAND[0]}"; then
LogError "Server Not Installed Properly"
Expand Down Expand Up @@ -111,7 +109,7 @@ if [ "${DISABLE_GENERATE_SETTINGS,,}" = true ]; then
if [ ! "$(grep -s '[^[:space:]]' /palworld/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini)" ]; then
LogAction "GENERATING CONFIG"
# Server will generate all ini files after first run.
if [ "$architecture" == "arm64" ]; then
if [ "${ARCH}" == "arm64" ]; then
timeout --preserve-status 15s ./PalServer-arm64.sh 1> /dev/null
else
timeout --preserve-status 15s ./PalServer.sh 1> /dev/null
Expand Down Expand Up @@ -153,34 +151,21 @@ if [ "${AUTO_REBOOT_ENABLED,,}" = true ] && [ "${RCON_ENABLED,,}" = true ]; then
supercronic -quiet -test "/home/steam/server/crontab" || exit
fi

if { [ "${AUTO_UPDATE_ENABLED,,}" = true ] && [ "${UPDATE_ON_BOOT,,}" = true ]; } || [ "${BACKUP_ENABLED,,}" = true ] || \
[ "${AUTO_REBOOT_ENABLED,,}" = true ]; then
supercronic "/home/steam/server/crontab" &
LogInfo "Cronjobs started"
else
LogInfo "No Cronjobs found"
fi

# Configure RCON settings
cat >/home/steam/server/rcon.yaml <<EOL
default:
address: "127.0.0.1:${RCON_PORT}"
password: "${ADMIN_PASSWORD}"
EOL

if [ "${ENABLE_PLAYER_LOGGING,,}" = true ] && [[ "${PLAYER_LOGGING_POLL_PERIOD}" =~ ^[0-9]+$ ]] && [ "${RCON_ENABLED,,}" = true ]; then
if [[ "$(id -u)" -eq 0 ]]; then
su steam -c /home/steam/server/player_logging.sh &
if [ "${ENABLE_PLAYER_LOGGING,,}" = true ]; then
if [[ "${PLAYER_LOGGING_POLL_PERIOD}" =~ ^[0-9]+$ ]] && [ "${RCON_ENABLED}" = true ]; then
LogInfo "Player Logging enabled"
mv -f /home/steam/server/services/conf.d/palworld_player_logging.disabled /home/steam/server/services/conf.d/palworld_player_logging.conf
else
/home/steam/server/player_logging.sh &
LogWarn "Unable to enable player logging"
mv -f /home/steam/server/services/conf.d/palworld_player_logging.conf /home/steam/server/services/conf.d/palworld_player_logging.disabled
fi
fi

LogAction "Starting Server"
DiscordMessage "Start" "${DISCORD_PRE_START_MESSAGE}" "success"

echo "${STARTCOMMAND[*]}"
"${STARTCOMMAND[@]}"

DiscordMessage "Stop" "${DISCORD_POST_SHUTDOWN_MESSAGE}" "failure"
exit 0
8 changes: 8 additions & 0 deletions services/conf.d/crontab.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[program:crontab]
user=steam
command=supercronic "/home/steam/server/crontab"
autostart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
stopsignal=INT
22 changes: 22 additions & 0 deletions services/conf.d/palworld.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[eventlistener:palworld-events]
user=steam
command=/home/steam/server/services/listener/palworld_state_handler.sh
priority=1
events=PROCESS_STATE
autostart=true
autorestart=true
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
startsecs=0
buffer_size=50

[program:palworld]
user=steam
command=/home/steam/server/server.sh
autostart=true
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
stopsignal=INT
startsecs=6
stopwaitsecs=30
8 changes: 8 additions & 0 deletions services/conf.d/palworld_player_logging.disabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[program:player_logging]
user=steam
command=/home/steam/server/player_logging.sh
autostart=%(ENV_ENABLE_PLAYER_LOGGING)s
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
startsecs=0
58 changes: 58 additions & 0 deletions services/listener/palworld_state_handler.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash
# shellcheck source=/dev/null
source "/home/steam/server/helper_functions.sh"

# generates variables from header String
# supervisor provides the following variables: ver, server, serial, pool, myeventpool, poolserial, processname, eventname, len
parse_headers() {

IFS=' '
for part in $1; do
key=$(echo "$part" | cut -d':' -f1)
value=$(echo "$part" | cut -d':' -f2)
declare -g "$key=$value"
done
}

declare eventname
declare processname

while true; do
printf "READY\n"
read -r header
parse_headers "$header"

if [ "${processname}" = "palworld" ]; then
case $eventname in
PROCESS_STATE_STARTING)
#Ignore Starting Event
LogAction "*****STARTING SERVER*****" >&2
DiscordMessage "Server is starting" "in-progress" >&2
;;
PROCESS_STATE_RUNNING)
LogAction "*****STARTED SERVER*****" >&2
DiscordMessage "${DISCORD_PRE_START_MESSAGE}" "success" >&2
;;
PROCESS_STATE_STOPPING)
LogAction "*****STOPPING SERVER*****" >&2
DiscordMessage "${DISCORD_PRE_SHUTDOWN_MESSAGE}" "in-progress" >&2
;;
PROCESS_STATE_STOPPED|PROCESS_STATE_EXITED)
LogAction "*****STOPPED SERVER*****" >&2
DiscordMessage "${DISCORD_POST_SHUTDOWN_MESSAGE}" "failure" >&2
;;
PROCESS_STATE_BACKOFF)
LogAction "*****FAILED TO START (RETRY)*****" >&2
;;
PROCESS_STATE_FATAL)
LogAction "*****COULD NOT START SERVER*****" >&2
DiscordMessage "Server was not able to Start. Please check your configuration." "failure" >&2
;;
*)
LogError "Unkown event occured: $header" "failure" >&2
;;
esac
fi
printf "RESULT 2\nOK"
done
exit 0
Loading