diff --git a/.github/workflows/build-multiarch.yml b/.github/workflows/build-multiarch.yml index 206fcee4..de1eecde 100644 --- a/.github/workflows/build-multiarch.yml +++ b/.github/workflows/build-multiarch.yml @@ -3,29 +3,61 @@ on: push: branches: - master - - java8-multiarch - - java8-openj9 - - java11* - - java16* - - java17* - test/** tags: - "[0-9]+.[0-9]+.[0-9]+" - - "[0-9]+.[0-9]+.[0-9]+-java8-multiarch" - - "[0-9]+.[0-9]+.[0-9]+-java8-openj9" - - "[0-9]+.[0-9]+.[0-9]+-java11*" - - "[0-9]+.[0-9]+.[0-9]+-java16*" + - "[0-9]+.[0-9]+.[0-9]+-*" paths-ignore: - "*.md" - "docs/**" - "examples/**" -env: - IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }} - jobs: build: if: github.repository == 'itzg/docker-minecraft-server' + strategy: + fail-fast: false + matrix: + variant: + - java17 + - java17-openj9 + - java8-multiarch + - java8-openj9 + - java11 + - java11-openj9 + include: + - variant: java17 + baseImage: eclipse-temurin:17 + tagPrefix: java17- + platforms: linux/amd64,linux/arm/v7,linux/arm64 + mcVersion: LATEST + - variant: java17-openj9 + baseImage: ibm-semeru-runtimes:open-17-jdk + tagPrefix: java17-openj9- + platforms: linux/amd64,linux/arm64 + mcVersion: LATEST + - variant: java8-multiarch + baseImage: eclipse-temurin:8-jdk + tagPrefix: java8- + platforms: linux/amd64,linux/arm/v7,linux/arm64 + mcVersion: 1.12.2 + - variant: java8-openj9 + baseImage: ibm-semeru-runtimes:open-8-jdk + tagPrefix: java8-openj9- + platforms: linux/amd64,linux/arm64 + mcVersion: 1.12.2 + - variant: java11 + baseImage: adoptopenjdk:11-jdk-hotspot + tagPrefix: java11- + platforms: linux/amd64,linux/arm/v7,linux/arm64 + mcVersion: 1.16.5 + - variant: java11-openj9 + baseImage: ibm-semeru-runtimes:open-11-jdk + tagPrefix: java11-openj9- + platforms: linux/amd64,linux/arm64 + mcVersion: 1.16.5 + env: + IMAGE_TO_TEST: itzg/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }} runs-on: ubuntu-20.04 steps: - name: Checkout @@ -38,10 +70,13 @@ jobs: images: | itzg/minecraft-server tags: | - type=ref,event=branch - type=ref,event=tag + type=ref,event=tag,enable=${{ matrix.variant == 'java17' }} + type=ref,event=tag,prefix=${{ matrix.variant }}- + type=raw,value=${{ matrix.variant }} flavor: | - latest=${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} + latest=${{ matrix.variant == 'java17' }} + labels: | + org.opencontainers.image.authors=Geoff Bourne - name: Setup Docker Buildx uses: docker/setup-buildx-action@v1 @@ -56,38 +91,37 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build for test - uses: docker/build-push-action@v2.7.0 - if: github.ref_name == 'master' || startsWith(github.ref_name, 'test/') + uses: docker/build-push-action@v2.8.0 with: - context: . platforms: linux/amd64 tags: ${{ env.IMAGE_TO_TEST }} # ensure latest base image is used pull: true + # load into daemon for test usage in next step load: true push: false - cache-from: type=gha + build-args: | + BASE_IMAGE=${{ matrix.baseImage }} + cache-from: type=gha,scope=${{ matrix.variant }} # no cache-to to avoid cross-cache update from next build step - name: Run tests - # It is assumed that image variants are merged from master and tested there - if: github.ref_name == 'master' || startsWith(github.ref_name, 'test/') + env: + MINECRAFT_VERSION: ${{ matrix.mcVersion }} run: | tests/test.sh - name: Build and push id: docker_build - uses: docker/build-push-action@v2.7.0 + uses: docker/build-push-action@v2.8.0 with: - context: . - platforms: linux/amd64,linux/arm/v7,linux/arm64 - push: true + platforms: ${{ matrix.platforms }} + push: ${{ github.ref_name == 'master' }} tags: ${{ steps.meta.outputs.tags }} # ensure latest base image is used pull: true - cache-from: type=gha - cache-to: type=gha,mode=max labels: ${{ steps.meta.outputs.labels }} - - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} + build-args: | + BASE_IMAGE=${{ matrix.baseImage }} + cache-from: type=gha,scope=${{ matrix.variant }} + cache-to: type=gha,mode=max,scope=${{ matrix.variant }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ec5052f..fb720843 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: uses: docker/setup-buildx-action@v1 - name: Build - uses: docker/build-push-action@v2.7.0 + uses: docker/build-push-action@v2.8.0 with: context: . platforms: linux/amd64 @@ -36,7 +36,7 @@ jobs: cache-from: type=gha - name: Run Setup Only Tests - run: sh tests/setuponlytests/test.sh + run: bash tests/setuponlytests/test.sh # - name: Run Full Minecraft Service Tests # run: | diff --git a/.github/workflows/issue-label.yml b/.github/workflows/issue-label.yml index 4d4df210..cc4f3b56 100644 --- a/.github/workflows/issue-label.yml +++ b/.github/workflows/issue-label.yml @@ -3,7 +3,7 @@ on: types: [labeled] env: - DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + DISCORD_WEBHOOK: ${{ secrets.DISCORD_ISSUES_WEBHOOK }} jobs: labelNotify: @@ -11,7 +11,13 @@ jobs: timeout-minutes: 5 steps: - name: notify - if: github.event.label.name == 'enhancement' || github.event.label.name == 'bug' + if: > + github.event.label.name == 'enhancement' + || github.event.label.name == 'bug' + || github.event.label.name == 'help wanted' + || github.event.label.name == 'priority/high' + || github.event.label.name == 'question' + || github.event.label.name == 'status/waiting on upstream' uses: Ilshidur/action-discord@master with: - args: "[${{ github.event.issue.title }}](<${{ github.event.issue.html_url }}>) added `${{ github.event.label.name }}` label" + args: "[${{ github.event.issue.title }} (#${{ github.event.issue.number }})](<${{ github.event.issue.html_url }}>) added `${{ github.event.label.name }}` label" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d9202a04..08604dc5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,16 +4,9 @@ on: push: branches: - java8 - - openj9 - - openj9-11 - - adopt11 - test/alpine/* tags: - "[0-9]+.[0-9]+.[0-9]+-java8" - - "[0-9]+.[0-9]+.[0-9]+-openj9" - - "[0-9]+.[0-9]+.[0-9]+-openj9-11" - - "[0-9]+.[0-9]+.[0-9]+-openj9-nightly" - - "[0-9]+.[0-9]+.[0-9]+-adopt11" env: IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }} @@ -53,7 +46,7 @@ jobs: password: ${{ secrets.DOCKER_PASSWORD }} - name: Build for test - uses: docker/build-push-action@v2.7.0 + uses: docker/build-push-action@v2.8.0 if: github.ref_name == 'java8' with: context: . @@ -75,7 +68,7 @@ jobs: - name: Build and push id: docker_build - uses: docker/build-push-action@v2.7.0 + uses: docker/build-push-action@v2.8.0 with: context: . file: ./Dockerfile @@ -92,6 +85,4 @@ jobs: org.opencontainers.image.version=${{ steps.prep.outputs.version }} org.opencontainers.image.source=https://github.com/itzg/docker-minecraft-server org.opencontainers.image.revision=${{ github.sha }} - - - name: Image digest - run: echo ${{ steps.docker_build.outputs.digest }} + org.opencontainers.image.authors=Geoff Bourne diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 79521468..b5580287 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -24,7 +24,7 @@ jobs: uses: docker/setup-buildx-action@v1 - name: Build - uses: docker/build-push-action@v2.7.0 + uses: docker/build-push-action@v2.8.0 with: context: . platforms: linux/amd64 @@ -53,7 +53,7 @@ jobs: - name: Push if: contains(github.event.pull_request.labels.*.name, 'ci/push-image') - uses: docker/build-push-action@v2.7.0 + uses: docker/build-push-action@v2.8.0 with: context: . platforms: linux/amd64,linux/arm/v7,linux/arm64 diff --git a/Dockerfile b/Dockerfile index 9c4fbb20..481e3331 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,5 @@ -FROM openjdk:8-jdk-alpine - -LABEL org.opencontainers.image.authors="Geoff Bourne " +ARG BASE_IMAGE=openjdk:8-jdk-alpine +FROM ${BASE_IMAGE} RUN apk add --no-cache -U \ openssl \ @@ -62,7 +61,7 @@ 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 -ARG MC_HELPER_VERSION=1.16.0 +ARG MC_HELPER_VERSION=1.16.2 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 - \ diff --git a/README.md b/README.md index b29be7ff..a52e05cd 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ By default, the container will download the latest version of the "vanilla" [Min * [Running on RaspberryPi](#running-on-raspberrypi) * [Contributing](#contributing) - + @@ -756,6 +756,7 @@ Parameters to use the ForgeAPI: * `MODS_FORGEAPI_FILE` - Required or use MODS_FORGEAPI_PROJECTIDS (Overrides MODS_FORGEAPI_PROJECTIDS) * `MODS_FORGEAPI_PROJECTIDS` - Required or use MODS_FORGEAPI_FILE * `MODS_FORGEAPI_RELEASES` - Default is release, Options: [Release|Beta|Alpha] +* `MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES` - Default is False, attempts to download required mods (releaseType Release) defined in Forge. * `REMOVE_OLD_FORGEAPI_MODS` - Default is False * `REMOVE_OLD_DATAPACKS_DEPTH` - Default is 1 * `REMOVE_OLD_DATAPACKS_INCLUDE` - Default is *.jar @@ -768,7 +769,13 @@ Example of expected forge api project ids, releases, and key: MODS_FORGEAPI_KEY: $WRX... ``` -Example of expected ForgeAPI file format: **Note**: name is currently unused, but can be used to document each entry. +Example of expected ForgeAPI file format. + +**Field Description**: +* Name is currently unused, but can be used to document each entry. +* Project id is the id found on the CurseForge website for a particular mod +* Release Type corresponds to forge's R, B, A icon for each file. Default Release, options are (release|beta|alpha). +* FileName is used for version pinning if latest file will not work for you. ```json [ @@ -781,6 +788,12 @@ Example of expected ForgeAPI file format: **Note**: name is currently unused, bu "name": "fabric voice mod", "projectId": "416089", "releaseType": "beta" + }, + { + "name": "Biomes o plenty", + "projectId": "220318", + "fileName": "BiomesOPlenty-1.18.1-15.0.0.100-universal.jar", + "releaseType": "release" } ] ``` diff --git a/docker-versions-create.sh b/docker-versions-create.sh index 9abdfd22..8eeb7310 100755 --- a/docker-versions-create.sh +++ b/docker-versions-create.sh @@ -3,12 +3,6 @@ # Use this variable to indicate a list of branches that docker hub is watching branches_list=( 'java8' - 'java8-multiarch' - 'java8-openj9' - 'java11' - 'java11-openj9' - 'java17' - 'java17-openj9' ) function TrapExit { diff --git a/scripts/start-configuration b/scripts/start-configuration index e61d2e73..20eb5c2b 100755 --- a/scripts/start-configuration +++ b/scripts/start-configuration @@ -3,7 +3,7 @@ set -euo pipefail IFS=$'\n\t' # shellcheck source=start-utils -. ${SCRIPTS:-/}start-utils +. "${SCRIPTS:-/}start-utils" : "${EULA:=}" : "${PROXY:=}" @@ -66,9 +66,12 @@ if [[ $RCON_PASSWORD_FILE ]]; then log "" fi +# Some Docker management UIs grab all the image declared variables and present them for configuration. +# When upgrading images across Java versions, that creates a mismatch in PATH's expected by base image. if ! which java > /dev/null; then - log "Fixing PATH to include java" - PATH="${PATH}:/usr/bin" + log "ERROR: PATH should not be explicitly passed into the container" + log " Remove configuration of that variable." + exit 1 fi export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json @@ -116,23 +119,31 @@ fi log "Resolving type given ${TYPE}" case "${TYPE^^}" in *BUKKIT|SPIGOT) - exec ${SCRIPTS:-/}start-deployBukkitSpigot "$@" + exec "${SCRIPTS:-/}start-deployBukkitSpigot" "$@" ;; PAPER) - exec ${SCRIPTS:-/}start-deployPaper "$@" + exec "${SCRIPTS:-/}start-deployPaper" "$@" ;; FORGE) - exec ${SCRIPTS:-/}start-deployForge "$@" + evaluateJavaCompatibilityForForge + exec "${SCRIPTS:-/}start-deployForge" "$@" ;; FABRIC) - exec ${SCRIPTS:-/}start-deployFabric "$@" + exec "${SCRIPTS:-/}start-deployFabric" "$@" + ;; + + FTBA) + log "ERROR: TYPE=FTBA is not supported with this image variant." + log " Use itzg/minecraft-server:java8-multiarch instead." + exit 1 ;; FTB|CURSEFORGE) - exec ${SCRIPTS:-/}start-deployCF "$@" + evaluateJavaCompatibilityForForge + exec "${SCRIPTS:-/}start-deployCF" "$@" ;; VANILLA) @@ -140,43 +151,47 @@ case "${TYPE^^}" in ;; SPONGEVANILLA) - exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@" + exec "${SCRIPTS:-/}start-deploySpongeVanilla" "$@" ;; CUSTOM) - exec ${SCRIPTS:-/}start-deployCustom "$@" + evaluateJavaCompatibilityForForge + exec "${SCRIPTS:-/}start-deployCustom" "$@" ;; MAGMA) - exec ${SCRIPTS:-/}start-deployMagma "$@" + evaluateJavaCompatibilityForForge + exec "${SCRIPTS:-/}start-deployMagma" "$@" ;; MOHIST) - exec ${SCRIPTS:-/}start-deployMohist "$@" + evaluateJavaCompatibilityForForge + exec "${SCRIPTS:-/}start-deployMohist" "$@" ;; CATSERVER) - exec ${SCRIPTS:-/}start-deployCatserver "$@" + evaluateJavaCompatibilityForForge + exec "${SCRIPTS:-/}start-deployCatserver" "$@" ;; PURPUR) - exec ${SCRIPTS:-/}start-deployPurpur "$@" + exec "${SCRIPTS:-/}start-deployPurpur" "$@" ;; AIRPLANE) - exec ${SCRIPTS:-/}start-deployAirplane "$@" + exec "${SCRIPTS:-/}start-deployAirplane" "$@" ;; PUFFERFISH) - exec ${SCRIPTS:-/}start-deployPufferfish "$@" + exec "${SCRIPTS:-/}start-deployPufferfish" "$@" ;; CANYON) - exec ${SCRIPTS:-/}start-deployCanyon "$@" + exec "${SCRIPTS:-/}start-deployCanyon" "$@" ;; LIMBO) - exec ${SCRIPTS:-/}start-deployLimbo "$@" + exec "${SCRIPTS:-/}start-deployLimbo" "$@" ;; CRUCIBLE) diff --git a/scripts/start-deployAirplane b/scripts/start-deployAirplane index 2229a6b0..99366cce 100755 --- a/scripts/start-deployAirplane +++ b/scripts/start-deployAirplane @@ -42,6 +42,5 @@ fi # Normalize on Spigot for later operations export FAMILY=SPIGOT -export SKIP_LOG4J_CONFIG=true exec "${SCRIPTS:-/}start-spiget" "$@" diff --git a/scripts/start-deployBukkitSpigot b/scripts/start-deployBukkitSpigot index a185e98f..c4a7c1f6 100755 --- a/scripts/start-deployBukkitSpigot +++ b/scripts/start-deployBukkitSpigot @@ -127,6 +127,5 @@ fi # Normalize on Spigot for operations below export FAMILY=SPIGOT -export SKIP_LOG4J_CONFIG=true exec ${SCRIPTS:-/}start-spiget "$@" diff --git a/scripts/start-deployCanyon b/scripts/start-deployCanyon index dab75946..d121495c 100755 --- a/scripts/start-deployCanyon +++ b/scripts/start-deployCanyon @@ -44,6 +44,5 @@ fi # Normalize on Spigot for later operations export FAMILY=SPIGOT -export SKIP_LOG4J_CONFIG=true exec ${SCRIPTS:-/}start-spiget "$@" diff --git a/scripts/start-deployCatserver b/scripts/start-deployCatserver index 88fef2b9..f15a2a8a 100755 --- a/scripts/start-deployCatserver +++ b/scripts/start-deployCatserver @@ -1,6 +1,7 @@ #!/bin/bash -. ${SCRIPTS:-/}start-utils +# shellcheck source=start-utils +. "${SCRIPTS:-/}start-utils" set -o pipefail set -e @@ -26,8 +27,6 @@ if [ ! -f ${SERVER} ]; then curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId} fi -export SKIP_LOG4J_CONFIG=true - export FAMILY=HYBRID -# Continue to Final Setup -exec ${SCRIPTS:-/}start-setupWorld "$@" + +exec "${SCRIPTS:-/}start-setupWorld" "$@" diff --git a/scripts/start-deployCrucible b/scripts/start-deployCrucible index c350668b..825afd74 100755 --- a/scripts/start-deployCrucible +++ b/scripts/start-deployCrucible @@ -56,7 +56,6 @@ if [ ! -d "$librariesDir" ]; then fi export SERVER -export SKIP_LOG4J_CONFIG=true export FAMILY=HYBRID exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@" diff --git a/scripts/start-deployCustom b/scripts/start-deployCustom index c4a92570..bc2e7311 100755 --- a/scripts/start-deployCustom +++ b/scripts/start-deployCustom @@ -1,6 +1,7 @@ #!/bin/bash -. ${SCRIPTS:-/}start-utils +# shellcheck source=start-utils +. "${SCRIPTS:-/}start-utils" isDebugging && set -x if isURL ${CUSTOM_SERVER}; then @@ -30,6 +31,6 @@ else fi -export SKIP_LOG4J_CONFIG=true export FAMILY=HYBRID + exec ${SCRIPTS:-/}start-setupWorld $@ diff --git a/scripts/start-deployFTBA b/scripts/start-deployFTBA index fc3962f5..b2b66c42 100755 --- a/scripts/start-deployFTBA +++ b/scripts/start-deployFTBA @@ -2,7 +2,8 @@ ftbInstallMarker=".ftb-installed" -. ${SCRIPTS:-/}start-utils +# shellcheck source=start-utils +. "${SCRIPTS:-/}start-utils" isDebugging && set -x set -e @@ -80,4 +81,5 @@ if ! [ -v SERVER ]; then fi export FAMILY=FORGE + exec ${SCRIPTS:-/}start-setupWorld $@ diff --git a/scripts/start-deployForge b/scripts/start-deployForge index 8111c295..c989ac21 100755 --- a/scripts/start-deployForge +++ b/scripts/start-deployForge @@ -38,18 +38,23 @@ install() { get_installer "$normForgeVersion" "$shortForgeVersion" fi - log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER" + log "Installing Forge $shortForgeVersion. This might take a minute or two..." mkdir -p mods tries=3 - while ((--tries >= 0)); do - if java -jar "$FORGE_INSTALLER" --installServer; then - break + while true; do + if ! java -jar "$FORGE_INSTALLER" --installServer &> forge-installer.log; then + if ((--tries <= 0)); then + cat forge-installer.log + log " +ERROR Forge failed to install after several tries. +" + exit 1 + fi + log "Install failed. Trying again..." + else + break # out of this loop fi done - if ((tries < 0)); then - log "Forge failed to install after several tries." >&2 - exit 10 - fi # NOTE $shortForgeVersion will be empty if installer location was given to us log "Finding installed server jar..." unset -v latest @@ -148,4 +153,5 @@ else fi export FAMILY=FORGE + exec "${SCRIPTS:-/}start-setupWorld" "$@" diff --git a/scripts/start-deployLimbo b/scripts/start-deployLimbo index ad19457c..173c7027 100755 --- a/scripts/start-deployLimbo +++ b/scripts/start-deployLimbo @@ -58,7 +58,5 @@ if [[ ${LEVEL} != *\;* ]]; then fi export LEVEL -export SKIP_LOG4J_CONFIG=true - export FAMILY=LIMBO exec ${SCRIPTS:-/}start-setupWorld $@ diff --git a/scripts/start-deployMagma b/scripts/start-deployMagma index fb92c684..7ff966f6 100755 --- a/scripts/start-deployMagma +++ b/scripts/start-deployMagma @@ -1,13 +1,12 @@ #!/bin/bash -. ${SCRIPTS:-/}start-utils -export SKIP_LOG4J_CONFIG=true - +# shellcheck source=start-utils +. "${SCRIPTS:-/}start-utils" isDebugging && set -x -: ${VANILLA_VERSION?} +: "${VANILLA_VERSION?}" # stable, dev -: ${MAGMA_CHANNEL:=stable} +: "${MAGMA_CHANNEL:=stable}" magmaDownloadServer() { @@ -90,4 +89,5 @@ else fi export FAMILY=HYBRID -exec ${SCRIPTS:-/}start-setupWorld "$@" + +exec "${SCRIPTS:-/}start-setupWorld" "$@" diff --git a/scripts/start-deployMohist b/scripts/start-deployMohist index e17b4d57..35dc97c4 100755 --- a/scripts/start-deployMohist +++ b/scripts/start-deployMohist @@ -38,7 +38,6 @@ if [ ! -f "${SERVER}" ]; then get -o "${SERVER}" "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}" fi -export SKIP_LOG4J_CONFIG=true - export FAMILY=HYBRID + exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@" diff --git a/scripts/start-deployPaper b/scripts/start-deployPaper index fe606dcc..c84d2727 100755 --- a/scripts/start-deployPaper +++ b/scripts/start-deployPaper @@ -74,6 +74,5 @@ fi # Normalize on Spigot for downstream operations export FAMILY=SPIGOT -export SKIP_LOG4J_CONFIG=true exec ${SCRIPTS:-/}start-spiget "$@" diff --git a/scripts/start-deployPufferfish b/scripts/start-deployPufferfish index 0b0ea52c..1ffd0c3b 100755 --- a/scripts/start-deployPufferfish +++ b/scripts/start-deployPufferfish @@ -40,6 +40,5 @@ fi # Normalize on Spigot for later operations export FAMILY=SPIGOT -export SKIP_LOG4J_CONFIG=true exec ${SCRIPTS:-/}start-spiget "$@" diff --git a/scripts/start-deployPurpur b/scripts/start-deployPurpur index 156920b8..de3d9bf6 100755 --- a/scripts/start-deployPurpur +++ b/scripts/start-deployPurpur @@ -6,9 +6,9 @@ IFS=$'\n\t' . "${SCRIPTS:-/}start-utils" isDebugging && set -x -: ${VANILLA_VERSION:?} -: ${PURPUR_BUILD:=LATEST} -: ${FORCE_REDOWNLOAD:=false} +: "${VANILLA_VERSION:?}" +: "${PURPUR_BUILD:=LATEST}" +: "${FORCE_REDOWNLOAD:=false}" if [[ ${PURPUR_BUILD} == LATEST ]]; then if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then @@ -31,6 +31,5 @@ fi # Normalize on Spigot for later operations export FAMILY=SPIGOT -export SKIP_LOG4J_CONFIG=true exec "${SCRIPTS:-/}start-spiget" "$@" diff --git a/scripts/start-finalExec b/scripts/start-finalExec index e5178446..3f282325 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -1,97 +1,9 @@ #!/bin/bash -. ${SCRIPTS:-/}start-utils +# shellcheck source=start-utils +. "${SCRIPTS:-/}start-utils" isDebugging && set -x -if versionLessThan 1.7.6; then - opsFile=ops.txt - whitelistFile=white-list.txt -else - opsFile=ops.json - whitelistFile=whitelist.json -fi - -function process_user_file() { - local output=$1 - local source=$2 - - if isURL "$source"; then - log "Downloading $output from $source" - if ! get -o /data/$output "$source"; then - log "ERROR: failed to download from $source" - exit 2 - fi - else - log "Copying $output from $source" - if ! cp "$source" /data/$output; then - log "ERROR: failed to copy from $source" - exit 1 - fi - fi -} - -function process_user_csv() { - local output=$1 - local list=$2 - local playerDataList - - if [[ "$output" == *"ops"* ]]; then - # Extra data for ops.json - userData='{"uuid": .id, "name": .username, "level": 4}' - else - userData='{"uuid": .id, "name": .username}' - fi - - log "Updating ${output%.*}" - for i in ${list//,/ } - do - if [ -e "$output" ] && grep -q "$i" "$output"; then - log "$i already present in $output, skipping" - continue - fi - if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then - log "WARNING: Could not lookup user $i for ${output} addition" - else - playerDataList=$playerDataList$(echo $playerData | jq -r "$userData") - fi - done - local newUsers=$(echo $playerDataList | jq -s .) - if [[ $output =~ .*\.txt ]]; then - # username list for txt config (Minecraft <= 1.7.5) - echo $newUsers | jq -r '.[].name' >> /data/${output} - sort -u /data/${output} -o /data/${output} - elif [ -e /data/${output} ]; then - # Merge with existing json file - local currentUsers=$(cat /data/${output}) - jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > /data/${output} - else - # New json file - echo $newUsers > /data/${output} - fi -} - -if isTrue "${OVERRIDE_OPS}"; then - log "Recreating ${opsFile} file at server startup" - rm -f /data/${opsFile} -fi -if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then - process_user_file ${opsFile} "$OPS_FILE" -fi -if [ -n "${OPS}" ]; then - process_user_csv ${opsFile} "$OPS" -fi - -if isTrue "${OVERRIDE_WHITELIST}"; then - log "Recreating ${whitelistFile} file at server startup" - rm -f /data/${whitelistFile} -fi -if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then - process_user_file ${whitelistFile} "$WHITELIST_FILE" -fi -if [ -n "${WHITELIST}" ]; then - process_user_csv ${whitelistFile} "$WHITELIST" -fi - if [ -n "$ICON" ]; then if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then log "Using server icon from $ICON..." @@ -169,7 +81,7 @@ if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then fi # Optional disable GUI for headless servers -if [[ ${GUI} = false || ${GUI} = FALSE ]]; then +if [[ ${GUI,,} = false ]]; then EXTRA_ARGS+=" nogui" fi @@ -331,6 +243,10 @@ EOF elif [[ $SERVER =~ run.sh ]]; then log "Using Forge supplied run.sh script..." echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt + if isTrue ${SETUP_ONLY:=false}; then + echo "SETUP_ONLY: bash ${SERVER}" + exit + fi exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash "${SERVER}" else # If we have a bootstrap.txt file... feed that in to the server stdin diff --git a/scripts/start-setupEnvVariables b/scripts/start-setupEnvVariables index 34712ded..42eae28f 100755 --- a/scripts/start-setupEnvVariables +++ b/scripts/start-setupEnvVariables @@ -32,4 +32,4 @@ if [[ ${PATCH_DEFINITIONS} ]]; then "${PATCH_DEFINITIONS}" fi -exec "${SCRIPTS:-/}start-finalExec" "$@" +exec "${SCRIPTS:-/}start-setupRbac" "$@" diff --git a/scripts/start-setupForgeApiMods b/scripts/start-setupForgeApiMods index 069ebc52..86e4d6cf 100644 --- a/scripts/start-setupForgeApiMods +++ b/scripts/start-setupForgeApiMods @@ -7,6 +7,7 @@ set -e -o pipefail : "${MODS_FORGEAPI_PROJECTIDS:=}" : "${MODS_FORGEAPI_FILE:=}" : "${MODS_FORGEAPI_RELEASES:=RELEASE}" +: "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES:=false}" : "${REMOVE_OLD_MODS_DEPTH:=1} " : "${REMOVE_OLD_MODS_INCLUDE:=*.jar}" @@ -36,11 +37,11 @@ ensureModKey(){ # NOTE: downcasing release type for comparing types. updateReleaseNumber(){ releaseType=$1 - if [ "release" = "${releaseType,,}" ]; then + if [ "release" = "${releaseType,,}" ] || [ 1 = "${releaseType,,}" ]; then RELEASE_NUMBER_FILTER=1 - elif [ "beta" = "${releaseType,,}" ]; then + elif [ "beta" = "${releaseType,,}" ] || [ 2 = "${releaseType,,}" ]; then RELEASE_NUMBER_FILTER=2 - elif [ "alpha" = "${releaseType,,}" ]; then + elif [ "alpha" = "${releaseType,,}" ] || [ 3 = "${releaseType,,}" ]; then RELEASE_NUMBER_FILTER=3 fi } @@ -52,12 +53,12 @@ retrieveVersionTypeNumber(){ -H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'') if [ ! "$minecraft_types" ]; then - log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI" + log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI. Check Forge API key or supplied Minecraft version" exit 2 fi TYPE_ID=$(jq -n "$minecraft_types" | jq --arg VERSION_NAME "$VERSION_NAME" -jc ' - .data[] | select(.name==$VERSION_NAME) | .id') + .data[]? | select(.name==$VERSION_NAME) | .id') if [ ! "$TYPE_ID" ]; then log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI" @@ -68,6 +69,7 @@ retrieveVersionTypeNumber(){ modFileByProjectID(){ project_id=$(echo $1 | tr -d '"') project_id_release_type=$2 + project_id_file_name=$3 unset PROJECT_FILE # if Type id isn't defined use minecraft version to go get it. @@ -100,9 +102,13 @@ modFileByProjectID(){ fi # grabs the highest ID of the releaseTypes selected. # Default is 1 for Release, Beta is 2, and Alpha is 3. Using less than we can validate highest release. - current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" -jc ' - .data | sort_by(.id) | reverse | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0]') - + if [ $project_id_file_name ]; then + current_project_file=$(jq -n "$project_files" | jq --arg FILE_NAME "$project_id_file_name" -jc ' + .data | map(select(.fileName<=($FILE_NAME))) | .[0]') + else + current_project_file=$(jq -n "$project_files" | jq --arg RELEASE_FILTER "$RELEASE_NUMBER_FILTER" -jc ' + .data | sort_by(.id) | reverse | map(select(.releaseType<=($RELEASE_FILTER|tonumber))) | .[0]') + fi # Logic to grab the latest release over the entire pagination if [ ! "$PROJECT_FILE" ]; then PROJECT_FILE=$current_project_file @@ -143,6 +149,40 @@ downloadModPackfromModFile() { fi } +downloadDependencies(){ + if [ "$PROJECT_FILE" ]; then + dependencies=$(jq -n "$PROJECT_FILE" | jq -jc '.dependencies' ) + required_dependencies=$(jq -n "$dependencies" | jq --arg REQUIRED_FILTER "3" -jc ' + map(select(.relationType==($REQUIRED_FILTER|tonumber)))') + if [ "$required_dependencies" ]; then + jq -n "$required_dependencies" | jq -c '.[]?' | while read current_dependency; do + mod_id=$(jq -n "$current_dependency" | jq -jc '.modId' ) + + # BROKEN: Example Voice mod keeps returning the voice mod file id instead of the mod file id. + # file_id=$(jq -n "$current_dependency" | jq -jc '.fileId' ) + # dependency_data=$(curl -X GET -s \ + # "${FORGEAPI_BASE_URL}/mods/${mod_id}/files/${file_id}/download-url" \ + # -H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'') + # if [ ! "$dependency_data" ]; then + # log "ERROR: unable to retrieve dependency data files for ${project_id} from ForgeAPI" + # exit 2 + # fi + # dependency_download_url=$(jq -n "$dependency_data" | jq -jc '.data' ) + # echo "Downloading dependency ${dependency_download_url}" + # if ! get -o "${out_dir}/" $dependency_download_url ; then + # log "ERROR: failed to download dependency from ${dependency_download_url}" + # exit 2 + # fi + + # Using current mod path and release to go get the REQUIRED DEPENDENCY + # NOTE: we are ASUMING it will be release. + modFileByProjectID $mod_id "release" + downloadModPackfromModFile + done + fi + fi +} + # Use forge api json file to filter and download the correct mods if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then ensureModKey @@ -150,18 +190,19 @@ if [ "$MODS_FORGEAPI_FILE" ] && [ -z "$MODS_FORGEAPI_PROJECTIDS" ]; then log "ERROR: given MODS_FORGEAPI_FILE file does not exist" exit 2 fi - MODS_FORGEAPI_PROJECTIDS=$(jq --raw-output '[.[] | .projectId] | join(",")' $MODS_FORGEAPI_FILE) - if [ ! "$MODS_FORGEAPI_PROJECTIDS" ]; then - log "ERROR: unable to retrieve packs from $MODS_FORGEAPI_FILE" - exit 2 - fi # Needs loop here to look up release types befor calling download. - for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do - current_release_type=$(jq --arg PROJECT_ID "$project_id" -jc ' - .[] | select(.projectId==$PROJECT_ID) | .releaseType' "$MODS_FORGEAPI_FILE") - modFileByProjectID $project_id $current_release_type - downloadModPackfromModFile + jq -n "$required_dependencies" | jq -c '.[]?' | while read current_project; do + # Per stack overflow we can use //empty to return empty string that works with -z + project_id=$(jq -n "$current_project" | jq -jc '.projectId // empty' ) + current_release_type=$(jq -n "$current_project" | jq -jc '.releaseType // empty' ) + current_file_name=$(jq -n "$current_project" | jq -jc '.fileName // empty' ) + + modFileByProjectID $project_id $current_release_type $current_file_name + downloadModPackfromModFile + if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then + downloadDependencies + fi done fi @@ -170,7 +211,10 @@ if [ "$MODS_FORGEAPI_PROJECTIDS" ] && [ -z "$MODS_FORGEAPI_FILE" ]; then ensureModKey for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do modFileByProjectID $project_id - downloadModPackfromModFile + downloadModPackfromModFile + if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then + downloadDependencies + fi done fi diff --git a/scripts/start-setupModpack b/scripts/start-setupModpack index 0c71c676..5dc66e38 100755 --- a/scripts/start-setupModpack +++ b/scripts/start-setupModpack @@ -207,12 +207,12 @@ if [[ "${GENERIC_PACKS}" ]]; then done isDebugging && [ -f "$sum_file}" ] && cat "$sum_file" - if ! sha256sum -c "${sum_file}" --status 2> /dev/null; then + if ! sha1sum -c "${sum_file}" --status 2> /dev/null; then base_dir=/tmp/generic_pack_base mkdir -p ${base_dir} for pack in "${packFiles[@]}"; do isDebugging && ls -l "${pack}" - unzip -q -d ${base_dir} "${pack}" + extract "${pack}" "${base_dir}" done # recalculate the actual base directory of content @@ -240,7 +240,7 @@ if [[ "${GENERIC_PACKS}" ]]; then cp -R -f "${base_dir}"/* /data rm -rf /tmp/generic_pack_base - sha256sum "${packFiles[@]}" > "${sum_file}" + sha1sum "${packFiles[@]}" > "${sum_file}" isDebugging && cat "$sum_file" fi fi diff --git a/scripts/start-setupRbac b/scripts/start-setupRbac new file mode 100644 index 00000000..9c92764b --- /dev/null +++ b/scripts/start-setupRbac @@ -0,0 +1,98 @@ +#!/bin/bash + +# shellcheck source=start-utils +. "${SCRIPTS:-/}start-utils" +isDebugging && set -x + +if versionLessThan 1.7.6; then + opsFile=ops.txt + whitelistFile=white-list.txt +else + opsFile=ops.json + whitelistFile=whitelist.json +fi + +function process_user_file() { + local output=$1 + local source=$2 + + if isURL "$source"; then + log "Downloading $output from $source" + if ! get -o "/data/$output" "$source"; then + log "ERROR: failed to download from $source" + exit 2 + fi + else + log "Copying $output from $source" + if ! cp "$source" "/data/$output"; then + log "ERROR: failed to copy from $source" + exit 1 + fi + fi +} + +function process_user_csv() { + local output=$1 + local list=$2 + local playerDataList + + if [[ "$output" == *"ops"* ]]; then + # Extra data for ops.json + userData='{"uuid": .id, "name": .username, "level": 4}' + else + userData='{"uuid": .id, "name": .username}' + fi + + log "Updating ${output%.*}" + for i in ${list//,/ } + do + if [ -e "$output" ] && grep -q "$i" "$output"; then + log "$i already present in $output, skipping" + continue + fi + if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then + log "WARNING: Could not lookup user $i for ${output} addition" + else + playerDataList=$playerDataList$(echo "$playerData" | jq -r "$userData") + fi + done + local newUsers=$(echo "$playerDataList" | jq -s .) + if [[ $output =~ .*\.txt ]]; then + # username list for txt config (Minecraft <= 1.7.5) + echo $newUsers | jq -r '.[].name' >> "/data/${output}" + sort -u /data/${output} -o /data/${output} + elif [ -e /data/${output} ]; then + # Merge with existing json file + local currentUsers=$(cat "/data/${output}") + jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > "/data/${output}" + else + # New json file + echo $newUsers > "/data/${output}" + fi +} + +if isTrue "${OVERRIDE_OPS}"; then + log "Recreating ${opsFile} file at server startup" + rm -f /data/${opsFile} +fi +if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then + process_user_file ${opsFile} "$OPS_FILE" +fi +if [ -n "${OPS}" ]; then + process_user_csv ${opsFile} "$OPS" +fi + +if isTrue "${OVERRIDE_WHITELIST}"; then + log "Recreating ${whitelistFile} file at server startup" + rm -f /data/${whitelistFile} +fi +if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then + process_user_file ${whitelistFile} "$WHITELIST_FILE" +fi +if [ -n "${WHITELIST}" ]; then + process_user_csv ${whitelistFile} "$WHITELIST" +fi + + + +exec "${SCRIPTS:-/}start-finalExec" "$@" diff --git a/scripts/start-utils b/scripts/start-utils index a2da3d5c..f55af29c 100755 --- a/scripts/start-utils +++ b/scripts/start-utils @@ -183,6 +183,7 @@ function isFamily() { } function isType() { for t in "${@}"; do + # shellcheck disable=SC2153 if [[ $TYPE == "$t" ]]; then return 0 fi @@ -190,17 +191,32 @@ function isType() { return 1 } +function evaluateJavaCompatibilityForForge() { + javaRelease=$(mc-image-helper java-release) + if versionLessThan 1.18 && (( javaRelease > 8 )); then + log "**********************************************************************" + log "WARNING: Some mods and modpacks may require Java 8." + log " Please use itzg/minecraft-server:java8" + log "**********************************************************************" + sleep 5 + fi +} + function extract() { src=${1?} destDir=${2?} type=$(file -b --mime-type "${src}") - if [[ $type == application/zip ]]; then - unzip -q -d "${destDir}" "${src}" - elif [[ $type == application/x-tar ]]; then - tar -C "${destDir}" -xf "${src}" - else - log "ERROR: unsupported archive type: $type" - return 1 - fi -} \ No newline at end of file + case "${type}" in + application/zip) + unzip -q -d "${destDir}" "${src}" + ;; + application/x-tar|application/gzip|application/x-bzip2|application/zstd) + tar -C "${destDir}" -xf "${src}" + ;; + *) + log "ERROR: unsupported archive type: $type" + return 1 + ;; + esac +} diff --git a/tests/setuponlytests/forgeapimods_file/docker-compose.disabled.yml b/tests/setuponlytests/forgeapimods_file/docker-compose.yml similarity index 71% rename from tests/setuponlytests/forgeapimods_file/docker-compose.disabled.yml rename to tests/setuponlytests/forgeapimods_file/docker-compose.yml index 11686a4b..2f9ce7d5 100644 --- a/tests/setuponlytests/forgeapimods_file/docker-compose.disabled.yml +++ b/tests/setuponlytests/forgeapimods_file/docker-compose.yml @@ -8,10 +8,11 @@ services: EULA: "TRUE" SETUP_ONLY: "TRUE" VERSION: ${MINECRAFT_VERSION:-LATEST} - MODS_FORGEAPI_FILE: /config/example.json + MODS_FORGEAPI_FILE: /config/forgeapi_mods.json # Key is defined in .github/workflows/pr.yml and ci.yml # This should be coming from github secrets. MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY} REMOVE_OLD_FORGEAPI_MODS: "TRUE" + MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "FALSE" volumes: - - ./example.json:/config/example.json:ro + - ./forgeapi_mods.json:/config/forgeapi_mods.json:ro diff --git a/tests/setuponlytests/forgeapimods_file/example.json b/tests/setuponlytests/forgeapimods_file/forgeapi_mods.json similarity index 54% rename from tests/setuponlytests/forgeapimods_file/example.json rename to tests/setuponlytests/forgeapimods_file/forgeapi_mods.json index b7c9a304..afc0b745 100644 --- a/tests/setuponlytests/forgeapimods_file/example.json +++ b/tests/setuponlytests/forgeapimods_file/forgeapi_mods.json @@ -7,5 +7,11 @@ "name": "Fabric Voice Mod", "projectId": "416089", "releaseType": "beta" + }, + { + "name": "Biomes o plenty", + "projectId": "220318", + "fileName": "BiomesOPlenty-1.18.1-15.0.0.100-universal.jar", + "releaseType": "release" } ] \ No newline at end of file diff --git a/tests/setuponlytests/forgeapimods_file/require.sh b/tests/setuponlytests/forgeapimods_file/require.sh new file mode 100644 index 00000000..2fd503da --- /dev/null +++ b/tests/setuponlytests/forgeapimods_file/require.sh @@ -0,0 +1 @@ +[[ $MODS_FORGEAPI_KEY ]] || exit 1 \ No newline at end of file diff --git a/tests/setuponlytests/forgeapimods_projectids/docker-compose.disabled.yml b/tests/setuponlytests/forgeapimods_projectids/docker-compose.yml similarity index 79% rename from tests/setuponlytests/forgeapimods_projectids/docker-compose.disabled.yml rename to tests/setuponlytests/forgeapimods_projectids/docker-compose.yml index 2bc794dc..17e35ec2 100644 --- a/tests/setuponlytests/forgeapimods_projectids/docker-compose.disabled.yml +++ b/tests/setuponlytests/forgeapimods_projectids/docker-compose.yml @@ -8,7 +8,8 @@ services: EULA: "TRUE" SETUP_ONLY: "TRUE" VERSION: ${MINECRAFT_VERSION:-LATEST} - MODS_FORGEAPI_PROJECTIDS: 306612,416089 + MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES: "TRUE" + MODS_FORGEAPI_PROJECTIDS: 306612,416089,220318 # Allows for Beta releases of 416089 the Fabric Voice Mod MODS_FORGEAPI_RELEASES: BETA MODS_FORGEAPI_KEY: ${MODS_FORGEAPI_KEY} diff --git a/tests/setuponlytests/forgeapimods_projectids/require.sh b/tests/setuponlytests/forgeapimods_projectids/require.sh new file mode 100644 index 00000000..2fd503da --- /dev/null +++ b/tests/setuponlytests/forgeapimods_projectids/require.sh @@ -0,0 +1 @@ +[[ $MODS_FORGEAPI_KEY ]] || exit 1 \ No newline at end of file diff --git a/tests/setuponlytests/ops_from_scratch/docker-compose.yml b/tests/setuponlytests/ops_from_scratch/docker-compose.yml new file mode 100644 index 00000000..4cc8eb64 --- /dev/null +++ b/tests/setuponlytests/ops_from_scratch/docker-compose.yml @@ -0,0 +1,13 @@ +version: "3" + +services: + mc: + restart: "no" + image: ${IMAGE_TO_TEST:-itzg/minecraft-server} + environment: + EULA: "TRUE" + SETUP_ONLY: "TRUE" + VERSION: ${MINECRAFT_VERSION:-LATEST} + OPS: itzg + volumes: + - ./data:/data diff --git a/tests/setuponlytests/ops_from_scratch/verify.sh b/tests/setuponlytests/ops_from_scratch/verify.sh new file mode 100644 index 00000000..4c916e07 --- /dev/null +++ b/tests/setuponlytests/ops_from_scratch/verify.sh @@ -0,0 +1,3 @@ +mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].name' --expect=itzg +mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].uuid' --expect=5cddfd26-fc86-4981-b52e-c42bb10bfdef +mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].level' --expect=4 \ No newline at end of file diff --git a/tests/setuponlytests/test.sh b/tests/setuponlytests/test.sh index 8c8cb38e..7eae2b5e 100644 --- a/tests/setuponlytests/test.sh +++ b/tests/setuponlytests/test.sh @@ -11,8 +11,19 @@ setupOnlyMinecraftTest(){ cd "$folder" result=0 - if ! logs=$(docker compose run --quiet-pull mc 2>&1); then - echo "${folder} setup FAILED" + if [ -f require.sh ]; then + # require.sh scripts can check for environment variables, etc that are required for the test. + # The script should exit with a non-zero status to indicate the test requirements are missing + # and the test should be skipped + if ! bash require.sh; then + echo "${folder} SKIP" + cd .. + return 0 + fi + fi + + if ! logs=$(docker-compose run mc 2>&1); then + echo "${folder} test scenario FAILED" echo ":::::::::::: LOGS :::::::::::::::: $logs :::::::::::::::::::::::::::::::::: @@ -29,7 +40,7 @@ $logs echo "${folder} PASS" fi - docker compose down -v --remove-orphans + docker-compose down -v --remove-orphans cd .. return $result diff --git a/tests/setuponlytests/whitelist_from_scratch/docker-compose.yml b/tests/setuponlytests/whitelist_from_scratch/docker-compose.yml new file mode 100644 index 00000000..a09104ac --- /dev/null +++ b/tests/setuponlytests/whitelist_from_scratch/docker-compose.yml @@ -0,0 +1,15 @@ +version: "3" + +services: + mc: + restart: "no" + image: ${IMAGE_TO_TEST:-itzg/minecraft-server} + environment: + EULA: "TRUE" + SETUP_ONLY: "TRUE" + VERSION: ${MINECRAFT_VERSION:-LATEST} + WHITELIST: itzg + ENFORCE_WHITELIST: "true" + OVERRIDE_SERVER_PROPERTIES: "true" + volumes: + - ./data:/data diff --git a/tests/setuponlytests/whitelist_from_scratch/verify.sh b/tests/setuponlytests/whitelist_from_scratch/verify.sh new file mode 100644 index 00000000..4e2417d2 --- /dev/null +++ b/tests/setuponlytests/whitelist_from_scratch/verify.sh @@ -0,0 +1,4 @@ +mc-image-helper assert jsonPathEquals --file=whitelist.json --path='$[0].name' --expect=itzg +mc-image-helper assert jsonPathEquals --file=whitelist.json --path='$[0].uuid' --expect=5cddfd26-fc86-4981-b52e-c42bb10bfdef +mc-image-helper assert propertyEquals --file=server.properties --property=white-list --expect=true +mc-image-helper assert propertyEquals --file=server.properties --property=enforce-whitelist --expect=true diff --git a/tests/setuponlytests/world_from_tgz/docker-compose.yml b/tests/setuponlytests/world_from_tar/docker-compose.yml similarity index 86% rename from tests/setuponlytests/world_from_tgz/docker-compose.yml rename to tests/setuponlytests/world_from_tar/docker-compose.yml index 530b1ed8..89aba954 100644 --- a/tests/setuponlytests/world_from_tgz/docker-compose.yml +++ b/tests/setuponlytests/world_from_tar/docker-compose.yml @@ -8,7 +8,7 @@ services: EULA: "TRUE" SETUP_ONLY: "TRUE" VERSION: ${MINECRAFT_VERSION:-LATEST} - WORLD: /worlds/world-for-testing.tgz + WORLD: /worlds/world-for-testing.tar volumes: - ./worlds:/worlds:ro - ./data:/data diff --git a/tests/setuponlytests/world_from_tgz/verify.sh b/tests/setuponlytests/world_from_tar/verify.sh similarity index 100% rename from tests/setuponlytests/world_from_tgz/verify.sh rename to tests/setuponlytests/world_from_tar/verify.sh diff --git a/tests/setuponlytests/world_from_tgz/worlds/world-for-testing.tgz b/tests/setuponlytests/world_from_tar/worlds/world-for-testing.tar similarity index 100% rename from tests/setuponlytests/world_from_tgz/worlds/world-for-testing.tgz rename to tests/setuponlytests/world_from_tar/worlds/world-for-testing.tar diff --git a/tests/setuponlytests/world_from_tarbz2/docker-compose.yml b/tests/setuponlytests/world_from_tarbz2/docker-compose.yml new file mode 100644 index 00000000..7f5bc2aa --- /dev/null +++ b/tests/setuponlytests/world_from_tarbz2/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} + WORLD: /worlds/world-for-testing.tar.bz2 + volumes: + - ./worlds:/worlds:ro + - ./data:/data diff --git a/tests/setuponlytests/world_from_tarbz2/verify.sh b/tests/setuponlytests/world_from_tarbz2/verify.sh new file mode 100644 index 00000000..b2138d04 --- /dev/null +++ b/tests/setuponlytests/world_from_tarbz2/verify.sh @@ -0,0 +1 @@ +mc-image-helper assert fileExists world/level.dat \ No newline at end of file diff --git a/tests/setuponlytests/world_from_tarbz2/worlds/world-for-testing.tar.bz2 b/tests/setuponlytests/world_from_tarbz2/worlds/world-for-testing.tar.bz2 new file mode 100644 index 00000000..a3fa505e Binary files /dev/null and b/tests/setuponlytests/world_from_tarbz2/worlds/world-for-testing.tar.bz2 differ diff --git a/tests/setuponlytests/world_from_targz/docker-compose.yml b/tests/setuponlytests/world_from_targz/docker-compose.yml new file mode 100644 index 00000000..59369b9f --- /dev/null +++ b/tests/setuponlytests/world_from_targz/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} + WORLD: /worlds/world-for-testing.tar.gz + volumes: + - ./worlds:/worlds:ro + - ./data:/data diff --git a/tests/setuponlytests/world_from_targz/verify.sh b/tests/setuponlytests/world_from_targz/verify.sh new file mode 100644 index 00000000..b2138d04 --- /dev/null +++ b/tests/setuponlytests/world_from_targz/verify.sh @@ -0,0 +1 @@ +mc-image-helper assert fileExists world/level.dat \ No newline at end of file diff --git a/tests/setuponlytests/world_from_targz/worlds/world-for-testing.tar.gz b/tests/setuponlytests/world_from_targz/worlds/world-for-testing.tar.gz new file mode 100644 index 00000000..d5e9f34e Binary files /dev/null and b/tests/setuponlytests/world_from_targz/worlds/world-for-testing.tar.gz differ diff --git a/tests/setuponlytests/world_from_tarzst/docker-compose.yml b/tests/setuponlytests/world_from_tarzst/docker-compose.yml new file mode 100644 index 00000000..3008f391 --- /dev/null +++ b/tests/setuponlytests/world_from_tarzst/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} + WORLD: /worlds/world-for-testing.tar.zst + volumes: + - ./worlds:/worlds:ro + - ./data:/data diff --git a/tests/setuponlytests/world_from_tarzst/verify.sh b/tests/setuponlytests/world_from_tarzst/verify.sh new file mode 100644 index 00000000..b2138d04 --- /dev/null +++ b/tests/setuponlytests/world_from_tarzst/verify.sh @@ -0,0 +1 @@ +mc-image-helper assert fileExists world/level.dat \ No newline at end of file diff --git a/tests/setuponlytests/world_from_tarzst/worlds/world-for-testing.tar.zst b/tests/setuponlytests/world_from_tarzst/worlds/world-for-testing.tar.zst new file mode 100644 index 00000000..80a8a60d Binary files /dev/null and b/tests/setuponlytests/world_from_tarzst/worlds/world-for-testing.tar.zst differ