From 0f7bd5f4fd58cced5b879a54cc6019aac5557d73 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Mon, 7 Dec 2020 10:52:37 -0600 Subject: [PATCH 1/7] ci: Added adopt15 branch releases --- .github/workflows/main.yml | 2 ++ docker-versions-create.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 93c06f1e..3e17d475 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,6 +9,7 @@ on: - adopt11 - adopt13 - adopt14 + - adopt15 tags: - "[0-9]+.[0-9]+.[0-9]+" - "[0-9]+.[0-9]+.[0-9]+-openj9" @@ -16,6 +17,7 @@ on: - "[0-9]+.[0-9]+.[0-9]+-adopt11" - "[0-9]+.[0-9]+.[0-9]+-adopt13" - "[0-9]+.[0-9]+.[0-9]+-adopt14" + - "[0-9]+.[0-9]+.[0-9]+-adopt15" jobs: test: diff --git a/docker-versions-create.sh b/docker-versions-create.sh index b9a4c0a9..5c745bca 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' 'adopt14' 'multiarch' 'multiarch-latest') +branches_list=('openj9' 'openj9-nightly' 'adopt11' 'adopt13' 'adopt14' 'adopt15' 'multiarch' 'multiarch-latest') function TrapExit { echo "Checking out back in master" From 59ca1ce3a69e7a4a95103b5ad43a37ad3169a68c Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Fri, 11 Dec 2020 21:12:44 -0600 Subject: [PATCH 2/7] Improved URL handling for GENERIC_PACK For #684 --- start-finalSetupModpack | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/start-finalSetupModpack b/start-finalSetupModpack index e21340cc..0c18406b 100644 --- a/start-finalSetupModpack +++ b/start-finalSetupModpack @@ -1,8 +1,11 @@ #!/bin/bash -set -e +set -e -o pipefail . ${SCRIPTS:-/}start-utils +if isDebugging; then + set -x +fi # CURSE_URL_BASE used in manifest downloads below CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects} @@ -140,10 +143,9 @@ fi if [[ "${GENERIC_PACK}" ]]; then if isURL "${GENERIC_PACK}"; then - generic_pack_url=${GENERIC_PACK} - GENERIC_PACK=/tmp/$(basename ${generic_pack_url}) - log "Downloading generic pack from ${generic_pack_url} ..." - curl -fsSL -o ${GENERIC_PACK} ${generic_pack_url} + log "Downloading generic pack ..." + curl -fsSL -o /tmp/generic_pack.zip "${GENERIC_PACK}" + GENERIC_PACK=/tmp/generic_pack.zip fi sum_file=/data/.generic_pack.sum From 31b0f711b8a8a0b8165241673d317f9681a26461 Mon Sep 17 00:00:00 2001 From: Mike Wilson Date: Sat, 12 Dec 2020 09:26:32 -0500 Subject: [PATCH 3/7] Fixing some spigot world import issues (#683) * Fixing adding an existing spigot world and removing incorrectly identifying spigot worlds as multiple worlds * Update start-finalSetupWorld Co-authored-by: Geoff Bourne Co-authored-by: Geoff Bourne --- start-finalSetupWorld | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/start-finalSetupWorld b/start-finalSetupWorld index 24642e59..bf3b5ded 100644 --- a/start-finalSetupWorld +++ b/start-finalSetupWorld @@ -25,7 +25,12 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); mkdir -p /tmp/world-data (cd /tmp/world-data && unzip -o -q "$zipSrc") - baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;) + if [ "$TYPE" = "SPIGOT" ]; then + baseDirs=$(find /tmp/world-data -name "level.dat" -not -path "*_nether*" -not -path "*_the_end*" -printf "%h") + else + baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;) + fi + count=$(echo "$baseDirs" | wc -l) if [[ $count -gt 1 ]]; then baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)" @@ -38,6 +43,11 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); exit 1 fi rsync --remove-source-files --recursive --delete "$baseDir/" "$worldDest" + if [ "$TYPE" = "SPIGOT" ]; then + log "Copying end and nether ..." + [ -d "${baseDir}_nether" ] && rsync --remove-source-files --recursive --delete "${baseDir}_nether/" "${worldDest}_nether" + [ -d "${baseDir}_the_end" ] && rsync --remove-source-files --recursive --delete "${baseDir}_the_end/" "${worldDest}_the_end" + fi else log "Cloning world directory from $WORLD ..." rsync --recursive --delete "${WORLD%/}"/ "$worldDest" From c1db13c1f6135a8611f223f6f1b6c649f99e331e Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sat, 12 Dec 2020 11:10:13 -0600 Subject: [PATCH 4/7] Fixed dirname handling in find for SPIGOT WORLD handling For #685 --- start-finalSetupWorld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start-finalSetupWorld b/start-finalSetupWorld index bf3b5ded..5d1bd79c 100644 --- a/start-finalSetupWorld +++ b/start-finalSetupWorld @@ -26,7 +26,7 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); (cd /tmp/world-data && unzip -o -q "$zipSrc") if [ "$TYPE" = "SPIGOT" ]; then - baseDirs=$(find /tmp/world-data -name "level.dat" -not -path "*_nether*" -not -path "*_the_end*" -printf "%h") + baseDirs=$(find /tmp/world-data -name "level.dat" -not -path "*_nether*" -not -path "*_the_end*" -exec dirname "{}" \;) else baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;) fi From d3a5885d9518244503a6ccaeed47c7989acad8b5 Mon Sep 17 00:00:00 2001 From: Geoff Bourne Date: Sat, 12 Dec 2020 15:22:07 -0600 Subject: [PATCH 5/7] Fixed handling of query parameters in MODS url For #684 --- start-finalSetupModpack | 48 ++++++++---------- start-utils | 110 +++++++++++++++++++++++++--------------- 2 files changed, 90 insertions(+), 68 deletions(-) diff --git a/start-finalSetupModpack b/start-finalSetupModpack index 0c18406b..20adddab 100644 --- a/start-finalSetupModpack +++ b/start-finalSetupModpack @@ -25,7 +25,7 @@ if [[ "$MODPACK" ]]; then if [[ "${MODPACK}" == *.zip ]]; then downloadUrl="${MODPACK}" else - downloadUrl=$(curl -Ls -o /dev/null -w %{url_effective} $MODPACK) + downloadUrl=$(curl -Ls -o /dev/null -w %{effective_url} $MODPACK) if ! [[ $downloadUrl == *.zip ]]; then log "ERROR Invalid URL given for MODPACK: $downloadUrl resolved from $MODPACK" log " Must be HTTP or HTTPS and a ZIP file" @@ -61,39 +61,31 @@ fi # If supplied with a URL for a plugin download it. if [[ "$MODS" ]]; then + if [ "$TYPE" = "SPIGOT" ]; then + out_dir=/data/plugins + else + out_dir=/data/mods + fi + mkdir -p "$out_dir" + for i in ${MODS//,/ } do if isURL $i; then - if [[ $i == *.jar ]]; then - EFFECTIVE_MOD_URL=$i - else - EFFECTIVE_MOD_URL=$(curl -Ls -o /dev/null -w %{url_effective} $i) - if ! [[ $EFFECTIVE_MOD_URL == *.jar ]]; then - log "ERROR Invalid URL given in MODS: $EFFECTIVE_MOD_URL resolved from $i" - log " Must be HTTP or HTTPS and a JAR file" - exit 1 + log "Downloading mod/plugin $i ..." + effective_url=$(resolveEffectiveUrl "$i") + if isValidFileURL jar "${effective_url}"; then + out_file=$(getFilenameFromUrl "${effective_url}") + if ! curl -fsSL -o "${out_dir}/$out_file" "${effective_url}"; then + log "ERROR: failed to download from $i into $out_dir" + exit 2 fi - fi - - log "Downloading mod/plugin via HTTP" - log " from $EFFECTIVE_MOD_URL ..." - if ! curl -sSL -o /tmp/${EFFECTIVE_MOD_URL##*/} $EFFECTIVE_MOD_URL; then - log "ERROR: failed to download from $EFFECTIVE_MOD_URL to /tmp/${EFFECTIVE_MOD_URL##*/}" + else + log "ERROR: $effective_url resolved from $i is not a valid jar URL" exit 2 fi - - if [ "$TYPE" = "SPIGOT" ]; then - mkdir -p /data/plugins - mv /tmp/${EFFECTIVE_MOD_URL##*/} /data/plugins/${EFFECTIVE_MOD_URL##*/} - else - mkdir -p /data/mods - mv /tmp/${EFFECTIVE_MOD_URL##*/} /data/mods/${EFFECTIVE_MOD_URL##*/} - fi - rm -f /tmp/${EFFECTIVE_MOD_URL##*/} - else log "ERROR Invalid URL given in MODS: $i" - exit 1 + exit 2 fi done fi @@ -103,7 +95,7 @@ if [[ "$MANIFEST" ]]; then EFFECTIVE_MANIFEST_FILE=$MANIFEST elif isURL "$MANIFEST"; then EFFECTIVE_MANIFEST_FILE=/tmp/manifest.json - EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w %{url_effective} $MANIFEST) + EFFECTIVE_MANIFEST_URL=$(curl -Ls -o /dev/null -w %{effective_url} $MANIFEST) curl -Ls -o $EFFECTIVE_MANIFEST_FILE "$EFFECTIVE_MANIFEST_URL" else log "MANIFEST='$MANIFEST' is not a valid manifest url or location" @@ -124,7 +116,7 @@ case "X$EFFECTIVE_MANIFEST_FILE" in do if [ ! -f $MOD_DIR/${p}_${f}.jar ] then - redirect_url="$(curl -Ls -o /dev/null -w %{url_effective} ${CURSE_URL_BASE}/${p})" + redirect_url="$(curl -Ls -o /dev/null -w %{effective_url} ${CURSE_URL_BASE}/${p})" url="$redirect_url/download/${f}/file" log Downloading curseforge mod $url # Manifest usually doesn't have mod names. Using id should be fine, tho diff --git a/start-utils b/start-utils index a46d1a28..b461a836 100644 --- a/start-utils +++ b/start-utils @@ -1,8 +1,14 @@ #!/bin/bash -function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; } +function join_by() { + local d=$1 + shift + echo -n "$1" + shift + printf "%s" "${@/#/$d}" +} -function isURL { +function isURL() { local value=$1 if [[ ${value:0:8} == "https://" || ${value:0:7} == "http://" ]]; then @@ -12,90 +18,114 @@ function isURL { fi } -function isTrue { +function isValidFileURL() { + suffix=${1:?Missing required suffix arg} + url=${2:?Missing required url arg} + + [[ "$url" == http*://*.${suffix} || "$url" == http*://*.${suffix}\?* ]] +} + +function resolveEffectiveUrl() { + url="${1:?Missing required url argument}" + if ! curl -Ls -o /dev/null -w %{url_effective} "$url"; then + log "ERROR failed to resolve effective URL from $url" + exit 2 + fi +} + +function getFilenameFromUrl() { + url="${1:?Missing required url argument}" + strippedOfQuery="${url%\?*}" + basename "$strippedOfQuery" +} + +function isTrue() { local value=${1,,} result= case ${value} in - true|on) - result=0 - ;; - *) - result=1 - ;; + true | on) + result=0 + ;; + *) + result=1 + ;; esac return ${result} } -function isDebugging { - if [[ -v DEBUG ]] && [[ ${DEBUG^^} = TRUE ]]; then +function isDebugging() { + if [[ -v DEBUG ]] && [[ ${DEBUG^^} == TRUE ]]; then return 0 else return 1 fi } -function debug { +function debug() { if isDebugging; then log "DEBUG: $*" fi } -function logn { +function logn() { echo -n "[init] $*" } -function log { +function log() { echo "[init] $*" } -function logAutopause { +function logAutopause() { echo "[Autopause loop] $*" } -function logAutopauseAction { +function logAutopauseAction() { echo "[$(date -Iseconds)] [Autopause] $*" } -function normalizeMemSize { +function normalizeMemSize() { local scale=1 case ${1,,} in - *k) - scale=1024;; - *m) - scale=1048576;; - *g) - scale=1073741824;; + *k) + scale=1024 + ;; + *m) + scale=1048576 + ;; + *g) + scale=1073741824 + ;; esac - val=${1:0: -1} - echo $(( val * scale )) + val=${1:0:-1} + echo $((val * scale)) } -function versionLessThan { +function versionLessThan() { local activeParts - IFS=. read -ra activeParts <<< "${VANILLA_VERSION}" + IFS=. read -ra activeParts <<<"${VANILLA_VERSION}" local givenParts - IFS=. read -ra givenParts <<< "$1" + IFS=. read -ra givenParts <<<"$1" - if (( ${#activeParts[@]} < 2 )); then + if ((${#activeParts[@]} < 2)); then return 1 fi - if (( ${#activeParts[@]} == 2 )); then - if (( activeParts[0] < givenParts[0] )) || \ - (( activeParts[0] == givenParts[0] && activeParts[1] < givenParts[1] )); then + 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 - 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 + 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 @@ -115,10 +145,10 @@ requireVar() { } function writeEula() { -if ! echo "# Generated via Docker on $(date) + if ! echo "# Generated via Docker on $(date) eula=${EULA,,} -" > /data/eula.txt; then - log "ERROR: unable to write eula to /data. Please make sure attached directory is writable by uid=${UID}" - exit 2 -fi +" >/data/eula.txt; then + log "ERROR: unable to write eula to /data. Please make sure attached directory is writable by uid=${UID}" + exit 2 + fi } From 9d68fa3b887a3a5809daaf528b67a3dc279b68f7 Mon Sep 17 00:00:00 2001 From: Silthus <755327+Silthus@users.noreply.github.com> Date: Mon, 14 Dec 2020 03:00:06 +0100 Subject: [PATCH 6/7] feat: improvde REMOVE_OLD_MODS option (#688) --- README.md | 6 +++--- start-finalSetupModpack | 16 ++++++++++------ start-minecraftFinalSetup | 3 --- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0aa245fa..5a753475 100644 --- a/README.md +++ b/README.md @@ -301,14 +301,14 @@ or downloading a world with the `WORLD` option. There are two additional volumes that can be mounted; `/mods` and `/config`. Any files in either of these filesystems will be copied over to the main -`/data` filesystem before starting Minecraft. If you want old mods to be removed as the `/mods` content is updated, then add `-e REMOVE_OLD_MODS=TRUE`. +`/data` filesystem before starting Minecraft. If you want old mods to be removed as the `/mods` content is updated, then add `-e REMOVE_OLD_MODS=TRUE`. If you are running a `BUKKIT` distribution this will affect all files inside the `plugins/` directory. You can fine tune the removal process by specifing the `REMOVE_OLD_MODS_INCLUDE` and `REMOVE_OLD_MODS_EXCLUDE` variables. By default everything will be removed. You can also specify the `REMOVE_OLD_MODS_DEPTH` (default 16) variable to only delete files up to a certain level. + +> For example: `-e REMOVE_OLD_MODS=TRUE -e REMOVE_OLD_MODS_INCLUDE="*.jar" -e REMOVE_OLD_MODS_DEPTH=1` will remove all old jar files that are directly inside the `plugins/` or `mods/` directory. This works well if you want to have a common set of modules in a separate location, but still have multiple worlds with different server requirements in either persistent volumes or a downloadable archive. - - ### Replacing variables inside configs Sometimes you have mods or plugins that require configuration information that is only available at runtime. diff --git a/start-finalSetupModpack b/start-finalSetupModpack index 20adddab..7cfabefc 100644 --- a/start-finalSetupModpack +++ b/start-finalSetupModpack @@ -11,12 +11,16 @@ fi CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects} # Remove old mods/plugins -if [ "$REMOVE_OLD_MODS" = "TRUE" ]; then - if [ "$TYPE" = "SPIGOT" ]; then - rm -rf /data/plugins/* - else - rm -rf /data/mods/* - fi +if isTrue ${REMOVE_OLD_MODS}; then + remove_mods_dest="/data/mods" + case ${TYPE} in + SPIGOT|BUKKIT|PAPER) + remove_mods_dest="/data/plugins" + ;; + esac + + log "Removing old mods in $remove_mods_dest..." + find $remove_mods_dest -mindepth 1 -maxdepth ${REMOVE_OLD_MODS_DEPTH:-16} -wholename "${REMOVE_OLD_MODS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_MODS_EXCLUDE}" -delete fi # If supplied with a URL for a modpack (simple zip of jars), download it and unpack diff --git a/start-minecraftFinalSetup b/start-minecraftFinalSetup index c19a2a13..05f5251a 100644 --- a/start-minecraftFinalSetup +++ b/start-minecraftFinalSetup @@ -54,9 +54,6 @@ done if [ -d /mods ]; then log "Copying any mods over..." mkdir -p /data/mods - if isTrue "${REMOVE_OLD_MODS}"; then - rsyncArgs=(--delete) - fi rsync -a --out-format="update:%f:Last Modified %M" "${rsyncArgs[@]}" --prune-empty-dirs --update /mods /data fi From ca9f883352c10779a52b7fceca36aa25e46a0ce9 Mon Sep 17 00:00:00 2001 From: Silthus <755327+Silthus@users.noreply.github.com> Date: Tue, 15 Dec 2020 20:31:51 +0100 Subject: [PATCH 7/7] feat: add COPY_CONFIG_DEST option (#689) --- README.md | 4 ++++ start-minecraftFinalSetup | 15 +++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5a753475..5340d3ae 100644 --- a/README.md +++ b/README.md @@ -309,6 +309,10 @@ This works well if you want to have a common set of modules in a separate location, but still have multiple worlds with different server requirements in either persistent volumes or a downloadable archive. +You can specify the destination of the configs that are located inside the `/config` mount by setting the `COPY_CONFIG_DEST` variable. The configs are copied recursivly to the `/data/config` directory by default. If a file was updated directly inside the `/data/*` directoy and is newer than the file in the `/config/*` mount it will not be overriden. + +> For example: `-v ./config:/config -e COPY_CONFIG_DEST=/data` will allow you to copy over your `bukkit.yml` and so on directly into the server directory. + ### Replacing variables inside configs Sometimes you have mods or plugins that require configuration information that is only available at runtime. diff --git a/start-minecraftFinalSetup b/start-minecraftFinalSetup index 05f5251a..9528a405 100644 --- a/start-minecraftFinalSetup +++ b/start-minecraftFinalSetup @@ -2,6 +2,8 @@ . ${SCRIPTS:-/}start-utils +: ${COPY_CONFIG_DEST:="/data/config"} + if [ -n "$OPS" ]; then log "Setting/adding ops" rm -rf /data/ops.txt.converted @@ -57,14 +59,11 @@ if [ -d /mods ]; then rsync -a --out-format="update:%f:Last Modified %M" "${rsyncArgs[@]}" --prune-empty-dirs --update /mods /data fi -[ -d /data/config ] || mkdir /data/config -for c in /config/* -do - if [ -f "$c" ]; then - log Copying configuration $(basename "$c") - cp -rf "$c" /data/config - fi -done +if [ -d /config ]; then + log "Copying any configs from /config to $COPY_CONFIG_DEST" + mkdir -p $COPY_CONFIG_DEST + rsync -a --out-format="update:%f:Last Modified %M" "${rsyncArgs[@]}" --prune-empty-dirs --update /config/ $COPY_CONFIG_DEST +fi EXTRA_ARGS="" # Optional disable console