diff --git a/.github/workflows/build-multiarch.yml b/.github/workflows/build-multiarch.yml index b26e032d..f6119e2c 100644 --- a/.github/workflows/build-multiarch.yml +++ b/.github/workflows/build-multiarch.yml @@ -8,8 +8,6 @@ on: - java11* - java16* - java17* - - test/* - - fix/* tags: - "[0-9]+.[0-9]+.[0-9]+" - "[0-9]+.[0-9]+.[0-9]+-java8-multiarch" diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c619ca43..9069dbc7 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -3,13 +3,18 @@ name: Validate PR on: pull_request: branches: [ master ] + types: [assigned, opened, synchronize, labeled] + paths-ignore: + - "*.md" + - "docs/**" + - "examples/**" env: IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }} jobs: test: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2.4.0 @@ -25,8 +30,34 @@ jobs: tags: ${{ env.IMAGE_TO_TEST }} load: true cache-from: type=gha - cache-to: type=gha,mode=max - name: Run tests run: | tests/test.sh + + - name: Gather Docker metadata + if: contains(github.event.pull_request.labels.*.name, 'ci/push-image') + id: meta + uses: docker/metadata-action@v3 + with: + images: | + itzg/minecraft-server + + - name: Login to DockerHub + if: contains(github.event.pull_request.labels.*.name, 'ci/push-image') + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Push + if: contains(github.event.pull_request.labels.*.name, 'ci/push-image') + uses: docker/build-push-action@v2.7.0 + with: + context: . + platforms: linux/amd64,linux/arm/v7,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + pull: true + push: true + cache-from: type=gha + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index 574e0d91..d7b092b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ +.vscode /data/ /.idea/ *.iml -/gh-md-toc \ No newline at end of file +*.zip +/gh-md-toc diff --git a/Dockerfile b/Dockerfile index 2f41656b..c59ad182 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,23 +5,23 @@ LABEL org.opencontainers.image.authors="Geoff Bourne " RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive \ apt-get install -y \ - imagemagick \ - gosu \ - sudo \ - net-tools \ - iputils-ping \ - curl wget \ - git \ - jq \ - dos2unix \ - mysql-client \ - tzdata \ - rsync \ - nano \ - unzip \ - knockd \ - ttf-dejavu \ - && apt-get clean + imagemagick \ + gosu \ + sudo \ + net-tools \ + iputils-ping \ + curl \ + git \ + jq \ + dos2unix \ + mysql-client \ + tzdata \ + rsync \ + nano \ + unzip \ + knockd \ + ttf-dejavu \ + && apt-get clean RUN addgroup --gid 1000 minecraft \ && adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft @@ -45,26 +45,26 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ - --var version=1.5.1 --var app=rcon-cli --file {{.app}} \ - --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz + --var version=1.5.1 --var app=rcon-cli --file {{.app}} \ + --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ - --var version=0.10.3 --var app=mc-monitor --file {{.app}} \ - --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz + --var version=0.10.3 --var app=mc-monitor --file {{.app}} \ + --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ - --var version=1.8.0 --var app=mc-server-runner --file {{.app}} \ - --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz + --var version=1.8.0 --var app=mc-server-runner --file {{.app}} \ + --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \ - --var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \ - --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz + --var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \ + --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz ARG MC_HELPER_VERSION=1.11.0 ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/v${MC_HELPER_VERSION} RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \ - | tar -C /usr/share -zxf - \ - && ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin + | tar -C /usr/share -zxf - \ + && ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin VOLUME ["/data"] WORKDIR /data diff --git a/README.md b/README.md index 2d2465ff..78056ac1 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ By default, the container will download the latest version of the "vanilla" [Min **TABLE OF CONTENTS** + * [Mitigated Log4jShell Vulnerability](#mitigated-log4jshell-vulnerability) * [Looking for a Bedrock Dedicated Server](#looking-for-a-bedrock-dedicated-server) * [Interacting with the server](#interacting-with-the-server) * [Data Directory](#data-directory) @@ -45,6 +46,7 @@ By default, the container will download the latest version of the "vanilla" [Min * [Running a Bukkit/Spigot server](#running-a-bukkitspigot-server) * [Running a Paper server](#running-a-paper-server) * [Running an Airplane server](#running-an-airplane-server) + * [Running a Pufferfish server](#running-a-pufferfish-server) * [Running a Purpur server](#running-a-purpur-server) * [Running a Magma server](#running-a-magma-server) * [Running a Mohist server](#running-a-mohist-server) @@ -74,6 +76,7 @@ By default, the container will download the latest version of the "vanilla" [Min * [Cloning world from a container path](#cloning-world-from-a-container-path) * [Overwrite world on start](#overwrite-world-on-start) * [Datapacks](#datapacks) + * [VanillaTweaks](#vanillatweaks) * [Server configuration](#server-configuration) * [Message of the Day](#message-of-the-day) * [Difficulty](#difficulty) @@ -136,10 +139,14 @@ By default, the container will download the latest version of the "vanilla" [Min * [Running on RaspberryPi](#running-on-raspberrypi) * [Contributing](#contributing) - + +## Mitigated Log4jShell Vulnerability + +**Please ensure you have pulled the latest image** since [all official mitigations](https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition) are automatically applied by the container startup process. + ## Looking for a Bedrock Dedicated Server For Minecraft clients running on consoles, mobile, or native Windows, you'll need to @@ -285,6 +292,7 @@ When using the image `itzg:/minecraft-server` without a tag, the `latest` image | java11-openj9 | 11 | Debian | OpenJ9 | amd64 | | java16-openj9 | 16 | Debian | OpenJ9 | amd64 | | java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 | +| java17-openj9 | 17 | Debian | OpenJ9 | amd64 | For example, to use Java version 8 on any supported architecture: @@ -479,6 +487,18 @@ Extra variables: - `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded - `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the [Flare](https://blog.airplane.gg/flare) profiler +### Running a Pufferfish server + +A [Pufferfish](https://github.com/pufferfish-gg/Pufferfish) server, which is "a highly optimized Paper fork designed for large servers requiring both maximum performance, stability, and "enterprise" features." + + -e TYPE=PUFFERFISH + +> NOTE: The `VERSION` variable is used to select a Pufferfish branch to download from. The available options are "LATEST" and "1.18" + +Extra variables: +- `PUFFERFISH_BUILD=lastSuccessfulBuild` : set a specific Pufferfish build to use +- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded + ### Running a Purpur server A [Purpur](https://purpur.pl3x.net/) server, which is "drop-in replacement for Paper servers designed for configurability, new fun and exciting gameplay features, and performance built on top of Airplane." @@ -804,6 +824,47 @@ Datapacks can be installed in a similar manner to mods/plugins. There are many e * `REMOVE_OLD_DATAPACKS_EXCLUDE` Datapacks will be placed in `/data/$LEVEL/datapacks` +### VanillaTweaks + +VanillaTweaks datapacks can be installed with a share code from the website UI **OR** a json file to specify packs to download and install. + +Accepted Parameters: + +- `VANILLATWEAKS_FILE` +- `VANILLATWEAKS_SHARECODE` +- `REMOVE_OLD_VANILLATWEAKS` +- `REMOVE_OLD_VANILLATWEAKS_DEPTH` +- `REMOVE_OLD_VANILLATWEAKS_INCLUDE` +- `REMOVE_OLD_VANILLATWEAKS_EXCLUDE` + +Example of expected Vanillatweaks sharecode: + +```yaml +VANILLATWEAKS_SHARECODE: MGr52E +``` + +Example of expected Vanillatweaks file format: + +```json +{ + "version": "1.18", + "packs": { + "survival": [ + "graves", + "multiplayer sleep", + "afk display", + "armor statues", + "unlock all recipes", + "fast leaf decay", + "coordinates hud" + ], + "items": ["armored elytra"] + } +} +``` + +Datapacks will be placed in `/data/$LEVEL/datapacks` + ## Server configuration By default, the server configuration will be created and set based on the following environment variables, but only the first time the server is started. If the `server.properties` file already exists, the values in them will not be changed. @@ -1400,10 +1461,6 @@ To enable remote JMX, such as for profiling with VisualVM or JMC, add the enviro When `MEMORY` is greater than or equal to 12G, then the Aikar flags will be adjusted according to the article. -Large page support can also be enabled by adding - - -e USE_LARGE_PAGES=true - ### HTTP Proxy You may configure the use of an HTTP/HTTPS proxy by passing the proxy's URL via the `PROXY` @@ -1459,6 +1516,8 @@ Enable the Autopause functionality by setting: Autopause is not compatible with `EXEC_DIRECTLY=true` and the two cannot be set together. +> When configuring kubernetes readiness/liveness health checks with auto-pause enabled, be sure to reference the `mc-health` wrapper script rather than `mc-status` directly. + The following environment variables define the behaviour of auto-pausing: * `AUTOPAUSE_TIMEOUT_EST`, default `3600` (seconds) describes the time between the last client disconnect and the pausing of the process (read as timeout established) diff --git a/examples/docker-compose-generic-pack.yml b/examples/docker-compose-generic-pack.yml index 314a8083..dfb2d152 100644 --- a/examples/docker-compose-generic-pack.yml +++ b/examples/docker-compose-generic-pack.yml @@ -13,6 +13,7 @@ services: VERSION: ${VERSION:-1.17.1} FORGEVERSION: ${FORGEVERSION:-37.0.90} GENERIC_PACK: /modpacks/${MODPACK:-Server-Files-0.0.21.zip} + REMOVE_OLD_MODS: "${REMOVE_OLD_MODS:-false}" ports: - "25565:25565" diff --git a/examples/vanilla-tweaks/docker-compose.yml b/examples/vanilla-tweaks/docker-compose.yml new file mode 100644 index 00000000..6adf5dce --- /dev/null +++ b/examples/vanilla-tweaks/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3.3" + +services: + vanillatweaks_file: + restart: "no" + image: itzg/minecraft-server + ports: + - "25565:25565/tcp" + environment: + EULA: "TRUE" + VERSION: ${MINECRAFT_VERSION:-LATEST} + VANILLATWEAKS_FILE: /config/vanillatweaks-datapacks.json + REMOVE_OLD_VANILLATWEAKS: "TRUE" + volumes: + - data:/data + - ./vanillatweaks-datapacks.json:/config/vanillatweaks-datapacks.json:ro + vanillatweaks_sharecode: + # port is set to 25566 to not conflict with vanillatweaks_file example + ports: + - "25566:25565/tcp" + restart: "no" + image: itzg/minecraft-server + environment: + EULA: "TRUE" + VERSION: ${MINECRAFT_VERSION:-LATEST} + VANILLATWEAKS_SHARECODE: MGr52E + REMOVE_OLD_VANILLATWEAKS: "TRUE" diff --git a/examples/vanilla-tweaks/vanillatweaks-datapacks.json b/examples/vanilla-tweaks/vanillatweaks-datapacks.json new file mode 100644 index 00000000..aa19970d --- /dev/null +++ b/examples/vanilla-tweaks/vanillatweaks-datapacks.json @@ -0,0 +1,15 @@ +{ + "version": "1.18", + "packs": { + "survival": [ + "graves", + "multiplayer sleep", + "afk display", + "armor statues", + "unlock all recipes", + "fast leaf decay", + "coordinates hud" + ], + "items": ["armored elytra"] + } +} diff --git a/scripts/start-configuration b/scripts/start-configuration index 13203302..204260a7 100755 --- a/scripts/start-configuration +++ b/scripts/start-configuration @@ -171,6 +171,10 @@ case "${TYPE^^}" in exec ${SCRIPTS:-/}start-deployAirplane "$@" ;; + PUFFERFISH) + exec ${SCRIPTS:-/}start-deployPufferfish "$@" + ;; + CANYON) exec ${SCRIPTS:-/}start-deployCanyon "$@" ;; @@ -187,7 +191,7 @@ case "${TYPE^^}" in log "Invalid type: '$TYPE'" log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only)," log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM," - log " MAGMA, MOHIST, CATSERVER, AIRPLANE, CANYON, LIMBO, CRUCIBLE" + log " MAGMA, MOHIST, CATSERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE" exit 1 ;; diff --git a/scripts/start-deployAirplane b/scripts/start-deployAirplane index 05e33202..601aeb67 100755 --- a/scripts/start-deployAirplane +++ b/scripts/start-deployAirplane @@ -14,7 +14,7 @@ fi : ${AIRPLANE_BUILD:=lastSuccessfulBuild} : ${AIRPLANE_TYPE:=airplane} -if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.17" ]; then +if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.17" ]; then AIRPLANE_BRANCH="1.17" fi @@ -36,8 +36,7 @@ done if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then downloadUrl="https://ci.tivy.ca/job/Airplane-${AIRPLANE_BRANCH}/${AIRPLANE_BUILD}/artifact/launcher-${AIRPLANE_TYPE}.jar" log "Downloading Airplane from $downloadUrl ..." - curl -fsSL -o "$SERVER" "$downloadUrl" - if [ ! -f "$SERVER" ]; then + if ! get -o "$SERVER" "$downloadUrl"; then log "ERROR: failed to download from $downloadUrl (status=$?)" exit 3 fi diff --git a/scripts/start-deployCF b/scripts/start-deployCF index c00c1dcf..ff2a72e8 100755 --- a/scripts/start-deployCF +++ b/scripts/start-deployCF @@ -35,11 +35,37 @@ FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD} log "Looking for Feed-The-Beast / CurseForge server modpack." requireVar FTB_SERVER_MOD -if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then - if ! [ -f "${FTB_SERVER_MOD}" ]; then - log "ERROR unable to find requested modpack file ${FTB_SERVER_MOD}" - exit 2 +downloadModpack() { + srv_modpack=${FTB_SERVER_MOD} + if isURL "${srv_modpack}"; then + log "Downloading modpack from ${srv_modpack}..." + if ! srv_modpack=$(get -o /data --output-filename --skip-existing "${srv_modpack}"); then + log "ERROR: failed to download modpack" + exit 1 + fi fi + if [[ "${srv_modpack:0:5}" == "data/" ]]; then + # Prepend with "/" + srv_modpack="/${srv_modpack}" + fi + if [[ ! "${srv_modpack:0:1}" == "/" ]]; then + # If not an absolute path, assume file is in "/data" + srv_modpack=/data/${srv_modpack} + fi + if [[ ! -f "${srv_modpack}" ]]; then + log "FTB server modpack ${srv_modpack} not found." + exit 2 + fi + if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then + log "FTB server modpack ${srv_modpack} is not a zip archive." + log "Please set FTB_SERVER_MOD to a file with a .zip extension." + exit 2 + fi + FTB_SERVER_MOD=${srv_modpack} +} + +if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then + downloadModpack needsInstall=true installMarker=/data/.curseforge-installed @@ -47,7 +73,7 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then if [ "$(cat $installMarker)" != "${FTB_SERVER_MOD}" ]; then log "Upgrading modpack" - serverJar=$(find "${FTB_BASE_DIR}" -not -name "forge*installer.jar" -name "forge*.jar") + serverJar=$(find "${FTB_BASE_DIR}" -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print) if [[ "${serverJar}" ]]; then rm -rf "$(dirname "${serverJar}")"/{mods,*.jar,libraries,resources,scripts,config} fi @@ -132,32 +158,9 @@ fi # also check for the start script rather than just the folder # this allows saving just the world separate from the rest of the data directory if [[ $startScriptCount = 0 ]]; then + downloadModpack srv_modpack=${FTB_SERVER_MOD} - if isURL "${srv_modpack}"; then - log "Downloading modpack from ${srv_modpack}..." - if ! srv_modpack=$(get -o /data --output-filename --skip-existing "${srv_modpack}"); then - log "ERROR: failed to download modpack" - exit 1 - fi - fi - if [[ "${srv_modpack:0:5}" == "data/" ]]; then - # Prepend with "/" - srv_modpack="/${srv_modpack}" - fi - if [[ ! "${srv_modpack:0:1}" == "/" ]]; then - # If not an absolute path, assume file is in "/data" - srv_modpack=/data/${srv_modpack} - fi - if [[ ! -f "${srv_modpack}" ]]; then - log "FTB server modpack ${srv_modpack} not found." - exit 2 - fi - if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then - log "FTB server modpack ${srv_modpack} is not a zip archive." - log "Please set FTB_SERVER_MOD to a file with a .zip extension." - exit 2 - fi - + log "Unpacking FTB server modpack ${srv_modpack} ..." mkdir -p "${FTB_BASE_DIR}" unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}' diff --git a/scripts/start-deployPufferfish b/scripts/start-deployPufferfish new file mode 100755 index 00000000..02666114 --- /dev/null +++ b/scripts/start-deployPufferfish @@ -0,0 +1,46 @@ +#!/bin/bash + +. ${SCRIPTS:-/}start-utils +set -euo pipefail +isDebugging && set -x + +IFS=$'\n\t' + +if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.18" ] ; then + log "ERROR: Pufferfish server type only supports VERSION=LATEST, VERSION=1.18. Note that these are branches, not #.#.# versions." + exit 1 +fi + +: ${PUFFERFISH_BUILD:=lastSuccessfulBuild} + +if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.18" ]; then + PUFFERFISH_BRANCH="1.18" + PUFFERFISH_VERSION="1.18.1-R0.1" +fi + +log "Using Pufferfish-${PUFFERFISH_BRANCH} branch" + +export SERVER=pufferfish-${PUFFERFISH_BRANCH}-${PUFFERFISH_BUILD}.jar + +log "Removing old Pufferfish versions ..." +shopt -s nullglob +for f in pufferfish-*.jar; do + [[ $f != $SERVER ]] && rm $f +done + +if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then + artifact="build/libs/pufferfish-paperclip-${PUFFERFISH_VERSION}-SNAPSHOT-reobf.jar" + downloadUrl="https://ci.pufferfish.host/job/Pufferfish-${PUFFERFISH_BRANCH}/${PUFFERFISH_BUILD}/artifact/${artifact}" + log "Downloading Pufferfish from $downloadUrl ..." + if ! get -o "$SERVER" "$downloadUrl"; then + log "ERROR: failed to download from $downloadUrl (status=$?)" + exit 3 + fi +fi + +# Normalize on Spigot for later operations +export TYPE=SPIGOT +export FAMILY=SPIGOT +export SKIP_LOG4J_CONFIG=true + +exec ${SCRIPTS:-/}start-spiget "$@" diff --git a/scripts/start-deployPurpur b/scripts/start-deployPurpur index e8b38424..de3234b3 100755 --- a/scripts/start-deployPurpur +++ b/scripts/start-deployPurpur @@ -2,7 +2,8 @@ set -euo pipefail IFS=$'\n\t' -. ${SCRIPTS:-/}start-utils +# shellcheck source=start-utils +. "${SCRIPTS:-/}start-utils" isDebugging && set -x : ${VANILLA_VERSION:?} @@ -10,12 +11,10 @@ isDebugging && set -x : ${FORCE_REDOWNLOAD:=false} if [[ ${PURPUR_BUILD} == LATEST ]]; then - PURPUR_BUILD=$(curl -fsSL "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}" | - jq -r '.builds.latest' || echo "") - if [[ -z ${PURPUR_BUILD} ]]; then + if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}." log " Please check if a download is available at https://purpur.pl3x.net/downloads/" - exit 3 + exit 1 fi fi @@ -24,7 +23,7 @@ export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar" if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download" log "Downloading Purpur from $downloadUrl ..." - if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then + if ! get -o "$SERVER" "$downloadUrl"; then log "ERROR: failed to download from $downloadUrl (status=$?)" exit 3 fi @@ -35,4 +34,4 @@ export TYPE=SPIGOT export FAMILY=SPIGOT export SKIP_LOG4J_CONFIG=true -exec ${SCRIPTS:-/}start-spiget "$@" +exec "${SCRIPTS:-/}start-spiget" "$@" diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 8e684d97..f0d6b5fb 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -236,12 +236,6 @@ if isTrue "${USE_AIKAR_FLAGS}"; then " fi -if isTrue "${USE_LARGE_PAGES}"; then - JVM_XX_OPTS="${JVM_XX_OPTS} - -XX:+UseLargePagesInMetaspace - " -fi - if isTrue "${USE_FLARE_FLAGS}"; then JVM_XX_OPTS="${JVM_XX_OPTS} -XX:+UnlockDiagnosticVMOptions diff --git a/scripts/start-setupModpack b/scripts/start-setupModpack index 02036b46..37bbaf78 100755 --- a/scripts/start-setupModpack +++ b/scripts/start-setupModpack @@ -6,6 +6,7 @@ set -e -o pipefail : "${MODS_FILE:=}" : "${REMOVE_OLD_MODS_DEPTH:=1} " : "${REMOVE_OLD_MODS_INCLUDE:=*.jar}" +sum_file=/data/.generic_pack.sum # shellcheck source=start-utils . "${SCRIPTS:-/}start-utils" @@ -18,6 +19,7 @@ CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects} if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then removeOldMods /data/mods removeOldMods /data/plugins + rm -f "$sum_file" fi # If packwiz url passed, bootstrap packwiz and update mods before other modpack processing @@ -204,7 +206,6 @@ if [[ "${GENERIC_PACKS}" ]]; then fi done - sum_file=/data/.generic_pack.sum isDebugging && [ -f "$sum_file}" ] && cat "$sum_file" if ! sha256sum -c "${sum_file}" --status 2> /dev/null; then base_dir=/tmp/generic_pack_base diff --git a/scripts/start-setupVanillaTweaks b/scripts/start-setupVanillaTweaks new file mode 100644 index 00000000..4da67423 --- /dev/null +++ b/scripts/start-setupVanillaTweaks @@ -0,0 +1,84 @@ +#!/bin/bash + +set -e -o pipefail + +: "${REMOVE_OLD_VANILLATWEAKS:=false}" +: "${VANILLATWEAKS_FILE:=}" +: "${VANILLATWEAKS_SHARECODE:=}" +: "${REMOVE_OLD_VANILLATWEAKS_DEPTH:=1} " +: "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:=*.zip}" + +# shellcheck source=start-utils +. "${SCRIPTS:-/}start-utils" +isDebugging && set -x + +out_dir=/data/${LEVEL:-world}/datapacks + +# Remove old VANILLATWEAKS +if isTrue "${REMOVE_OLD_VANILLATWEAKS}" && [ -z "${VANILLATWEAKS_FILE}" ]; then + if [ -d "$out_dir" ]; then + find "$out_dir" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete + fi +fi + +# Example: VANILLATWEAKS_SHARECODE=MGr52E +# Code generated from the UI website, typically a alphanumeric 6 digit code. +if [[ "$VANILLATWEAKS_SHARECODE" ]]; then + VANILLATWEAKS_FILE=/tmp/vanillatweaksfile.json + SHARECODE_LOOKUP_URL="https://vanillatweaks.net/assets/server/sharecode.php?code=${VANILLATWEAKS_SHARECODE}" + curl -f $SHARECODE_LOOKUP_URL -o $VANILLATWEAKS_FILE + if [ ! -f "$VANILLATWEAKS_FILE" ]; then + log "ERROR: Unable to use share code provided to retreive vanillatweaks file" + exit 2 + fi +fi + +# Use vanillatweaks file to specify VT and datapacks +if [[ "$VANILLATWEAKS_FILE" ]]; then + if [ ! -f "$VANILLATWEAKS_FILE" ]; then + log "ERROR: given VANILLATWEAKS_FILE file does not exist" + exit 2 + fi + + PACKS=$(jq -jc '.packs' $VANILLATWEAKS_FILE) + if [ ! "$PACKS" ]; then + log "ERROR: unable to retrieve packs from $VANILLATWEAKS_FILE" + exit 2 + fi + + VT_VERSION=$(jq -jc '.version' $VANILLATWEAKS_FILE) + if [ ! "$VT_VERSION" ]; then + log "ERROR: unable to retrieve version from $VANILLATWEAKS_FILE" + exit 2 + fi +fi + +# Download and unzip packs +if [[ "$PACKS" ]] && [[ "$VT_VERSION" ]]; then + VT_ZIPDATA_URL=https://vanillatweaks.net/assets/server/zipdatapacks.php + DOWNLOAD_URL=$(curl -X POST -F "packs=${PACKS}" -F "version=${VT_VERSION}" $VT_ZIPDATA_URL | jq -r '.link') + if [ ! "$DOWNLOAD_URL" ]; then + log "ERROR: unable to retrieve DOWNLOAD_URL from vanillatweaks.net!" + exit 2 + fi + + TEMPZIP=/tmp/vanillatweaks.zip + if ! get -o $TEMPZIP "https://vanillatweaks.net${DOWNLOAD_URL}"; then + log "ERROR: failed to download from ${DOWNLOAD_URL}" + exit 2 + fi + + mkdir -p "$out_dir" + if ! unzip -o -d "$out_dir" $TEMPZIP; then + log "ERROR: failed to unzip the ${PACKS} from ${$TEMPZIP}" + fi + + # clean up files time! + rm -f $TEMPZIP + # cleans up temp vanilla tweaks file download to get stored packs + if [[ "$VANILLATWEAKS_SHARECODE" ]]; then + rm -f $VANILLATWEAKS_FILE + fi +fi + +exec "${SCRIPTS:-/}start-setupDatapack" "$@" diff --git a/scripts/start-setupWorld b/scripts/start-setupWorld index 3484b46d..c4dad94f 100755 --- a/scripts/start-setupWorld +++ b/scripts/start-setupWorld @@ -69,4 +69,4 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] ); fi fi -exec "${SCRIPTS:-/}start-setupDatapack" "$@" +exec "${SCRIPTS:-/}start-setupVanillaTweaks" "$@" diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index f3a0bb0a..61c6f289 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3.8" +version: "3" services: monitor: diff --git a/tests/generic-packs/docker-compose.test.yml b/tests/generic-packs/docker-compose.yml similarity index 75% rename from tests/generic-packs/docker-compose.test.yml rename to tests/generic-packs/docker-compose.yml index 210c54dd..46dd8344 100644 --- a/tests/generic-packs/docker-compose.test.yml +++ b/tests/generic-packs/docker-compose.yml @@ -2,14 +2,13 @@ version: "3" services: mc: - image: itzg/minecraft-server + image: ${IMAGE_TO_TEST:-itzg/minecraft-server} environment: EULA: "true" + SETUP_ONLY: "TRUE" GENERIC_PACKS: https://github.com/itzg/mc-image-helper/releases/download/v1.9.5/mc-image-helper-1.9.5.zip,/packs/testing.zip - DEBUG: "true" volumes: - ./packs:/packs - data:/data - volumes: - data: {} \ No newline at end of file + data: {} diff --git a/tests/test.sh b/tests/test.sh index 9db35dec..661499be 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -1,22 +1,56 @@ #!/bin/bash +# go to script root directory cd "$(dirname "$0")" || exit 1 -failed=false - +# compose down function for reuse down() { - docker-compose down -v + docker-compose down -v --remove-orphans } -docker-compose run monitor || failed=true -echo " -Result: failed=$failed" +fullMinecraftUpTest(){ + name=$1 + failed=false + # run the monitor to validate the Minecraft image is healthy + docker-compose run monitor || failed=true + echo "${name} Result: failed=$failed" -if $failed; then - docker-compose logs mc + # docker-compose logs outputs messages from the specified container + if $failed; then + docker-compose logs mc + down + exit 2 + fi down - exit 1 -else - down -fi +} +setupOnlyMinecraftTest(){ + folder=$1 + failed=false + # run the monitor to validate the Minecraft image is healthy + docker-compose --log-level ERROR up --quiet-pull --exit-code-from mc 2>/dev/null || failed=true + echo "${folder} Result: failed=$failed" + + # docker-compose logs outputs messages from the specified container + if $failed; then + docker-compose logs mc + down + cd .. + exit 2 + fi + down + cd .. +} + +# run tests on base docker compose and validate mc service with monitor +fullMinecraftUpTest 'Full Vanilla Test' + +# go through each folder to test builds +FOLDERS=$(ls) +for folder in $FOLDERS; do + # If folder is a directory + if [ -d "$folder" ]; then + cd "$folder" + setupOnlyMinecraftTest $folder + fi +done diff --git a/tests/vanillatweaks_file/docker-compose.yml b/tests/vanillatweaks_file/docker-compose.yml new file mode 100644 index 00000000..b33292ee --- /dev/null +++ b/tests/vanillatweaks_file/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3" + +services: + mc: + restart: "no" + image: ${IMAGE_TO_TEST:-itzg/minecraft-server} + environment: + EULA: "TRUE" + SETUP_ONLY: "TRUE" + VERSION: ${MINECRAFT_VERSION:-LATEST} + VANILLATWEAKS_FILE: /config/vanillatweaks-datapacks.json + REMOVE_OLD_VANILLATWEAKS: "TRUE" + volumes: + - ./vanillatweaks-datapacks.json:/config/vanillatweaks-datapacks.json:ro diff --git a/tests/vanillatweaks_file/vanillatweaks-datapacks.json b/tests/vanillatweaks_file/vanillatweaks-datapacks.json new file mode 100644 index 00000000..80604c49 --- /dev/null +++ b/tests/vanillatweaks_file/vanillatweaks-datapacks.json @@ -0,0 +1,17 @@ +{ + "type": "datapacks", + "version": "1.18", + "packs": { + "survival": [ + "graves", + "multiplayer sleep", + "afk display", + "armor statues", + "unlock all recipes", + "fast leaf decay", + "coordinates hud" + ], + "items": ["armored elytra"] + }, + "result": "ok" +} diff --git a/tests/vanillatweaks_sharecode/docker-compose.yml b/tests/vanillatweaks_sharecode/docker-compose.yml new file mode 100644 index 00000000..66eac5b5 --- /dev/null +++ b/tests/vanillatweaks_sharecode/docker-compose.yml @@ -0,0 +1,12 @@ +version: "3" + +services: + mc: + restart: "no" + image: ${IMAGE_TO_TEST:-itzg/minecraft-server} + environment: + EULA: "TRUE" + SETUP_ONLY: "TRUE" + VERSION: ${MINECRAFT_VERSION:-LATEST} + VANILLATWEAKS_SHARECODE: MGr52E + REMOVE_OLD_VANILLATWEAKS: "TRUE"