From 71a7afab1706301e08faa1c4f9321906d1cecd5c Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Wed, 20 May 2020 15:17:58 +0200 Subject: [PATCH 01/22] Autopause functionality (#531) --- Dockerfile | 21 +++++-- README.md | 34 ++++++++++ files/autopause/autopause-daemon.sh | 97 +++++++++++++++++++++++++++++ files/autopause/autopause-fcns.sh | 38 +++++++++++ files/autopause/knockd-config.cfg | 12 ++++ files/autopause/pause.sh | 19 ++++++ files/autopause/resume.sh | 6 ++ files/sudoers-mc | 2 + health.sh | 11 ++++ start | 8 +++ start-configuration | 59 ++++++++++++++++++ start-finalSetup04ServerProperties | 9 +++ start-utils | 18 ++++-- 13 files changed, 324 insertions(+), 10 deletions(-) create mode 100644 files/autopause/autopause-daemon.sh create mode 100644 files/autopause/autopause-fcns.sh create mode 100644 files/autopause/knockd-config.cfg create mode 100755 files/autopause/pause.sh create mode 100755 files/autopause/resume.sh create mode 100644 files/sudoers-mc create mode 100644 health.sh diff --git a/Dockerfile b/Dockerfile index 6204c854..cee2e0ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,15 +15,17 @@ RUN apk add --no-cache -U \ mysql-client \ tzdata \ rsync \ - nano - -HEALTHCHECK --start-period=1m CMD mc-monitor status --host localhost --port $SERVER_PORT + nano \ + sudo \ + knock RUN addgroup -g 1000 minecraft \ && adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft \ && mkdir -m 777 /data \ && chown minecraft:minecraft /data /home/minecraft +COPY files/sudoers* /etc/sudoers.d + EXPOSE 25565 25575 # hook into docker BuildKit --platform support @@ -63,14 +65,21 @@ COPY server.properties /tmp/server.properties COPY log4j2.xml /tmp/log4j2.xml WORKDIR /data -ENTRYPOINT [ "/start" ] - ENV UID=1000 GID=1000 \ JVM_XX_OPTS="-XX:+UseG1GC" MEMORY="1G" \ TYPE=VANILLA VERSION=LATEST FORGEVERSION=RECOMMENDED SPONGEBRANCH=STABLE SPONGEVERSION= FABRICVERSION=LATEST LEVEL=world \ PVP=true DIFFICULTY=easy ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \ LEVEL_TYPE=DEFAULT SERVER_PORT=25565 ONLINE_MODE=TRUE SERVER_NAME="Dedicated Server" \ - REPLACE_ENV_VARIABLES="FALSE" ENV_VARIABLE_PREFIX="CFG_" + REPLACE_ENV_VARIABLES="FALSE" ENV_VARIABLE_PREFIX="CFG_" \ + ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 AUTOPAUSE_PERIOD=10 COPY start* / +COPY health.sh / +ADD files/autopause /autopause + RUN dos2unix /start* && chmod +x /start* +RUN dos2unix /health.sh && chmod +x /health.sh +RUN dos2unix /autopause/* && chmod +x /autopause/*.sh + +ENTRYPOINT [ "/start" ] +HEALTHCHECK --start-period=1m CMD /health.sh diff --git a/README.md b/README.md index 13e2a4d1..0488795d 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,40 @@ You can also query the container's health in a script friendly way: healthy ``` +## Autopause + +### Description + +> There are various bug reports on [Mojang](https://bugs.mojang.com) about high CPU usage of servers with newer versions, even with few or no clients connected (e.g. [this one](https://bugs.mojang.com/browse/MC-149018), in fact the functionality is based on [this comment in the thread](https://bugs.mojang.com/browse/MC-149018?focusedCommentId=593606&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-593606)). + +An autopause functionality has been added to this image to monitor whether clients are connected to the server. If for a specified time no client is connected, the Java process is stopped. When knocking on the server port (e.g. by the ingame Multiplayer server overview), the process is resumed. The experience for the client does not change. + +Of course, even loaded chunks are not ticked when the process is stopped. + +From the server's point of view, the pausing causes a single tick to take as long as the process is stopped, so the server watchdog might intervene after the process is continued, possibly forcing a container restart. To prevent this, ensure that the `max-tick-time` in the `server.properties` file is set correctly. + +On startup the `server.properties` file is checked and, if applicable, a warning is printed to the terminal. When the server is created (no data available in the persistent directory), the properties file is created with the Watchdog disabled. + +The autopause functionality is not compatible with docker's host network_mode, as the `knockd` utility cannot properly listen for connections in that mode. + +### Enabling Autopause + +Enable the Autopause functionality by setting: + +``` +-e ENABLE_AUTOPAUSE=TRUE +``` + +There are 4 more environment variables that define the behaviour: +* `AUTOPAUSE_TIMEOUT_EST`, default `3600` (seconds) +describes the time between the last client disconnect and the pausing of the process (read as timeout established) +* `AUTOPAUSE_TIMEOUT_INIT`, default `600` (seconds) +describes the time between server start and the pausing of the process, when no client connects inbetween (read as timeout initialized) +* `AUTOPAUSE_TIMEOUT_KN`, default `120` (seconds) +describes the time between knocking of the port (e.g. by the main menu ping) and the pausing of the process, when no client connects inbetween (read as timeout knocked) +* `AUTOPAUSE_PERIOD`, default `10` (seconds) +describes period of the daemonized state machine, that handles the pausing of the process (resuming is done independently) + ## Deployment Templates and Examples ### Helm Charts diff --git a/files/autopause/autopause-daemon.sh b/files/autopause/autopause-daemon.sh new file mode 100644 index 00000000..b4896d43 --- /dev/null +++ b/files/autopause/autopause-daemon.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +exec 1>/tmp/terminal-mc + +. /autopause/autopause-fcns.sh + +sudo /usr/sbin/knockd -c /autopause/knockd-config.cfg -d +if [ $? -ne 0 ] ; then + while : + do + if [[ -n $(ps -o comm | grep java) ]] ; then + break + fi + sleep 0.1 + done + echo "[Autopause loop] Failed to start knockd daemon." + echo "[Autopause loop] Possible cause: docker's host network mode." + echo "[Autopause loop] Recreate without host mode or disable autopause functionality." + echo "[Autopause loop] Stopping server." + killall -SIGTERM java + exit 1 +fi + +STATE=INIT + +while : +do + case X$STATE in + XINIT) + # Server startup + if mc_server_listening ; then + TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_INIT)) + echo "[Autopause loop] MC Server listening for connections - stopping in $AUTOPAUSE_TIMEOUT_INIT seconds" + STATE=K + fi + ;; + XK) + # Knocked + if java_clients_connected ; then + echo "[Autopause loop] Client connected - waiting for disconnect" + STATE=E + else + if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then + echo "[Autopause loop] No client connected since startup / knocked - stopping" + /autopause/pause.sh + STATE=S + fi + fi + ;; + XE) + # Established + if ! java_clients_connected ; then + TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_EST)) + echo "[Autopause loop] All clients disconnected - stopping in $AUTOPAUSE_TIMEOUT_EST seconds" + STATE=I + fi + ;; + XI) + # Idle + if java_clients_connected ; then + echo "[Autopause loop] Client reconnected - waiting for disconnect" + STATE=E + else + if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then + echo "[Autopause loop] No client reconnected - stopping" + /autopause/pause.sh + STATE=S + fi + fi + ;; + XS) + # Stopped + if rcon_client_exists ; then + /autopause/resume.sh + fi + if java_running ; then + if java_clients_connected ; then + echo "[Autopause loop] Client connected - waiting for disconnect" + STATE=E + else + TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_KN)) + echo "[Autopause loop] Server was knocked - waiting for clients or timeout" + STATE=K + fi + fi + ;; + *) + echo "[Autopause loop] Error: invalid state: $STATE" + ;; + esac + if [[ "$STATE" == "S" ]] ; then + # before rcon times out + sleep 2 + else + sleep $AUTOPAUSE_PERIOD + fi +done diff --git a/files/autopause/autopause-fcns.sh b/files/autopause/autopause-fcns.sh new file mode 100644 index 00000000..aea37a6f --- /dev/null +++ b/files/autopause/autopause-fcns.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +current_uptime() { + echo $(awk '{print $1}' /proc/uptime | cut -d . -f 1) +} + +java_running() { + [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] +} + +rcon_client_exists() { + [[ -n "$(ps -a -o comm | grep 'rcon-cli')" ]] +} + +mc_server_listening() { + [[ -n $(netstat -tln | grep "0.0.0.0:$SERVER_PORT" | grep LISTEN) ]] +} + +java_clients_connected() { + local connections + connections=$(netstat -tn | grep ":$SERVER_PORT" | grep ESTABLISHED) + if [[ -z "$connections" ]] ; then + return 1 + fi + IFS=$'\n' + connections=($connections) + unset IFS + # check that at least one external address is not localhost + # remember, that the host network mode does not work with autopause because of the knockd utility + for (( i=0; i<${#connections[@]}; i++ )) + do + if [[ ! $(echo "${connections[$i]}" | awk '{print $5}') =~ ^\s*127\.0\.0\.1:.*$ ]] ; then + # not localhost + return 0 + fi + done + return 1 +} diff --git a/files/autopause/knockd-config.cfg b/files/autopause/knockd-config.cfg new file mode 100644 index 00000000..86c98d02 --- /dev/null +++ b/files/autopause/knockd-config.cfg @@ -0,0 +1,12 @@ +[options] + logfile = /dev/null +[unpauseMCServer-server] + sequence = 25565 + seq_timeout = 1 + command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh + tcpflags = syn +[unpauseMCServer-rcon] + sequence = 25575 + seq_timeout = 1 + command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh + tcpflags = syn diff --git a/files/autopause/pause.sh b/files/autopause/pause.sh new file mode 100755 index 00000000..3acc5bd6 --- /dev/null +++ b/files/autopause/pause.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then + # save world + rcon-cli save-all >/dev/null + + # wait until mc-monitor is no longer connected to the server + while : + do + if [[ -z "$(netstat -nt | grep "127.0.0.1:$SERVER_PORT" | grep 'ESTABLISHED')" ]]; then + break + fi + sleep 0.1 + done + + # finally pause the process + echo "[$(date -Iseconds)] [Autopause] Pausing Java process" >/tmp/terminal-mc + killall -q -STOP java +fi diff --git a/files/autopause/resume.sh b/files/autopause/resume.sh new file mode 100755 index 00000000..dcf0a1dd --- /dev/null +++ b/files/autopause/resume.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then + echo "[$(date -Iseconds)] [Autopause] Knocked, resuming Java process" >/tmp/terminal-mc + killall -q -CONT java +fi diff --git a/files/sudoers-mc b/files/sudoers-mc new file mode 100644 index 00000000..419c352e --- /dev/null +++ b/files/sudoers-mc @@ -0,0 +1,2 @@ +%minecraft ALL=(ALL) NOPASSWD:/usr/bin/killall +%minecraft ALL=(ALL) NOPASSWD:/usr/sbin/knockd diff --git a/health.sh b/health.sh new file mode 100644 index 00000000..eab0f5c0 --- /dev/null +++ b/health.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +. /start-utils + +if isTrue "${ENABLE_AUTOPAUSE}" && [[ "$( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }')" =~ ^T.*$ ]]; then + echo "Java process suspended by Autopause function" + exit 0 +else + mc-monitor status --host localhost --port $SERVER_PORT + exit $? +fi diff --git a/start b/start index 3a919292..37c422c2 100644 --- a/start +++ b/start @@ -36,6 +36,14 @@ if [ $(id -u) = 0 ]; then chown -R ${runAsUser}:${runAsGroup} /data fi + if [[ $(stat -c "%u" /autopause) != $UID ]]; then + log "Changing ownership of /autopause to $UID ..." + chown -R ${runAsUser}:${runAsGroup} /autopause + fi + + ln -fs $(tty) /tmp/terminal-mc + chmod 777 /tmp/terminal-mc + if [[ ${SKIP_NSSWITCH_CONF^^} != TRUE ]]; then echo 'hosts: files dns' > /etc/nsswitch.conf fi diff --git a/start-configuration b/start-configuration index 0d6290c9..842a87b7 100644 --- a/start-configuration +++ b/start-configuration @@ -68,6 +68,65 @@ cd /data || exit 1 export ORIGINAL_TYPE=${TYPE^^} +if isTrue "${ENABLE_AUTOPAUSE}"; then + log "Autopause functionality enabled" + + # update server port to listen to + regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$" + linenum=$(grep -nm1 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1) + if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then + sed -i "${linenum}s/sequence.*/sequence = $SERVER_PORT/" /autopause/knockd-config.cfg + log "Updated server port in knockd config" + fi + # update rcon port to listen to + regseq="^\s*sequence\s*=\s*$RCON_PORT\s*$" + linenum=$(grep -nm2 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1) + if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then + sed -i "${linenum}s/sequence.*/sequence = $RCON_PORT/" /autopause/knockd-config.cfg + log "Updated rcon port in knockd config" + fi + + if ! [[ $AUTOPAUSE_PERIOD =~ ^[0-9]+$ ]]; then + AUTOPAUSE_PERIOD=10 + export AUTOPAUSE_PERIOD + log "Warning: AUTOPAUSE_PERIOD is not numeric, set to 10 (seconds)" + fi + if [ "$AUTOPAUSE_PERIOD" -eq "0" ] ; then + AUTOPAUSE_PERIOD=10 + export AUTOPAUSE_PERIOD + log "Warning: AUTOPAUSE_PERIOD must not be 0, set to 10 (seconds)" + fi + if ! [[ $AUTOPAUSE_TIMEOUT_KN =~ ^[0-9]+$ ]] ; then + AUTOPAUSE_TIMEOUT_KN=120 + export AUTOPAUSE_TIMEOUT_KN + log "Warning: AUTOPAUSE_TIMEOUT_KN is not numeric, set to 120 (seconds)" + fi + if ! [[ $AUTOPAUSE_TIMEOUT_EST =~ ^[0-9]+$ ]] ; then + AUTOPAUSE_TIMEOUT_EST=3600 + export AUTOPAUSE_TIMEOUT_EST + log "Warning: AUTOPAUSE_TIMEOUT_EST is not numeric, set to 3600 (seconds)" + fi + if ! [[ $AUTOPAUSE_TIMEOUT_INIT =~ ^[0-9]+$ ]] ; then + AUTOPAUSE_TIMEOUT_INIT=600 + export AUTOPAUSE_TIMEOUT_INIT + log "Warning: AUTOPAUSE_TIMEOUT_INIT is not numeric, set to 600 (seconds)" + fi + + if [[ -n $MAX_TICK_TIME ]] ; then + log "Warning: MAX_TICK_TIME is non-default, for autopause to work properly, this check should be disabled (-1 for versions >= 1.8.1)" + else + if versionLessThan 1.8.1; then + # 10 years + MAX_TICK_TIME=315360000000 + else + MAX_TICK_TIME=-1 + fi + export MAX_TICK_TIME + fi + + /autopause/autopause-daemon.sh & +fi + log "Resolving type given ${TYPE}" case "${TYPE^^}" in *BUKKIT|SPIGOT) diff --git a/start-finalSetup04ServerProperties b/start-finalSetup04ServerProperties index bdc02108..ea92f88e 100644 --- a/start-finalSetup04ServerProperties +++ b/start-finalSetup04ServerProperties @@ -180,4 +180,13 @@ else log "server.properties already created, skipping" fi +if isTrue "${ENABLE_AUTOPAUSE}"; then + current_max_tick=$( grep 'max-tick-time' "$SERVER_PROPERTIES" | sed -r 's/( )+//g' | awk -F= '{print $2}' ) + if (( $current_max_tick > 0 && $current_max_tick < 86400000 )); then + log "Warning: The server.properties for the server doesn't have the Server Watchdog (effectively) disabled." + log "Warning (cont): Autopause functionality resuming the process might trigger the Watchdog and restart the server completely." + log "Warning (cont): Set the max-tick-time property to a high value (or disable the Watchdog with value -1 for versions 1.8.1+)." + fi +fi + exec /start-finalSetup05EnvVariables $@ diff --git a/start-utils b/start-utils index 9641256e..03b4c562 100644 --- a/start-utils +++ b/start-utils @@ -75,10 +75,20 @@ function versionLessThan { return 1 fi - if (( activeParts[0] < givenParts[0] )) || \ - (( activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1] )); then - return 0 + if (( ${#activeParts[@]} == 2 )); then + if (( activeParts[0] < givenParts[0] )) || \ + (( activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1] )); then + return 0 + else + return 1 + fi else - return 1 + if (( activeParts[0] < givenParts[0] )) || \ + (( activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1] )) || \ + (( activeParts[0] == givenParts[0] && activeParts[1] == givenParts[1] && activeParts[2] < givenParts[2] )); then + return 0 + else + return 1 + fi fi } \ No newline at end of file From b11806e34107723c74e67f963cdd9f3c038fa6cd Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Thu, 21 May 2020 20:59:13 -0500 Subject: [PATCH 02/22] Consolidated armv7 branch into multiarch --- docker-versions-create.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-versions-create.sh b/docker-versions-create.sh index 36486ba3..557c9689 100755 --- a/docker-versions-create.sh +++ b/docker-versions-create.sh @@ -1,7 +1,7 @@ #!/bin/bash #set -x # Use this variable to indicate a list of branches that docker hub is watching -branches_list=('openj9' 'openj9-nightly' 'adopt11' 'adopt13' 'multiarch' 'armv7') +branches_list=('openj9' 'openj9-nightly' 'adopt11' 'adopt13' 'multiarch') function TrapExit { echo "Checking out back in master" From f2806d93352520c1c3626180bb3ca15bcbe88d6c Mon Sep 17 00:00:00 2001 From: Michael Kirsch Date: Sat, 23 May 2020 16:15:10 +0200 Subject: [PATCH 03/22] Autopause logs (#539) --- files/autopause/autopause-daemon.sh | 30 ++++++++++++++--------------- files/autopause/pause.sh | 4 +++- files/autopause/resume.sh | 4 +++- start | 3 --- start-utils | 8 ++++++++ 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/files/autopause/autopause-daemon.sh b/files/autopause/autopause-daemon.sh index b4896d43..3150740c 100644 --- a/files/autopause/autopause-daemon.sh +++ b/files/autopause/autopause-daemon.sh @@ -1,9 +1,9 @@ #!/bin/bash -exec 1>/tmp/terminal-mc - . /autopause/autopause-fcns.sh +. /start-utils + sudo /usr/sbin/knockd -c /autopause/knockd-config.cfg -d if [ $? -ne 0 ] ; then while : @@ -13,10 +13,10 @@ if [ $? -ne 0 ] ; then fi sleep 0.1 done - echo "[Autopause loop] Failed to start knockd daemon." - echo "[Autopause loop] Possible cause: docker's host network mode." - echo "[Autopause loop] Recreate without host mode or disable autopause functionality." - echo "[Autopause loop] Stopping server." + logAutopause "Failed to start knockd daemon." + logAutopause "Possible cause: docker's host network mode." + logAutopause "Recreate without host mode or disable autopause functionality." + logAutopause "Stopping server." killall -SIGTERM java exit 1 fi @@ -30,18 +30,18 @@ do # Server startup if mc_server_listening ; then TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_INIT)) - echo "[Autopause loop] MC Server listening for connections - stopping in $AUTOPAUSE_TIMEOUT_INIT seconds" + logAutopause "MC Server listening for connections - stopping in $AUTOPAUSE_TIMEOUT_INIT seconds" STATE=K fi ;; XK) # Knocked if java_clients_connected ; then - echo "[Autopause loop] Client connected - waiting for disconnect" + logAutopause "Client connected - waiting for disconnect" STATE=E else if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then - echo "[Autopause loop] No client connected since startup / knocked - stopping" + logAutopause "No client connected since startup / knocked - stopping" /autopause/pause.sh STATE=S fi @@ -51,18 +51,18 @@ do # Established if ! java_clients_connected ; then TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_EST)) - echo "[Autopause loop] All clients disconnected - stopping in $AUTOPAUSE_TIMEOUT_EST seconds" + logAutopause "All clients disconnected - stopping in $AUTOPAUSE_TIMEOUT_EST seconds" STATE=I fi ;; XI) # Idle if java_clients_connected ; then - echo "[Autopause loop] Client reconnected - waiting for disconnect" + logAutopause "Client reconnected - waiting for disconnect" STATE=E else if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then - echo "[Autopause loop] No client reconnected - stopping" + logAutopause "No client reconnected - stopping" /autopause/pause.sh STATE=S fi @@ -75,17 +75,17 @@ do fi if java_running ; then if java_clients_connected ; then - echo "[Autopause loop] Client connected - waiting for disconnect" + logAutopause "Client connected - waiting for disconnect" STATE=E else TIME_THRESH=$(($(current_uptime)+$AUTOPAUSE_TIMEOUT_KN)) - echo "[Autopause loop] Server was knocked - waiting for clients or timeout" + logAutopause "Server was knocked - waiting for clients or timeout" STATE=K fi fi ;; *) - echo "[Autopause loop] Error: invalid state: $STATE" + logAutopause "Error: invalid state: $STATE" ;; esac if [[ "$STATE" == "S" ]] ; then diff --git a/files/autopause/pause.sh b/files/autopause/pause.sh index 3acc5bd6..c84bdda5 100755 --- a/files/autopause/pause.sh +++ b/files/autopause/pause.sh @@ -1,5 +1,7 @@ #!/bin/bash +. /start-utils + if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then # save world rcon-cli save-all >/dev/null @@ -14,6 +16,6 @@ if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; th done # finally pause the process - echo "[$(date -Iseconds)] [Autopause] Pausing Java process" >/tmp/terminal-mc + logAutopauseAction "Pausing Java process" killall -q -STOP java fi diff --git a/files/autopause/resume.sh b/files/autopause/resume.sh index dcf0a1dd..73ab648e 100755 --- a/files/autopause/resume.sh +++ b/files/autopause/resume.sh @@ -1,6 +1,8 @@ #!/bin/bash +. /start-utils + if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then - echo "[$(date -Iseconds)] [Autopause] Knocked, resuming Java process" >/tmp/terminal-mc + logAutopauseAction "Knocked, resuming Java process" killall -q -CONT java fi diff --git a/start b/start index 37c422c2..c50aef4f 100644 --- a/start +++ b/start @@ -41,9 +41,6 @@ if [ $(id -u) = 0 ]; then chown -R ${runAsUser}:${runAsGroup} /autopause fi - ln -fs $(tty) /tmp/terminal-mc - chmod 777 /tmp/terminal-mc - if [[ ${SKIP_NSSWITCH_CONF^^} != TRUE ]]; then echo 'hosts: files dns' > /etc/nsswitch.conf fi diff --git a/start-utils b/start-utils index 03b4c562..e054396a 100644 --- a/start-utils +++ b/start-utils @@ -49,6 +49,14 @@ function log { echo "[init] $*" } +function logAutopause { + echo "[Autopause loop] $*" +} + +function logAutopauseAction { + echo "[$(date -Iseconds)] [Autopause] $*" +} + function normalizeMemSize { local scale=1 case ${1,,} in From ccac249c01646c0579718fdfecdf01d281201e26 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sat, 23 May 2020 09:55:38 -0500 Subject: [PATCH 04/22] Added server-start.sh support for CF modpacks Fixes #540 --- start-deployFTB | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/start-deployFTB b/start-deployFTB index dfdab6fe..2a3c12b5 100644 --- a/start-deployFTB +++ b/start-deployFTB @@ -16,7 +16,12 @@ if [[ -z $FTB_SERVER_MOD ]]; then exit 2 fi -entryScriptExpr="-name ServerStart.sh -o -name ServerStartLinux.sh -o -name LaunchServer.sh" +entryScriptExpr=" + -name ServerStart.sh + -o -name ServerStartLinux.sh + -o -name LaunchServer.sh + -o -name server-start.sh + " if [[ -d ${FTB_BASE_DIR} ]]; then startScriptCount=$(find ${FTB_BASE_DIR} $entryScriptExpr |wc -l) From 825398f4d48bb96653ef128f833fa5d2f90e6a6b Mon Sep 17 00:00:00 2001 From: Kevin Klinemeier Date: Sat, 23 May 2020 15:57:11 -0700 Subject: [PATCH 05/22] removed version entries except for the version section (#541) Co-authored-by: BuildTools --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 0488795d..c90c8295 100644 --- a/README.md +++ b/README.md @@ -230,7 +230,7 @@ Enable Forge server mode by adding a `-e TYPE=FORGE` to your command-line. By default the container will run the `RECOMMENDED` version of [Forge server](http://www.minecraftforge.net/wiki/) but you can also choose to run a specific version with `-e FORGEVERSION=10.13.4.1448`. - $ docker run -d -v /path/on/host:/data -e VERSION=1.7.10 \ + $ docker run -d -v /path/on/host:/data \ -e TYPE=FORGE -e FORGEVERSION=10.13.4.1448 \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server @@ -384,10 +384,10 @@ The content of `db_password`: ## Running a Bukkit/Spigot server -Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT -e VERSION=1.8` or `-e TYPE=SPIGOT -e VERSION=1.8` to your command-line. +Enable Bukkit/Spigot server mode by adding a `-e TYPE=BUKKIT` or `-e TYPE=SPIGOT` to your command-line. docker run -d -v /path/on/host:/data \ - -e TYPE=SPIGOT -e VERSION=1.8 \ + -e TYPE=SPIGOT \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server If you are hosting your own copy of Bukkit/Spigot you can override the download URLs with: @@ -401,7 +401,7 @@ You can build spigot from source by adding `-e BUILD_FROM_SOURCE=true` pass `--noconsole` at the very end of the command line and not use `-it`. For example, docker run -d -v /path/on/host:/data \ - -e TYPE=SPIGOT -e VERSION=1.8 \ + -e TYPE=SPIGOT \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server --noconsole You can install Bukkit plugins in two ways... @@ -446,20 +446,20 @@ in either persistent volumes or a downloadable archive. ## Running a PaperSpigot server -Enable PaperSpigot server mode by adding a `-e TYPE=PAPER -e VERSION=1.9.4` to your command-line. +Enable PaperSpigot server mode by adding a `-e TYPE=PAPER` to your command-line. By default the container will run the latest build of [Paper server](https://papermc.io/downloads) but you can also choose to run a specific build with `-e PAPERBUILD=205`. docker run -d -v /path/on/host:/data \ - -e TYPE=PAPER -e VERSION=1.9.4 \ + -e TYPE=PAPER \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server **NOTE: to avoid pegging the CPU when running PaperSpigot,** you will need to pass `--noconsole` at the very end of the command line and not use `-it`. For example, docker run -d -v /path/on/host:/data \ - -e TYPE=PAPER -e VERSION=1.9.4 \ + -e TYPE=PAPER \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server --noconsole If you are hosting your own copy of PaperSpigot you can override the download URL with: @@ -585,7 +585,6 @@ $ docker run -itd --name derpcraft \ -e MANIFEST=/data/FeedTheBeast/manifest.json \ -v $PWD/ServerStart.sh:/data/FeedTheBeast/ServerStart.sh \ -v $PWD/settings.cfg:/data/FeedTheBeast/settings.cfg \ - -e VERSION=1.12.2\ -e TYPE=CURSEFORGE\ -e CF_SERVER_MOD=https://minecraft.curseforge.com/projects/your_amazing_modpack/files/2670435/download\ -p 25565:25565\ @@ -617,7 +616,7 @@ Enable Fabric server mode by adding a `-e TYPE=FABRIC` to your command-line. By default the container will run the latest version of [Fabric server](http://fabricmc.net/use/) but you can also choose to run a specific version with `-e FABRICVERSION=0.5.0.32`. - $ docker run -d -v /path/on/host:/data -e VERSION=1.14.3 \ + $ docker run -d -v /path/on/host:/data \ -e TYPE=FABRIC -e FABRICVERSION=0.5.0.32 \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server @@ -696,7 +695,7 @@ For example, with PaperSpigot, it would look something like this: ``` docker run -d -v /path/on/host:/data \ - -e TYPE=PAPER -e VERSION=1.14.1 -e FORCE_REDOWNLOAD=true \ + -e TYPE=PAPER -e FORCE_REDOWNLOAD=true \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server ``` From 5aa6e5c2a903fe912e69f9f3fe75194423dc8e2a Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Mon, 25 May 2020 10:20:14 -0500 Subject: [PATCH 06/22] Refactored autopause setup into its own start-file (#545) --- start-autopause | 60 +++++++++++++++++++++++++++++++++++++++++++++ start-configuration | 57 +----------------------------------------- 2 files changed, 61 insertions(+), 56 deletions(-) create mode 100755 start-autopause diff --git a/start-autopause b/start-autopause new file mode 100755 index 00000000..d73f8302 --- /dev/null +++ b/start-autopause @@ -0,0 +1,60 @@ +#!/bin/bash + +. /start-utils + +log "Autopause functionality enabled" + +# update server port to listen to +regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$" +linenum=$(grep -nm1 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1) +if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then + sed -i "${linenum}s/sequence.*/sequence = $SERVER_PORT/" /autopause/knockd-config.cfg + log "Updated server port in knockd config" +fi +# update rcon port to listen to +regseq="^\s*sequence\s*=\s*$RCON_PORT\s*$" +linenum=$(grep -nm2 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1) +if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then + sed -i "${linenum}s/sequence.*/sequence = $RCON_PORT/" /autopause/knockd-config.cfg + log "Updated rcon port in knockd config" +fi + +if ! [[ $AUTOPAUSE_PERIOD =~ ^[0-9]+$ ]]; then + AUTOPAUSE_PERIOD=10 + export AUTOPAUSE_PERIOD + log "Warning: AUTOPAUSE_PERIOD is not numeric, set to 10 (seconds)" +fi +if [ "$AUTOPAUSE_PERIOD" -eq "0" ] ; then + AUTOPAUSE_PERIOD=10 + export AUTOPAUSE_PERIOD + log "Warning: AUTOPAUSE_PERIOD must not be 0, set to 10 (seconds)" +fi +if ! [[ $AUTOPAUSE_TIMEOUT_KN =~ ^[0-9]+$ ]] ; then + AUTOPAUSE_TIMEOUT_KN=120 + export AUTOPAUSE_TIMEOUT_KN + log "Warning: AUTOPAUSE_TIMEOUT_KN is not numeric, set to 120 (seconds)" +fi +if ! [[ $AUTOPAUSE_TIMEOUT_EST =~ ^[0-9]+$ ]] ; then + AUTOPAUSE_TIMEOUT_EST=3600 + export AUTOPAUSE_TIMEOUT_EST + log "Warning: AUTOPAUSE_TIMEOUT_EST is not numeric, set to 3600 (seconds)" +fi +if ! [[ $AUTOPAUSE_TIMEOUT_INIT =~ ^[0-9]+$ ]] ; then + AUTOPAUSE_TIMEOUT_INIT=600 + export AUTOPAUSE_TIMEOUT_INIT + log "Warning: AUTOPAUSE_TIMEOUT_INIT is not numeric, set to 600 (seconds)" +fi + +if [[ -n $MAX_TICK_TIME ]] ; then + log "Warning: MAX_TICK_TIME is non-default, for autopause to work properly, this check should be disabled (-1 for versions >= 1.8.1)" +else + if versionLessThan 1.8.1; then + # 10 years + MAX_TICK_TIME=315360000000 + else + MAX_TICK_TIME=-1 + fi + export MAX_TICK_TIME +fi + +/autopause/autopause-daemon.sh & diff --git a/start-configuration b/start-configuration index 842a87b7..55a157ea 100644 --- a/start-configuration +++ b/start-configuration @@ -69,62 +69,7 @@ cd /data || exit 1 export ORIGINAL_TYPE=${TYPE^^} if isTrue "${ENABLE_AUTOPAUSE}"; then - log "Autopause functionality enabled" - - # update server port to listen to - regseq="^\s*sequence\s*=\s*$SERVER_PORT\s*$" - linenum=$(grep -nm1 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1) - if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then - sed -i "${linenum}s/sequence.*/sequence = $SERVER_PORT/" /autopause/knockd-config.cfg - log "Updated server port in knockd config" - fi - # update rcon port to listen to - regseq="^\s*sequence\s*=\s*$RCON_PORT\s*$" - linenum=$(grep -nm2 sequence /autopause/knockd-config.cfg | cut -d : -f 1 | tail -n1) - if ! [[ $(awk "NR==$linenum" /autopause/knockd-config.cfg) =~ $regseq ]]; then - sed -i "${linenum}s/sequence.*/sequence = $RCON_PORT/" /autopause/knockd-config.cfg - log "Updated rcon port in knockd config" - fi - - if ! [[ $AUTOPAUSE_PERIOD =~ ^[0-9]+$ ]]; then - AUTOPAUSE_PERIOD=10 - export AUTOPAUSE_PERIOD - log "Warning: AUTOPAUSE_PERIOD is not numeric, set to 10 (seconds)" - fi - if [ "$AUTOPAUSE_PERIOD" -eq "0" ] ; then - AUTOPAUSE_PERIOD=10 - export AUTOPAUSE_PERIOD - log "Warning: AUTOPAUSE_PERIOD must not be 0, set to 10 (seconds)" - fi - if ! [[ $AUTOPAUSE_TIMEOUT_KN =~ ^[0-9]+$ ]] ; then - AUTOPAUSE_TIMEOUT_KN=120 - export AUTOPAUSE_TIMEOUT_KN - log "Warning: AUTOPAUSE_TIMEOUT_KN is not numeric, set to 120 (seconds)" - fi - if ! [[ $AUTOPAUSE_TIMEOUT_EST =~ ^[0-9]+$ ]] ; then - AUTOPAUSE_TIMEOUT_EST=3600 - export AUTOPAUSE_TIMEOUT_EST - log "Warning: AUTOPAUSE_TIMEOUT_EST is not numeric, set to 3600 (seconds)" - fi - if ! [[ $AUTOPAUSE_TIMEOUT_INIT =~ ^[0-9]+$ ]] ; then - AUTOPAUSE_TIMEOUT_INIT=600 - export AUTOPAUSE_TIMEOUT_INIT - log "Warning: AUTOPAUSE_TIMEOUT_INIT is not numeric, set to 600 (seconds)" - fi - - if [[ -n $MAX_TICK_TIME ]] ; then - log "Warning: MAX_TICK_TIME is non-default, for autopause to work properly, this check should be disabled (-1 for versions >= 1.8.1)" - else - if versionLessThan 1.8.1; then - # 10 years - MAX_TICK_TIME=315360000000 - else - MAX_TICK_TIME=-1 - fi - export MAX_TICK_TIME - fi - - /autopause/autopause-daemon.sh & + /start-autopause fi log "Resolving type given ${TYPE}" From 11989d17e338618142964f67e351adf6b3370be8 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sun, 31 May 2020 18:34:21 -0500 Subject: [PATCH 07/22] Updated README for FTBA server type support For #524 --- README.md | 83 +++++++++++++++++++++++++------------------------------ 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index c90c8295..de89422a 100644 --- a/README.md +++ b/README.md @@ -525,20 +525,46 @@ A [Magma](https://magmafoundation.org/) server, which is a combination of Forge > **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2" -## Running a Server with a Feed-The-Beast (FTB) / CurseForge modpack +## Running a server with a Feed the Beast modpack -Enable this server mode by adding a `-e TYPE=FTB` or `-e TYPE=CURSEFORGE` to your command-line, +> **NOTE** requires `itzg/minecraft-server:multiarch` image + +[Feed the Beast application](https://www.feed-the-beast.com/) modpacks are supported by using `-e TYPE=FTBA` (**note** the "A" at the end of the type). This server type will automatically take care of downloading and installing the modpack and appropriate version of Forge, so the `VERSION` does not need to be specified. + +### Environment Variables: +- `FTB_MODPACK_ID`: **required**, the numerical ID of the modpack to install. The ID can be located by finding the modpack at [Neptune FTB](https://ftb.neptunepowered.org/) and using the "Pack ID" +- `FTB_MODPACK_VERSION_ID`: optional, the numerical Id of the version to install. If not specified, the latest version will be installed. The "Version ID" can be obtained by drilling into the Versions tab and clicking a specific version. + +### Upgrading + +If a specific `FTB_MODPACK_VERSION_ID` was not specified, simply restart the container to pick up the newest modpack version. If using a specific version ID, recreate the container with the new version ID. + +### Example + +The following example runs the latest version of [FTB Presents Direwolf20 1.12](https://ftb.neptunepowered.org/pack/ftb-presents-direwolf20-1-12/): + +``` +docker run -d --name mc-ftb -e EULA=TRUE \ + -e TYPE=FTBA -e FTB_MODPACK_ID=31 \ + -p 25565:25565 \ + itzg/minecraft-server:multiarch +``` + +> Normally you will also add `-v` volume for `/data` since the mods and config are installed there along with world data. + +## Running a server with a CurseForge modpack + +Enable this server mode by adding `-e TYPE=CURSEFORGE` to your command-line, but note the following additional steps needed... -You need to specify a modpack to run, using the `FTB_SERVER_MOD` or `CF_SERVER_MOD` environment -variable. An FTB/CurseForge server modpack is available together with its respective -client modpack on under "Additional Files." Similar you can -locate the modpacks for CurseForge at . +You need to specify a modpack to run, using the `CF_SERVER_MOD` environment +variable. A CurseForge server modpack is available together with its respective +client modpack at . -Now you can add a `-e FTB_SERVER_MOD=name_of_modpack.zip` to your command-line. +Now you can add a `-e CF_SERVER_MOD=name_of_modpack.zip` to your command-line. - docker run -d -v /path/on/host:/data -e TYPE=FTB \ - -e FTB_SERVER_MOD=FTBPresentsSkyfactory3Server_3.0.6.zip \ + docker run -d -v /path/on/host:/data -e TYPE=CURSEFORGE \ + -e CF_SERVER_MOD=SkyFactory_4_Server_4.1.0.zip \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server If you want to keep the pre-download modpacks separate from your data directory, @@ -546,8 +572,8 @@ then you can attach another volume at a path of your choosing and reference that The following example uses `/modpacks` as the container path as the pre-download area: docker run -d -v /path/on/host:/data -v /path/to/modpacks:/modpacks \ - -e TYPE=FTB \ - -e FTB_SERVER_MOD=/modpacks/FTBPresentsSkyfactory3Server_3.0.6.zip \ + -e TYPE=CURSEFORGE \ + -e CF_SERVER_MOD=/modpacks/SkyFactory_4_Server_4.1.0.zip \ -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server ### Fixing "unable to launch forgemodloader" @@ -560,41 +586,6 @@ then you apply a workaround by adding this to the run invocation: -e FTB_LEGACYJAVAFIXER=true -### Using a client-made curseforge modpack - -If you use something like CurseForge, you may end up creating/using modpacks that do not -contain server mod jars. Instead, the CurseForge setup has `manifest.json` files, which -will show up under `/data/FeedTheBeast/manifest.json`. - -To use these packs you will need to: - -- Specify the manifest location with env var `MANIFEST=/data/FeedTheBeast/manifest` -- Pick a relevant ServerStart.sh and potentially settings.cfg and put them in `/data/FeedTheBeast` - -An example of the latter would be to use -There, you'll find that all you have to do is put `ServerStart.sh` and `settings.cfg` into -`/data/FeedTheBeast`, taking care to update `settings.cfg` to specify your desired version -of minecraft and forge. You can do this in the cli with something like: - -``` -$ wget https://raw.githubusercontent.com/AllTheMods/Server-Scripts/master/ServerStart.sh -$ wget https://raw.githubusercontent.com/AllTheMods/Server-Scripts/master/settings.cfg -$ vim settings.cfg #update the forge version to the one you want. Your manifest.json will have it -$ chmod +x ServerStart.sh -$ docker run -itd --name derpcraft \ - -e MANIFEST=/data/FeedTheBeast/manifest.json \ - -v $PWD/ServerStart.sh:/data/FeedTheBeast/ServerStart.sh \ - -v $PWD/settings.cfg:/data/FeedTheBeast/settings.cfg \ - -e TYPE=CURSEFORGE\ - -e CF_SERVER_MOD=https://minecraft.curseforge.com/projects/your_amazing_modpack/files/2670435/download\ - -p 25565:25565\ - -e EULA=TRUE\ - --restart=always\ - itzg/minecraft-server -``` - -Note the `CF_SERVER_MOD` env var should match the server version of the modpack you are targeting. - ## Running a SpongeVanilla server Enable SpongeVanilla server mode by adding a `-e TYPE=SPONGEVANILLA` to your command-line. From 6da2aca97569757d93c4b4aa3b53b53aa483b538 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sun, 31 May 2020 18:39:53 -0500 Subject: [PATCH 08/22] Updated examples for FTBA support --- examples/docker-compose-curseforge.yml | 6 ++++-- examples/docker-compose-forge.yml | 14 +++++++------- examples/docker-compose-ftb.yml | 16 ---------------- examples/docker-compose-ftba.yml | 23 +++++++++++++++++++++++ examples/modpacks/.gitignore | 1 + examples/modpacks/README.md | 3 +++ 6 files changed, 38 insertions(+), 25 deletions(-) delete mode 100644 examples/docker-compose-ftb.yml create mode 100644 examples/docker-compose-ftba.yml create mode 100644 examples/modpacks/.gitignore create mode 100644 examples/modpacks/README.md diff --git a/examples/docker-compose-curseforge.yml b/examples/docker-compose-curseforge.yml index 8bdc844e..fbdd8c89 100644 --- a/examples/docker-compose-curseforge.yml +++ b/examples/docker-compose-curseforge.yml @@ -3,9 +3,11 @@ version: '3.2' services: mc: image: itzg/minecraft-server + volumes: + - ./modpacks:/modpacks:ro environment: EULA: "true" - TYPE: FTB - FTB_SERVER_MOD: https://minecraft.curseforge.com/projects/all-the-mods-expert-remastered/files/2493900/download + TYPE: CURSEFORGE + CF_SERVER_MOD: /modpacks/SkyFactory_4_Server_4.1.0.zip ports: - 25565:25565 diff --git a/examples/docker-compose-forge.yml b/examples/docker-compose-forge.yml index 4c9f6c86..756d7d5b 100644 --- a/examples/docker-compose-forge.yml +++ b/examples/docker-compose-forge.yml @@ -2,7 +2,8 @@ version: "3.7" services: mc: - image: itzg/minecraft-server + # FTBA support is only available in multiarch image tag + image: itzg/minecraft-server:multiarch ports: # expose the Minecraft server port outside of container - 25565:25565 @@ -10,14 +11,13 @@ services: # REQUIRED for all types EULA: "TRUE" # Set server type (vs the default of vanilla) - TYPE: FORGE + TYPE: FTBA + # Use Pack ID from https://ftb.neptunepowered.org/pack/ftb-presents-direwolf20-1-12/ + FTB_MODPACK_ID: "31" volumes: # use a named, managed volume for data volume - - mc_forge:/data - # attach local host directory "mods" in same directory as this compose file - # all mods in this directory get copied into /data/mods at startup - - ./mods:/mods:ro + - mc_ftb:/data volumes: # declared the named volume, but use default/local storage engine - mc_forge: {} + mc_ftb: {} diff --git a/examples/docker-compose-ftb.yml b/examples/docker-compose-ftb.yml deleted file mode 100644 index f6c49488..00000000 --- a/examples/docker-compose-ftb.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: '3.2' - -services: - mc: - image: itzg/minecraft-server - environment: - EULA: "true" - TYPE: FTB - FTB_SERVER_MOD: https://www.feed-the-beast.com/projects/ftb-presents-skyfactory-3/files/2481284 - ports: - - 25565:25565 - volumes: - - mc-ftb:/data - -volumes: - mc-ftb: \ No newline at end of file diff --git a/examples/docker-compose-ftba.yml b/examples/docker-compose-ftba.yml new file mode 100644 index 00000000..4c9f6c86 --- /dev/null +++ b/examples/docker-compose-ftba.yml @@ -0,0 +1,23 @@ +version: "3.7" + +services: + mc: + image: itzg/minecraft-server + ports: + # expose the Minecraft server port outside of container + - 25565:25565 + environment: + # REQUIRED for all types + EULA: "TRUE" + # Set server type (vs the default of vanilla) + TYPE: FORGE + volumes: + # use a named, managed volume for data volume + - mc_forge:/data + # attach local host directory "mods" in same directory as this compose file + # all mods in this directory get copied into /data/mods at startup + - ./mods:/mods:ro + +volumes: + # declared the named volume, but use default/local storage engine + mc_forge: {} diff --git a/examples/modpacks/.gitignore b/examples/modpacks/.gitignore new file mode 100644 index 00000000..c4c4ffc6 --- /dev/null +++ b/examples/modpacks/.gitignore @@ -0,0 +1 @@ +*.zip diff --git a/examples/modpacks/README.md b/examples/modpacks/README.md new file mode 100644 index 00000000..17b8e85b --- /dev/null +++ b/examples/modpacks/README.md @@ -0,0 +1,3 @@ +Please server [modpacks downloaded from CurseForge](https://www.curseforge.com/minecraft/modpacks) in this directory. + +The example [`docker-compose-curseforge.yml`](../docker-compose-curseforge.yml) references a modpack downloaded from . From 8deaf1850b6c86e83c9e3060b45ff1e93f1da731 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sun, 31 May 2020 18:43:40 -0500 Subject: [PATCH 09/22] Fixed TYPE=FTBA in example compose file --- examples/docker-compose-ftba.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/docker-compose-ftba.yml b/examples/docker-compose-ftba.yml index 4c9f6c86..5558a36e 100644 --- a/examples/docker-compose-ftba.yml +++ b/examples/docker-compose-ftba.yml @@ -10,7 +10,7 @@ services: # REQUIRED for all types EULA: "TRUE" # Set server type (vs the default of vanilla) - TYPE: FORGE + TYPE: FTBA volumes: # use a named, managed volume for data volume - mc_forge:/data From 8c866bd17dcd942c0f81569ead9d6cd485ee1a3b Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sun, 31 May 2020 18:46:17 -0500 Subject: [PATCH 10/22] Un-flipped forge and FTBA examples compose files --- examples/docker-compose-forge.yml | 14 +++++++------- examples/docker-compose-ftba.yml | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/docker-compose-forge.yml b/examples/docker-compose-forge.yml index 756d7d5b..4c9f6c86 100644 --- a/examples/docker-compose-forge.yml +++ b/examples/docker-compose-forge.yml @@ -2,8 +2,7 @@ version: "3.7" services: mc: - # FTBA support is only available in multiarch image tag - image: itzg/minecraft-server:multiarch + image: itzg/minecraft-server ports: # expose the Minecraft server port outside of container - 25565:25565 @@ -11,13 +10,14 @@ services: # REQUIRED for all types EULA: "TRUE" # Set server type (vs the default of vanilla) - TYPE: FTBA - # Use Pack ID from https://ftb.neptunepowered.org/pack/ftb-presents-direwolf20-1-12/ - FTB_MODPACK_ID: "31" + TYPE: FORGE volumes: # use a named, managed volume for data volume - - mc_ftb:/data + - mc_forge:/data + # attach local host directory "mods" in same directory as this compose file + # all mods in this directory get copied into /data/mods at startup + - ./mods:/mods:ro volumes: # declared the named volume, but use default/local storage engine - mc_ftb: {} + mc_forge: {} diff --git a/examples/docker-compose-ftba.yml b/examples/docker-compose-ftba.yml index 5558a36e..6e07bbbc 100644 --- a/examples/docker-compose-ftba.yml +++ b/examples/docker-compose-ftba.yml @@ -2,22 +2,22 @@ version: "3.7" services: mc: - image: itzg/minecraft-server + # FTBA support is only available in multiarch image tag + image: itzg/minecraft-server:multiarch ports: - # expose the Minecraft server port outside of container - - 25565:25565 + # expose the Minecraft server port outside of container + - 25565:25565 environment: # REQUIRED for all types EULA: "TRUE" # Set server type (vs the default of vanilla) TYPE: FTBA + # Use Pack ID from https://ftb.neptunepowered.org/pack/ftb-presents-direwolf20-1-12/ + FTB_MODPACK_ID: "31" volumes: - # use a named, managed volume for data volume - - mc_forge:/data - # attach local host directory "mods" in same directory as this compose file - # all mods in this directory get copied into /data/mods at startup - - ./mods:/mods:ro + # use a named, managed volume for data volume + - mc_ftb:/data volumes: # declared the named volume, but use default/local storage engine - mc_forge: {} + mc_ftb: {} From 450442a916062c780c64b78ee7c72568668743e0 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sat, 6 Jun 2020 20:41:09 -0500 Subject: [PATCH 11/22] Enhanced WORLD to support path to zip file --- README.md | 21 ++----- examples/docker-compose-world-download.yml | 11 ++++ start-deployVanilla | 3 + start-finalSetup01World | 71 +++++++++++----------- 4 files changed, 55 insertions(+), 51 deletions(-) create mode 100644 examples/docker-compose-world-download.yml diff --git a/README.md b/README.md index de89422a..0109f739 100644 --- a/README.md +++ b/README.md @@ -984,30 +984,19 @@ where the default is "world": ### Downloadable world -Instead of mounting the `/data` volume, you can instead specify the URL of -a ZIP file containing an archived world. This will be downloaded, and -unpacked in the `/data` directory; if it does not contain a subdirectory -called `world/` then it will be searched for a file `level.dat` and the -containing subdirectory renamed to `world`. This means that most of the -archived Minecraft worlds downloadable from the Internet will already be in -the correct format. - -The ZIP file may also contain a `server.properties` file and `modules` -directory, if required. +Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format. docker run -d -e WORLD=http://www.example.com/worlds/MySave.zip ... -**NOTE:** Unless you also mount `/data` as an external volume, this world -will be deleted when the container is deleted. - **NOTE:** This URL must be accessible from inside the container. Therefore, -you should use an IP address or a globally resolveable FQDN, or else the +you should use an IP address or a globally resolvable FQDN, or else the name of a linked container. +**NOTE:** If the archive contains more than one `level.dat`, then the one to select can be picked with `WORLD_INDEX`, which defaults to 1. + ### Cloning world from a container path -The `WORLD` option can also be used to reference a directory that will be used -as a source to clone the world directory. +The `WORLD` option can also be used to reference a directory or zip file that will be used as a source to clone or unzip the world directory. For example, the following would initially clone the world's content from `/worlds/basic`. Also notice in the example that you can use a diff --git a/examples/docker-compose-world-download.yml b/examples/docker-compose-world-download.yml new file mode 100644 index 00000000..5b334f67 --- /dev/null +++ b/examples/docker-compose-world-download.yml @@ -0,0 +1,11 @@ +version: "3.7" + +services: + mc: + image: itzg/minecraft-server + ports: + - 25565:25565 + environment: + EULA: "TRUE" + VERSION: 1.7.2 + WORLD: https://www.minecraftmaps.com/survival-maps/cube-survival/download diff --git a/start-deployVanilla b/start-deployVanilla index e5dd91c3..0c161639 100644 --- a/start-deployVanilla +++ b/start-deployVanilla @@ -1,6 +1,7 @@ #!/bin/bash . /start-utils +isDebugging && set -x set -o pipefail export SERVER="minecraft_server.${VANILLA_VERSION// /_}.jar" @@ -39,5 +40,7 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then fi fi +isDebugging && ls -l + # Continue to Final Setup exec /start-finalSetup01World $@ diff --git a/start-finalSetup01World b/start-finalSetup01World index 6ef57f19..1a0bd753 100644 --- a/start-finalSetup01World +++ b/start-finalSetup01World @@ -1,6 +1,8 @@ #!/bin/bash . /start-utils +set -e +isDebugging && set -x if [ $TYPE = "FEED-THE-BEAST" ]; then worldDest=$FTB_BASE_DIR/$LEVEL @@ -8,46 +10,45 @@ else worldDest=/data/$LEVEL fi -# If no world exists and a URL for a world is supplied, download it and unpack if [[ "$WORLD" ]] && [ ! -d "$worldDest" ]; then -case "X$WORLD" in - X[Hh][Tt][Tt][Pp]*) - log "Downloading world from $WORLD" - curl -sSL -o - "$WORLD" > /data/world.zip + if isURL $WORLD; then + curl -fsSL "$WORLD" -o /tmp/world.zip + zipSrc=/tmp/world.zip + elif [[ "$WORLD" =~ .*\.zip ]]; then + zipSrc="$WORLD" + fi + + if [[ "$zipSrc" ]]; then log "Unzipping world" - unzip -o -q /data/world.zip - rm -f /data/world.zip - if [ ! -d $worldDest ]; then - log World directory not found - for i in /data/*/level.dat; do - if [ -f "$i" ]; then - d=`dirname "$i"` - log Renaming world directory from $d - mv -f "$d" $worldDest - fi - done - fi - if [ "$TYPE" = "SPIGOT" ]; then - # Reorganise if a Spigot server - log "Moving End and Nether maps to Spigot location" - [ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "/data/${LEVEL}_the_end" - [ -d "$worldDest/DIM-1" ] && mv -f "$worldDest/DIM-1" "/data/${LEVEL}_nether" - fi - ;; - *) - if [[ -d "$WORLD" ]]; then - if [[ ! -d "$worldDest" ]]; then - log "Cloning world directory from $WORLD ..." - cp -r "$WORLD" "$worldDest" - else - log "Skipping clone from $WORLD since $worldDest exists" - fi + + # Stage contents so that the correct subdirectory can be picked off + mkdir -p /tmp/world-data + (cd /tmp/world-data && unzip -o -q "$zipSrc") + + baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;) + count=$(echo "$baseDirs" | wc -l) + if [[ $count -gt 1 ]]; then + baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)" + baseName=$(basename "$baseDir") + log "WARN multiple levels found, picking: $baseName" + elif [[ $count -gt 0 ]]; then + baseDir="$baseDirs" else - log "World cloning source '$WORLD' doesn't seem to exist" + log "ERROR invalid world content" exit 1 fi - ;; -esac + mv "$baseDir" "$worldDest" + else + log "Cloning world directory from $WORLD ..." + cp -r "$WORLD" "$worldDest" + fi + + if [ "$TYPE" = "SPIGOT" ]; then + # Reorganise if a Spigot server + log "Moving End and Nether maps to Spigot location" + [ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "/data/${LEVEL}_the_end" + [ -d "$worldDest/DIM-1" ] && mv -f "$worldDest/DIM-1" "/data/${LEVEL}_nether" + fi fi exec /start-finalSetup02Modpack $@ From 3cf58e3cafad9af89297593aa8f9eafeb5b6c8bc Mon Sep 17 00:00:00 2001 From: Luis Marroquin Date: Wed, 10 Jun 2020 06:56:07 -0500 Subject: [PATCH 12/22] Fixed docker-compose-proxied.yml link (#554) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0109f739..07247960 100644 --- a/README.md +++ b/README.md @@ -1111,7 +1111,7 @@ Large page support can also be enabled by adding ### HTTP Proxy You may configure the use of an HTTP/HTTPS proxy by passing the proxy's URL via the `PROXY` -environment variable. In [the example compose file](docker-compose-proxied.yml) it references +environment variable. In [the example compose file](examples/docker-compose-proxied.yml) it references a companion squid proxy by setting the equivalent of -e PROXY=proxy:3128 From 2241ba88199c6f41ead7b73a0dc8f1deec1c8e94 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Wed, 10 Jun 2020 18:43:07 -0500 Subject: [PATCH 13/22] Added build image action --- .github/workflows/main.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..ca62ce4c --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,28 @@ +# This is a basic workflow to help you get started with Actions + +name: build + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Build and push Docker images + uses: docker/build-push-action@v1.1.0 + with: + repository: itzg/minecraft-server + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASSWORD }} + tag_with_ref: true + tag_with_sha: true + cache_froms: itzg/minecraft-server:latest + add_git_labels: true + push: false From b273bf29478ebe6f390d8d914addf4c2cb96e487 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Wed, 10 Jun 2020 18:50:40 -0500 Subject: [PATCH 14/22] Removed cirleci config --- .circleci/config.yml | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 1c98efc9..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,22 +0,0 @@ -version: 2 -jobs: - minecraft_server: - docker: - - image: circleci/buildpack-deps:19.10 - steps: - - checkout - - setup_remote_docker - - run: - name: Build image - command: docker build -t mc:$CIRCLE_BUILD_NUM . - -workflows: - version: 2 - build: - jobs: - - minecraft_server: - filters: - branches: - ignore: - - armv7 - - multiarch From 80099ad63dd05e3c4f852450d2996cd4fc2f5e52 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sun, 14 Jun 2020 11:14:11 -0500 Subject: [PATCH 15/22] Added debug option to dump managed server.properties --- start-finalSetup04ServerProperties | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/start-finalSetup04ServerProperties b/start-finalSetup04ServerProperties index ea92f88e..d95ddaa1 100644 --- a/start-finalSetup04ServerProperties +++ b/start-finalSetup04ServerProperties @@ -189,4 +189,9 @@ if isTrue "${ENABLE_AUTOPAUSE}"; then fi fi +if isDebugging; then + log "DEBUG Dumping server.properties" + cat /data/server.properties +fi + exec /start-finalSetup05EnvVariables $@ From 2b7f923865de63874fc04dcfd8f7eedd4a005953 Mon Sep 17 00:00:00 2001 From: Toboshii Nakama <63410334+toboshii@users.noreply.github.com> Date: Sun, 14 Jun 2020 11:20:37 -0500 Subject: [PATCH 16/22] Add ttf-dejavu to package list (#556) --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index cee2e0ed..8b0ec782 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,8 @@ RUN apk add --no-cache -U \ rsync \ nano \ sudo \ - knock + knock \ + ttf-dejavu RUN addgroup -g 1000 minecraft \ && adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft \ From f5dde77efe253e7ac668acb721f6257db32f818d Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Fri, 19 Jun 2020 11:05:32 -0500 Subject: [PATCH 17/22] Enabled iterative development with SCRIPTS var --- DEVELOPMENT.md | 28 ++++++++++++++++++++++++++++ health.sh | 2 +- start | 6 +++--- start-autopause | 2 +- start-configuration | 26 +++++++++++++------------- start-deployBukkitSpigot | 4 ++-- start-deployCustom | 4 ++-- start-deployFTB | 4 ++-- start-deployFabric | 4 ++-- start-deployForge | 4 ++-- start-deployPaper | 4 ++-- start-deploySpongeVanilla | 4 ++-- start-deployTuinity | 4 ++-- start-deployVanilla | 4 ++-- start-finalSetup01World | 4 ++-- start-finalSetup02Modpack | 4 ++-- start-finalSetup03Modconfig | 4 ++-- start-finalSetup04ServerProperties | 4 ++-- start-finalSetup05EnvVariables | 4 ++-- start-magma | 4 ++-- start-minecraftFinalSetup | 2 +- start-validateCurseInstance | 4 ++-- 22 files changed, 79 insertions(+), 51 deletions(-) create mode 100644 DEVELOPMENT.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 00000000..d879bc7b --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,28 @@ +Individual scripts can be iteratively developed and tested using the following procedure. + +First, build a baseline of the image to include the packages needed by existing or new scripts: + +```shell script +docker build -t mc-dev . +``` + +Using the baseline image, an interactive container can be started to iteratively run the scripts to be developed. By attaching the current workspace directory, you can use the local editor of your choice to iteratively modify scripts while using the container to run them. + +```shell script +docker run -it --rm -v ${PWD}:/scripts -e SCRIPTS=/scripts/ --entrypoint bash mc-dev +``` + +From within the container you can run individual scripts via the attached `/scripts/` path; however, be sure to set any environment variables expected by the scripts by either `export`ing them manually: + +```shell script +export VANILLA_VERSION=1.12.2 +/scripts/start-magma +``` + +...or pre-pending script execution: + +```shell script +VANILLA_VERSION=1.12.2 /scripts/start-magma +``` + +> NOTE: You may want to temporarily add an `exit` statement near the end of your script to isolate execution to just the script you're developing. diff --git a/health.sh b/health.sh index eab0f5c0..0ce34be1 100644 --- a/health.sh +++ b/health.sh @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils if isTrue "${ENABLE_AUTOPAUSE}" && [[ "$( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }')" =~ ^T.*$ ]]; then echo "Java process suspended by Autopause function" diff --git a/start b/start index c50aef4f..f6d467e7 100644 --- a/start +++ b/start @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils umask 0002 chmod g+w /data @@ -45,7 +45,7 @@ if [ $(id -u) = 0 ]; then echo 'hosts: files dns' > /etc/nsswitch.conf fi - exec su-exec ${runAsUser}:${runAsGroup} /start-configuration $@ + exec su-exec ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration $@ else - exec /start-configuration $@ + exec ${SCRIPTS:-/}start-configuration $@ fi diff --git a/start-autopause b/start-autopause index d73f8302..32c5e64a 100755 --- a/start-autopause +++ b/start-autopause @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils log "Autopause functionality enabled" diff --git a/start-configuration b/start-configuration index 55a157ea..737c960a 100644 --- a/start-configuration +++ b/start-configuration @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils shopt -s nullglob @@ -69,53 +69,53 @@ cd /data || exit 1 export ORIGINAL_TYPE=${TYPE^^} if isTrue "${ENABLE_AUTOPAUSE}"; then - /start-autopause + ${SCRIPTS:-/}start-autopause fi log "Resolving type given ${TYPE}" case "${TYPE^^}" in *BUKKIT|SPIGOT) - exec /start-deployBukkitSpigot "$@" + exec ${SCRIPTS:-/}start-deployBukkitSpigot "$@" ;; PAPER) - exec /start-deployPaper "$@" + exec ${SCRIPTS:-/}start-deployPaper "$@" ;; TUINITY) - exec /start-deployTuinity "$@" + exec ${SCRIPTS:-/}start-deployTuinity "$@" ;; FORGE) - exec /start-deployForge "$@" + exec ${SCRIPTS:-/}start-deployForge "$@" ;; FABRIC) - exec /start-deployFabric "$@" + exec ${SCRIPTS:-/}start-deployFabric "$@" ;; FTB|CURSEFORGE) - exec /start-deployFTB "$@" + exec ${SCRIPTS:-/}start-deployFTB "$@" ;; VANILLA) - exec /start-deployVanilla "$@" + exec ${SCRIPTS:-/}start-deployVanilla "$@" ;; SPONGEVANILLA) - exec /start-deploySpongeVanilla "$@" + exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@" ;; CUSTOM) - exec /start-deployCustom "$@" + exec ${SCRIPTS:-/}start-deployCustom "$@" ;; CURSE_INSTANCE) - exec /start-validateCurseInstance "$@" + exec ${SCRIPTS:-/}start-validateCurseInstance "$@" ;; MAGMA) - exec /start-magma "$@" + exec ${SCRIPTS:-/}start-magma "$@" ;; *) diff --git a/start-deployBukkitSpigot b/start-deployBukkitSpigot index fec3f655..d995089a 100644 --- a/start-deployBukkitSpigot +++ b/start-deployBukkitSpigot @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils set -e @@ -102,4 +102,4 @@ export TYPE=SPIGOT export SKIP_LOG4J_CONFIG=true # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-deployCustom b/start-deployCustom index 5b7e6f8d..31105e4e 100644 --- a/start-deployCustom +++ b/start-deployCustom @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils if isURL ${CUSTOM_SERVER}; then filename=$(basename ${CUSTOM_SERVER}) @@ -28,4 +28,4 @@ fi export SKIP_LOG4J_CONFIG=true # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-deployFTB b/start-deployFTB index 2a3c12b5..5006f24b 100644 --- a/start-deployFTB +++ b/start-deployFTB @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils export FTB_BASE_DIR=/data/FeedTheBeast legacyJavaFixerUrl=http://ftb.cursecdn.com/FTB2/maven/net/minecraftforge/lex/legacyjavafixer/1.0/legacyjavafixer-1.0.jar @@ -135,4 +135,4 @@ elif [ -e "${FTB_DIR}/Install.sh" ]; then fi # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-deployFabric b/start-deployFabric index d8305568..b0bc1329 100644 --- a/start-deployFabric +++ b/start-deployFabric @@ -1,7 +1,7 @@ #!/bin/bash set -eu -. /start-utils +. ${SCRIPTS:-/}start-utils export TYPE=FABRIC @@ -75,4 +75,4 @@ else fi # Contineut to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-deployForge b/start-deployForge index 739808b0..8feb33ea 100644 --- a/start-deployForge +++ b/start-deployForge @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils export TYPE=FORGE @@ -113,4 +113,4 @@ else fi # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-deployPaper b/start-deployPaper index 07d77117..018efa63 100644 --- a/start-deployPaper +++ b/start-deployPaper @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils : ${PAPERBUILD:=latest} export SERVER=paper_server-${VANILLA_VERSION}-${PAPERBUILD}.jar @@ -20,4 +20,4 @@ export TYPE=SPIGOT export SKIP_LOG4J_CONFIG=true # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-deploySpongeVanilla b/start-deploySpongeVanilla index f6ab1934..28c5ab73 100644 --- a/start-deploySpongeVanilla +++ b/start-deploySpongeVanilla @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils export TYPE=spongevanilla @@ -36,4 +36,4 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then fi # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-deployTuinity b/start-deployTuinity index b998bdd9..8e6adc62 100644 --- a/start-deployTuinity +++ b/start-deployTuinity @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils if [ "${VERSION}" != "LATEST" ]; then log "ERROR: Tunity server type only supports VERSION=LATEST" @@ -24,4 +24,4 @@ fi export TYPE=SPIGOT # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-deployVanilla b/start-deployVanilla index 0c161639..52dc92e7 100644 --- a/start-deployVanilla +++ b/start-deployVanilla @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils isDebugging && set -x set -o pipefail @@ -43,4 +43,4 @@ fi isDebugging && ls -l # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-finalSetup01World b/start-finalSetup01World index 1a0bd753..31a6e156 100644 --- a/start-finalSetup01World +++ b/start-finalSetup01World @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils set -e isDebugging && set -x @@ -51,4 +51,4 @@ if [[ "$WORLD" ]] && [ ! -d "$worldDest" ]; then fi fi -exec /start-finalSetup02Modpack $@ +exec ${SCRIPTS:-/}start-finalSetup02Modpack $@ diff --git a/start-finalSetup02Modpack b/start-finalSetup02Modpack index bdd0b40b..15347cf9 100644 --- a/start-finalSetup02Modpack +++ b/start-finalSetup02Modpack @@ -2,7 +2,7 @@ set -e -. /start-utils +. ${SCRIPTS:-/}start-utils # CURSE_URL_BASE used in manifest downloads below CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects} @@ -154,4 +154,4 @@ if [[ "${GENERIC_PACK}" ]]; then fi fi -exec /start-finalSetup03Modconfig $@ +exec ${SCRIPTS:-/}start-finalSetup03Modconfig $@ diff --git a/start-finalSetup03Modconfig b/start-finalSetup03Modconfig index f4219a73..5758a25c 100644 --- a/start-finalSetup03Modconfig +++ b/start-finalSetup03Modconfig @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils # If supplied with a URL for a config (simple zip of configurations), download it and unpack if [[ "$MODCONFIG" ]]; then @@ -24,4 +24,4 @@ case "X$MODCONFIG" in esac fi -exec /start-finalSetup04ServerProperties $@ +exec ${SCRIPTS:-/}start-finalSetup04ServerProperties $@ diff --git a/start-finalSetup04ServerProperties b/start-finalSetup04ServerProperties index d95ddaa1..e77ea8a1 100644 --- a/start-finalSetup04ServerProperties +++ b/start-finalSetup04ServerProperties @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils # FUNCTIONS function setServerProp { @@ -194,4 +194,4 @@ if isDebugging; then cat /data/server.properties fi -exec /start-finalSetup05EnvVariables $@ +exec ${SCRIPTS:-/}start-finalSetup05EnvVariables $@ diff --git a/start-finalSetup05EnvVariables b/start-finalSetup05EnvVariables index 90a85d52..3df6b5a2 100644 --- a/start-finalSetup05EnvVariables +++ b/start-finalSetup05EnvVariables @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils if [ "${REPLACE_ENV_VARIABLES^^}" = "TRUE" ]; then log "Replacing env variables in configs that match the prefix $ENV_VARIABLE_PREFIX..." @@ -25,4 +25,4 @@ if [ "${REPLACE_ENV_VARIABLES^^}" = "TRUE" ]; then done < <(env) fi -exec /start-minecraftFinalSetup $@ +exec ${SCRIPTS:-/}start-minecraftFinalSetup $@ diff --git a/start-magma b/start-magma index 70b201f4..a8c7c6a3 100755 --- a/start-magma +++ b/start-magma @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils export SERVER="/data/magma-server-${VANILLA_VERSION}.jar" @@ -15,4 +15,4 @@ fi export SKIP_LOG4J_CONFIG=true # Continue to Final Setup -exec /start-finalSetup01World $@ +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-minecraftFinalSetup b/start-minecraftFinalSetup index 6b1e858c..5b706ad0 100644 --- a/start-minecraftFinalSetup +++ b/start-minecraftFinalSetup @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils if [ -n "$OPS" ]; then log "Setting/adding ops" diff --git a/start-validateCurseInstance b/start-validateCurseInstance index 09af3ab5..60bb2edd 100755 --- a/start-validateCurseInstance +++ b/start-validateCurseInstance @@ -1,6 +1,6 @@ #!/bin/bash -. /start-utils +. ${SCRIPTS:-/}start-utils if ! [[ -v CURSE_INSTANCE_JSON ]]; then log "ERROR: CURSE_INSTANCE_JSON needs to be set" @@ -15,4 +15,4 @@ fi log "Resolved CURSE_INSTANCE_JSON as ${CURSE_INSTANCE_JSON}" # Continue to Final Setup -exec /start-finalSetup01World "$@" +exec ${SCRIPTS:-/}start-finalSetup01World "$@" From f93c42a23f51bca75c619e390e5cd7af97eb5975 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Fri, 19 Jun 2020 11:31:41 -0500 Subject: [PATCH 18/22] Added support for tagging during docker-versions-create.sh --- docker-versions-create.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/docker-versions-create.sh b/docker-versions-create.sh index 557c9689..6de22938 100755 --- a/docker-versions-create.sh +++ b/docker-versions-create.sh @@ -10,12 +10,28 @@ function TrapExit { batchMode=false -while getopts "b" arg +while getopts "hbt:" arg do case $arg in b) batchMode=true ;; + t) + tag=${OPTARG} + ;; + h) + echo " +Usage $0 [options] + +Options: + -b enable batch mode, which avoids interactive prompts and causes script to fail immediately + when any merge fails + -t TAG tag and push the current revision on master with the given tag + and apply respective tags to each branch + -h display this help and exit +" + exit + ;; *) echo "Unsupported arg $arg" exit 2 @@ -34,6 +50,10 @@ test -d ./.git || { echo ".git folder was not found. Please start this script fr git checkout master git pull --all || { echo "Can't pull the repo!"; \ exit 1; } +if [[ $tag ]]; then + git tag $tag + git push origin $tag +fi git_branches=$(git branch -a) @@ -57,6 +77,10 @@ for branch in "${branches_list[@]}"; do git commit -m "Auto merge branch with master" -a # push may fail if remote doesn't have this branch yet. In this case - sending branch git push || git push -u origin "$branch" || { echo "Can't push changes to the origin."; exit 1; } + if [[ $tag ]]; then + git tag "$tag-$branch" + git push origin "$tag-$branch" + fi elif ${batchMode}; then status=$? echo "Git merge failed in batch mode" From bc318fa18585a99a0c4abf4eae0dfa810252cc5d Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Fri, 19 Jun 2020 11:31:56 -0500 Subject: [PATCH 19/22] Added support for Mohist servers --- README.md | 9 +++++++++ start-configuration | 4 ++++ start-mohist | 40 ++++++++++++++++++++++++++++++++++++++++ start-utils | 9 ++++++++- 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 start-mohist diff --git a/README.md b/README.md index 07247960..da9fdbeb 100644 --- a/README.md +++ b/README.md @@ -525,6 +525,15 @@ A [Magma](https://magmafoundation.org/) server, which is a combination of Forge > **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2" + +## Running a Mohist server + +A [Mohist](https://github.com/Mohist-Community/Mohist) server can be used with + + -e TYPE=MOHIST + +> **NOTE** there are limited base versions supported, so you will also need to set `VERSION`, such as "1.12.2" + ## Running a server with a Feed the Beast modpack > **NOTE** requires `itzg/minecraft-server:multiarch` image diff --git a/start-configuration b/start-configuration index 737c960a..a41cae58 100644 --- a/start-configuration +++ b/start-configuration @@ -118,6 +118,10 @@ case "${TYPE^^}" in exec ${SCRIPTS:-/}start-magma "$@" ;; + MOHIST) + exec ${SCRIPTS:-/}start-mohist "$@" + ;; + *) log "Invalid type: '$TYPE'" log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTB, CURSEFORGE, SPONGEVANILLA" diff --git a/start-mohist b/start-mohist new file mode 100644 index 00000000..c9fcecd2 --- /dev/null +++ b/start-mohist @@ -0,0 +1,40 @@ +#!/bin/bash + +. ${SCRIPTS:-/}start-utils +requireVar VANILLA_VERSION +set -o pipefail +set -e +isDebugging && set -x + +mohistJobs=https://ci.codemc.io/job/Mohist-Community/job/ +mohistJob=${mohistJobs}Mohist-${VANILLA_VERSION}/ + +if ! curl -X HEAD -o /dev/null -fsSL "${mohistJob}"; then + log "ERROR: mohist builds do not exist for ${VANILLA_VERSION}" + log " check https://ci.codemc.io/job/Mohist-Community/ for available versions" + exit 1 +fi + +latestBuildRelPath=$( + curl -fsSL "${mohistJob}lastSuccessfulBuild/api/json" | + jq -r '.artifacts[0].relativePath' +) + +baseName=$(basename "${latestBuildRelPath}") +if [[ ${baseName} != *-server.jar* ]]; then + log "ERROR: mohist build for ${VANILLA_VERSION} is not a valid server jar, found ${baseName}" + log " check https://ci.codemc.io/job/Mohist-Community/ for available versions" + exit 1 +fi + +export SERVER="/data/${baseName}" + +if [ ! -f ${SERVER} ]; then + log "Downloading ${SERVER}" + curl -o "${SERVER}" -fsSL "${mohistJob}lastSuccessfulBuild/artifact/${latestBuildRelPath}" +fi + +export SKIP_LOG4J_CONFIG=true + +# Continue to Final Setup +exec ${SCRIPTS:-/}start-finalSetup01World $@ diff --git a/start-utils b/start-utils index e054396a..aa8d933a 100644 --- a/start-utils +++ b/start-utils @@ -99,4 +99,11 @@ function versionLessThan { return 1 fi fi -} \ No newline at end of file +} + +requireVar() { + if [ ! -v $1 ]; then + log "ERROR: $1 is required to be set" + exit 1 + fi +} From 3eaf756aa2a9fbc1a8ca764c6b84ffad06cee727 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Fri, 19 Jun 2020 11:41:53 -0500 Subject: [PATCH 20/22] ci: adjusted github actions to build non-multiarch branches/tags --- .github/workflows/main.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ca62ce4c..cd01bf65 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,7 +4,15 @@ name: build on: push: - branches: [ master ] + branches: + - master + - openj9 + - openj9-nightly + - adopt11 + - adopt13 + tags: + - "[0-9.]" + - "[0-9.]-*" pull_request: branches: [ master ] From 60ef1b886724a903d09344e03b0714a7b92a320b Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Fri, 19 Jun 2020 13:15:23 -0500 Subject: [PATCH 21/22] ci: fixed github action tags matching --- .github/workflows/main.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cd01bf65..c57c31ee 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,8 +11,11 @@ on: - adopt11 - adopt13 tags: - - "[0-9.]" - - "[0-9.]-*" + - "[0-9]+.[0-9]+.[0-9]+" + - "[0-9]+.[0-9]+.[0-9]+-openj9" + - "[0-9]+.[0-9]+.[0-9]+-openj9-nightly" + - "[0-9]+.[0-9]+.[0-9]+-adopt11" + - "[0-9]+.[0-9]+.[0-9]+-adopt13" pull_request: branches: [ master ] From 2ee5a25c9103e94600c41f27eca272d207856bd6 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Fri, 19 Jun 2020 13:23:05 -0500 Subject: [PATCH 22/22] ci: adjusted main github action name --- .github/workflows/main.yml | 2 +- start-mohist | 0 2 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 start-mohist diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c57c31ee..6b8fdd84 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,6 @@ # This is a basic workflow to help you get started with Actions -name: build +name: Build non-multiarch branches/tags on: push: diff --git a/start-mohist b/start-mohist old mode 100644 new mode 100755