Compare commits

..

22 Commits

Author SHA1 Message Date
Geoff Bourne
ae96adaeec Auto-merging via docker-versions-create 2021-12-10 10:43:14 -06:00
Geoff Bourne
d34be9f20e Auto-merging via docker-versions-create 2021-12-10 07:58:31 -06:00
Geoff Bourne
64a02d28bc Auto-merging via docker-versions-create 2021-12-06 22:06:58 -06:00
Geoff Bourne
c446cb11da Auto-merging via docker-versions-create 2021-12-04 10:00:59 -06:00
Geoff Bourne
7aea5b593e Auto-merging via docker-versions-create 2021-12-02 19:47:40 -06:00
Geoff Bourne
91adfaa1d9 Auto-merging via docker-versions-create 2021-11-24 15:58:26 -06:00
Geoff Bourne
e7b223f1c6 Auto-merging via docker-versions-create 2021-11-24 14:35:16 -06:00
Geoff Bourne
45eff98011 Track latest from master 2021-11-16 19:02:53 -06:00
Geoff Bourne
b4111f0428 Auto-merging via docker-versions-create 2021-11-16 18:52:49 -06:00
Geoff Bourne
288bdf3804 Auto-merging via docker-versions-create 2021-11-15 20:49:35 -06:00
Geoff Bourne
5bc1ac672e Auto-merging via docker-versions-create 2021-11-13 19:18:44 -06:00
Geoff Bourne
a503ad2ec2 Auto-merging via docker-versions-create 2021-11-13 18:53:18 -06:00
Geoff Bourne
3042aa4909 Auto-merging via docker-versions-create 2021-11-12 21:25:05 -06:00
Geoff Bourne
8882ae5f89 Auto-merging via docker-versions-create 2021-11-06 21:41:15 -05:00
Geoff Bourne
4149db7f11 Auto-merging via docker-versions-create 2021-11-04 21:08:06 -05:00
Geoff Bourne
666f538ad5 Auto-merging via docker-versions-create 2021-10-31 09:49:21 -05:00
Geoff Bourne
145403ea54 Merge branch 'master' into java17 2021-10-27 21:28:49 -05:00
Geoff Bourne
5392801ecd Auto-merging via docker-versions-create 2021-10-25 19:26:48 -05:00
Geoff Bourne
3dfd70d068 Auto-merging via docker-versions-create 2021-10-24 20:31:59 -05:00
Geoff Bourne
e5bc9b939f Auto-merging via docker-versions-create 2021-10-23 09:47:31 -05:00
Geoff Bourne
1b620d2d6d Auto-merging via docker-versions-create 2021-10-22 15:57:41 -05:00
Geoff Bourne
28d77853cb Added java17 variant
#1054
2021-10-19 21:34:02 -05:00
123 changed files with 494 additions and 2293 deletions

4
.github/release.yml vendored
View File

@@ -1,4 +0,0 @@
changelog:
exclude:
authors:
- dependabot

View File

@@ -3,60 +3,30 @@ on:
push: push:
branches: branches:
- master - master
- test/** - java8-multiarch
- java8-openj9
- java11*
- java16*
- java17*
- test/*
- fix/*
tags: tags:
- "[0-9]+.[0-9]+.[0-9]+" - "[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*"
paths-ignore: paths-ignore:
- "*.md" - "*.md"
- "docs/**" - "docs/**"
- "examples/**" - "examples/**"
env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
jobs: jobs:
build: build:
if: github.repository == 'itzg/docker-minecraft-server' 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/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 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout - name: Checkout
@@ -69,13 +39,10 @@ jobs:
images: | images: |
itzg/minecraft-server itzg/minecraft-server
tags: | tags: |
type=ref,event=tag,enable=${{ matrix.variant == 'java17' }} type=ref,event=branch
type=ref,event=tag,suffix=-${{ matrix.variant }} type=ref,event=tag
type=raw,value=${{ matrix.variant }}
flavor: | flavor: |
latest=${{ matrix.variant == 'java17' }} latest=${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
labels: |
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
- name: Setup Docker Buildx - name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v1
@@ -90,37 +57,38 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test - name: Build for test
uses: docker/build-push-action@v2.9.0 uses: docker/build-push-action@v2.7.0
if: github.ref_name == 'master'
with: with:
context: .
platforms: linux/amd64 platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }} tags: ${{ env.IMAGE_TO_TEST }}
# ensure latest base image is used # ensure latest base image is used
pull: true pull: true
# load into daemon for test usage in next step
load: true load: true
push: false push: false
build-args: | cache-from: type=gha
BASE_IMAGE=${{ matrix.baseImage }} cache-to: type=gha,mode=max
cache-from: type=gha,scope=${{ matrix.variant }}
# no cache-to to avoid cross-cache update from next build step
- name: Run tests - name: Run tests
env: # It is assumed that image variants are merged from master and tested there
MINECRAFT_VERSION: ${{ matrix.mcVersion }} if: github.ref_name == 'master'
run: | run: |
tests/test.sh tests/test.sh
- name: Build and push - name: Build and push
id: docker_build id: docker_build
uses: docker/build-push-action@v2.9.0 uses: docker/build-push-action@v2.7.0
with: with:
platforms: ${{ matrix.platforms }} context: .
push: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }} platforms: linux/amd64,linux/arm/v7,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
# ensure latest base image is used # ensure latest base image is used
pull: true pull: true
cache-from: type=gha
cache-to: type=gha,mode=max
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
build-args: |
BASE_IMAGE=${{ matrix.baseImage }} - name: Image digest
cache-from: type=gha,scope=${{ matrix.variant }} run: echo ${{ steps.docker_build.outputs.digest }}
cache-to: type=gha,mode=max,scope=${{ matrix.variant }}

View File

@@ -1,43 +0,0 @@
name: ContinuousIntegration
on:
push:
branches:
- 'dev*'
- '!master'
- '!java*'
- '!multi*'
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
env:
IMAGE_TO_TEST: ${{ secrets.IMAGE_ORG }}/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
jobs:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2.4.0
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build
uses: docker/build-push-action@v2.9.0
with:
context: .
platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }}
load: true
cache-from: type=gha
- name: Run Setup Only Tests
run: bash tests/setuponlytests/test.sh
# - name: Run Full Minecraft Service Tests
# run: |
# tests/fulltests/test.sh

View File

@@ -1,26 +0,0 @@
name: Discord notifications
on:
workflow_run:
workflows: ["ContinuousIntegration", "Build and Publish", "Build and publish multiarch" ]
types:
- completed
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
jobs:
discord:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: on-success
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: Ilshidur/action-discord@master
with:
args: "Github repo: ${{ github.repository }}\n- Branch: ${{ github.event.workflow_run.head_branch }}\n- [Link: to Actions](<${{ github.event.workflow_run.html_url }}>)\n- Status: 🎉 ${{ github.event.workflow_run.conclusion }} 🍏"
- name: on-failure
if: ${{ github.event.workflow_run.conclusion == 'failure' }}
uses: Ilshidur/action-discord@master
with:
args: "Github repo: ${{ github.repository }}\n- Branch: ${{ github.event.workflow_run.head_branch }}\n- [Link: to Actions](<${{ github.event.workflow_run.html_url }}>)\n- Status: 🤔 ${{ github.event.workflow_run.conclusion }} 💣💥"

View File

@@ -16,6 +16,6 @@ jobs:
curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc curl https://raw.githubusercontent.com/ekalinin/github-markdown-toc/master/gh-md-toc -o gh-md-toc
chmod a+x gh-md-toc chmod a+x gh-md-toc
./gh-md-toc --insert --no-backup README.md ./gh-md-toc --insert --no-backup README.md
- uses: stefanzweifel/git-auto-commit-action@v4.13.1 - uses: stefanzweifel/git-auto-commit-action@v4.12.0
with: with:
commit_message: "docs: Auto update markdown TOC" commit_message: "docs: Auto update markdown TOC"

View File

@@ -1,25 +0,0 @@
name: Issue labels
on:
issues:
types: [labeled]
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_ISSUES_WEBHOOK }}
jobs:
labelNotify:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: notify
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.number }})](<${{ github.event.issue.html_url }}>) added `${{ github.event.label.name }}` label"

View File

@@ -4,9 +4,16 @@ on:
push: push:
branches: branches:
- java8 - java8
- openj9
- openj9-11
- adopt11
- test/alpine/* - test/alpine/*
tags: tags:
- "[0-9]+.[0-9]+.[0-9]+-java8" - "[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: env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }} IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
@@ -46,7 +53,7 @@ jobs:
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build for test - name: Build for test
uses: docker/build-push-action@v2.9.0 uses: docker/build-push-action@v2.7.0
if: github.ref_name == 'java8' if: github.ref_name == 'java8'
with: with:
context: . context: .
@@ -68,7 +75,7 @@ jobs:
- name: Build and push - name: Build and push
id: docker_build id: docker_build
uses: docker/build-push-action@v2.9.0 uses: docker/build-push-action@v2.7.0
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
@@ -85,4 +92,6 @@ jobs:
org.opencontainers.image.version=${{ steps.prep.outputs.version }} org.opencontainers.image.version=${{ steps.prep.outputs.version }}
org.opencontainers.image.source=https://github.com/itzg/docker-minecraft-server org.opencontainers.image.source=https://github.com/itzg/docker-minecraft-server
org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>
- name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

View File

@@ -1,21 +1,15 @@
name: PullRequest name: Validate PR
on: on:
pull_request: pull_request:
branches: [ master ] branches: [ master ]
types: [assigned, opened, synchronize, labeled]
paths-ignore:
- "*.md"
- "docs/**"
- "examples/**"
env: env:
IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }} IMAGE_TO_TEST: itzg/minecraft-server:test-${{ github.repository_owner }}-${{ github.run_id }}
MODS_FORGEAPI_KEY: ${{ secrets.MODS_FORGEAPI_KEY }}
jobs: jobs:
test: test:
runs-on: ubuntu-20.04 runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2.4.0 - uses: actions/checkout@v2.4.0
@@ -24,41 +18,15 @@ jobs:
uses: docker/setup-buildx-action@v1 uses: docker/setup-buildx-action@v1
- name: Build - name: Build
uses: docker/build-push-action@v2.9.0 uses: docker/build-push-action@v2.7.0
with: with:
context: . context: .
platforms: linux/amd64 platforms: linux/amd64
tags: ${{ env.IMAGE_TO_TEST }} tags: ${{ env.IMAGE_TO_TEST }}
load: true load: true
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max
- name: Run tests - name: Run tests
run: | run: |
tests/test.sh 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.9.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 }}

View File

@@ -12,7 +12,7 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- name: Process Stale Issues - name: Process Stale Issues
uses: actions/stale@v4.1.0 uses: actions/stale@v4.0.0
with: with:
stale-issue-label: status/stale stale-issue-label: status/stale
stale-pr-label: status/stale stale-pr-label: status/stale
@@ -21,5 +21,5 @@ jobs:
Please add a comment describing the reason to keep this issue open. Please add a comment describing the reason to keep this issue open.
days-before-stale: 30 days-before-stale: 30
days-before-close: 5 days-before-close: 5
exempt-issue-labels: 'enhancement,keep,status/needs triage,priority/high' exempt-issue-labels: 'enhancement,keep,status/needs triage'

3
.gitignore vendored
View File

@@ -1,5 +1,4 @@
.vscode
/data/ /data/
/.idea/ /.idea/
*.iml *.iml
/gh-md-toc /gh-md-toc

View File

@@ -15,24 +15,8 @@ Individual scripts can be iteratively developed, debugged, and tested using the
First, build a baseline of the image to include the packages needed by existing or new scripts: First, build a baseline of the image to include the packages needed by existing or new scripts:
PowerShell: ```shell script
```powershell docker build -t mc-dev .
$env:IMAGE_TO_TEST="mc-dev"
docker build -t $env:IMAGE_TO_TEST .
pushd tests/setuponlytests/vanillatweaks_file/
docker-compose run mc
docker-compose down --remove-orphans
popd
```
Bash:
```bash
export IMAGE_TO_TEST=mc-dev
docker build -t $IMAGE_TO_TEST .
pushd tests/setuponlytests/vanillatweaks_file/
docker-compose run mc
docker-compose down --remove-orphans
popd
``` ```
Using the baseline image, an interactive container can be started to iteratively run the scripts to be developed. By attaching the current workspace directory, you can use the local editor of your choice to iteratively modify scripts while using the container to run them. Using the baseline image, an interactive container can be started to iteratively run the scripts to be developed. By attaching the current workspace directory, you can use the local editor of your choice to iteratively modify scripts while using the container to run them.
@@ -132,4 +116,4 @@ for b in "${branches[@]}"; do
git merge -s ours -m "Track latest from master" master git merge -s ours -m "Track latest from master" master
git push origin git push origin
done done
``` ```

View File

@@ -1,42 +1,40 @@
ARG BASE_IMAGE=openjdk:8-jdk-alpine FROM eclipse-temurin:17-jdk
FROM ${BASE_IMAGE}
RUN apk add --no-cache -U \ LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
openssl \
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y \
imagemagick \ imagemagick \
file \ gosu \
lsof \ sudo \
su-exec \ net-tools \
# GNU compatible 'find' iputils-ping \
findutils \ curl wget \
shadow \
bash \
curl iputils \
git \ git \
jq \ jq \
dos2unix \
mysql-client \ mysql-client \
tzdata \ tzdata \
rsync \ rsync \
nano \ nano \
sudo \ unzip \
knock \ knockd \
ttf-dejavu \ ttf-dejavu \
zstd && apt-get clean
RUN addgroup -g 1000 minecraft \ RUN addgroup --gid 1000 minecraft \
&& adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft \ && adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft
&& mkdir -m 777 /data \
&& chown minecraft:minecraft /data /home/minecraft
COPY --chmod=644 files/sudoers* /etc/sudoers.d COPY files/sudoers* /etc/sudoers.d
EXPOSE 25565 25575 EXPOSE 25565 25575
# hook into docker BuildKit --platform support # hook into docker BuildKit --platform support
# see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope # see https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG TARGETOS=linux ARG TARGETOS
ARG TARGETARCH=amd64 ARG TARGETARCH
ARG TARGETVARIANT="" ARG TARGETVARIANT
ARG EASY_ADD_VER=0.7.1 ARG EASY_ADD_VER=0.7.1
ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add ADD https://github.com/itzg/easy-add/releases/download/${EASY_ADD_VER}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
@@ -47,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 --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} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.5.1 --var app=rcon-cli --file {{.app}} \ --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 --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} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.10.3 --var app=mc-monitor --file {{.app}} \ --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 --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} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=1.8.0 --var app=mc-server-runner --file {{.app}} \ --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 --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} \ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=0.1.1 --var app=maven-metadata-release --file {{.app}} \ --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 --from https://github.com/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
ARG MC_HELPER_VERSION=1.16.5 ARG MC_HELPER_VERSION=1.9.10
ARG MC_HELPER_BASE_URL=https://github.com/itzg/mc-image-helper/releases/download/v${MC_HELPER_VERSION} 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 \ RUN curl -fsSL ${MC_HELPER_BASE_URL}/mc-image-helper-${MC_HELPER_VERSION}.tgz \
| tar -C /usr/share -zxf - \ | tar -C /usr/share -zxf - \
&& ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin && ln -s /usr/share/mc-image-helper-${MC_HELPER_VERSION}/bin/mc-image-helper /usr/bin
VOLUME ["/data"] VOLUME ["/data"]
WORKDIR /data WORKDIR /data
@@ -74,22 +72,21 @@ WORKDIR /data
STOPSIGNAL SIGTERM STOPSIGNAL SIGTERM
ENV UID=1000 GID=1000 \ ENV UID=1000 GID=1000 \
JVM_XX_OPTS="-XX:+UseG1GC" MEMORY="1G" \ MEMORY="1G" \
TYPE=VANILLA VERSION=LATEST \ TYPE=VANILLA VERSION=LATEST \
ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \ ENABLE_RCON=true RCON_PORT=25575 RCON_PASSWORD=minecraft \
ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 \ ENABLE_AUTOPAUSE=false AUTOPAUSE_TIMEOUT_EST=3600 AUTOPAUSE_TIMEOUT_KN=120 AUTOPAUSE_TIMEOUT_INIT=600 \
AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0 \ AUTOPAUSE_PERIOD=10 AUTOPAUSE_KNOCK_INTERFACE=eth0
ENABLE_AUTOSTOP=false AUTOSTOP_TIMEOUT_EST=3600 AUTOSTOP_TIMEOUT_INIT=1800 AUTOSTOP_PERIOD=10
COPY --chmod=755 scripts/start* / COPY scripts/start* /
COPY --chmod=755 bin/ /usr/local/bin/ COPY bin/ /usr/local/bin/
COPY --chmod=755 bin/mc-health /health.sh COPY bin/mc-health /health.sh
COPY --chmod=644 files/server.properties /tmp/server.properties COPY files/server.properties /tmp/server.properties
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml COPY files/log4j2.xml /tmp/log4j2.xml
COPY --chmod=755 files/autopause /autopause COPY files/autopause /autopause
COPY --chmod=755 files/autostop /autostop
RUN dos2unix /start* /autopause/* /autostop/* RUN dos2unix /start* && chmod +x /start* \
&& dos2unix /autopause/* && chmod +x /autopause/*.sh
ENTRYPOINT [ "/start" ] ENTRYPOINT [ "/start" ]
HEALTHCHECK --start-period=1m CMD mc-health HEALTHCHECK --start-period=1m CMD mc-health

306
README.md
View File

@@ -24,7 +24,6 @@ By default, the container will download the latest version of the "vanilla" [Min
**TABLE OF CONTENTS** **TABLE OF CONTENTS**
<!--ts--> <!--ts-->
* [Mitigated Log4jShell Vulnerability](#mitigated-log4jshell-vulnerability)
* [Looking for a Bedrock Dedicated Server](#looking-for-a-bedrock-dedicated-server) * [Looking for a Bedrock Dedicated Server](#looking-for-a-bedrock-dedicated-server)
* [Interacting with the server](#interacting-with-the-server) * [Interacting with the server](#interacting-with-the-server)
* [Data Directory](#data-directory) * [Data Directory](#data-directory)
@@ -46,7 +45,6 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Running a Bukkit/Spigot server](#running-a-bukkitspigot-server) * [Running a Bukkit/Spigot server](#running-a-bukkitspigot-server)
* [Running a Paper server](#running-a-paper-server) * [Running a Paper server](#running-a-paper-server)
* [Running an Airplane server](#running-an-airplane-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 Purpur server](#running-a-purpur-server)
* [Running a Magma server](#running-a-magma-server) * [Running a Magma server](#running-a-magma-server)
* [Running a Mohist server](#running-a-mohist-server) * [Running a Mohist server](#running-a-mohist-server)
@@ -68,16 +66,13 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Optional plugins, mods, and config attach points](#optional-plugins-mods-and-config-attach-points) * [Optional plugins, mods, and config attach points](#optional-plugins-mods-and-config-attach-points)
* [Auto-downloading SpigotMC/Bukkit/PaperMC plugins](#auto-downloading-spigotmcbukkitpapermc-plugins) * [Auto-downloading SpigotMC/Bukkit/PaperMC plugins](#auto-downloading-spigotmcbukkitpapermc-plugins)
* [Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers) * [Downloadable mod/plugin pack for Forge, Fabric, and Bukkit-like Servers](#downloadable-modplugin-pack-for-forge-fabric-and-bukkit-like-servers)
* [ForgeAPI usage to use non-version specific projects](#forgeapi-usage-to-use-non-version-specific-projects) * [Generic pack file](#generic-pack-file)
* [Generic pack files](#generic-pack-files)
* [Mod/Plugin URL Listing File](#modplugin-url-listing-file) * [Mod/Plugin URL Listing File](#modplugin-url-listing-file)
* [Remove old mods/plugins](#remove-old-modsplugins) * [Remove old mods/plugins](#remove-old-modsplugins)
* [Working with world data](#working-with-world-data) * [Working with world data](#working-with-world-data)
* [Downloadable world](#downloadable-world) * [Downloadable world](#downloadable-world)
* [Cloning world from a container path](#cloning-world-from-a-container-path) * [Cloning world from a container path](#cloning-world-from-a-container-path)
* [Overwrite world on start](#overwrite-world-on-start) * [Overwrite world on start](#overwrite-world-on-start)
* [Datapacks](#datapacks)
* [VanillaTweaks](#vanillatweaks)
* [Server configuration](#server-configuration) * [Server configuration](#server-configuration)
* [Message of the Day](#message-of-the-day) * [Message of the Day](#message-of-the-day)
* [Difficulty](#difficulty) * [Difficulty](#difficulty)
@@ -133,23 +128,16 @@ By default, the container will download the latest version of the "vanilla" [Min
* [Explicitly disable GUI](#explicitly-disable-gui) * [Explicitly disable GUI](#explicitly-disable-gui)
* [Stop Duration](#stop-duration) * [Stop Duration](#stop-duration)
* [Setup only](#setup-only) * [Setup only](#setup-only)
* [Enable Flare Flags](#enable-flare-flags)
* [Enable timestamps in init logs](#enable-timestamps-in-init-logs)
* [Autopause](#autopause) * [Autopause](#autopause)
* [Description](#description) * [Description](#description)
* [Enabling Autopause](#enabling-autopause) * [Enabling Autopause](#enabling-autopause)
* [Autostop](#autostop)
* [Running on RaspberryPi](#running-on-raspberrypi) * [Running on RaspberryPi](#running-on-raspberrypi)
* [Contributing](#contributing) * [Contributing](#contributing)
<!-- Added by: runner, at: Sun Feb 6 18:45:39 UTC 2022 --> <!-- Added by: runner, at: Tue Dec 7 03:43:47 UTC 2021 -->
<!--te--> <!--te-->
## 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 ## Looking for a Bedrock Dedicated Server
For Minecraft clients running on consoles, mobile, or native Windows, you'll need to For Minecraft clients running on consoles, mobile, or native Windows, you'll need to
@@ -245,8 +233,6 @@ If you had used the commands in the first section, without the `-v` volume attac
> In this example, it is assumed the original container was given a `--name` of "mc", so change the container identifier accordingly. > In this example, it is assumed the original container was given a `--name` of "mc", so change the container identifier accordingly.
> You can also locate the Docker-managed directory from the `Source` field obtained from `docker inspect <container id or name> -f "{{json .Mounts}}"`
First, stop the existing container: First, stop the existing container:
```shell ```shell
docker stop mc docker stop mc
@@ -295,8 +281,8 @@ When using the image `itzg:/minecraft-server` without a tag, the `latest` image
| java8-openj9 | 8 | Debian | OpenJ9 | amd64 | | java8-openj9 | 8 | Debian | OpenJ9 | amd64 |
| java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 | | java11 | 11 | Debian | Hotspot | amd64,arm64,armv7 |
| java11-openj9 | 11 | Debian | OpenJ9 | amd64 | | java11-openj9 | 11 | Debian | OpenJ9 | amd64 |
| java16-openj9 | 16 | Debian | OpenJ9 | amd64 |
| java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 | | java17 | 17 | Ubuntu | Hotspot | amd64,arm64,armv7 |
| java17-openj9 | 17 | Debian | OpenJ9 | amd64 |
For example, to use Java version 8 on any supported architecture: For example, to use Java version 8 on any supported architecture:
@@ -314,7 +300,7 @@ The following image tags have been deprecated and are no longer receiving update
- adopt15 - adopt15
- openj9-nightly - openj9-nightly
- multiarch-latest - multiarch-latest
- java16/java16-openj9 - java16
## Healthcheck ## Healthcheck
@@ -394,7 +380,7 @@ To troubleshoot any issues with memory allocation reported by the JVM, set the e
### Running a Forge Server ### Running a Forge Server
Enable [Forge server](http://www.minecraftforge.net/) mode by adding a `-e TYPE=FORGE` to your command-line. Enable [Forge server](http://www.minecraftforge.net/wiki/) mode by adding a `-e TYPE=FORGE` to your command-line.
The overall version is specified by `VERSION`, [as described in the section above](#versions) and will run the recommended Forge version by default. You can also choose to run a specific Forge version with `FORGEVERSION`, such as `-e FORGEVERSION=14.23.5.2854`. The overall version is specified by `VERSION`, [as described in the section above](#versions) and will run the recommended Forge version by default. You can also choose to run a specific Forge version with `FORGEVERSION`, such as `-e FORGEVERSION=14.23.5.2854`.
@@ -466,13 +452,19 @@ Plugins can either be managed within the `plugins` subdirectory of the [data dir
Enable Paper server mode by adding a `-e TYPE=PAPER` to your command-line. Enable Paper server mode by adding a `-e TYPE=PAPER` to your command-line.
By default, the container will run the latest build of [Paper server](https://papermc.io/downloads) but you can also choose to run a specific build with `-e PAPERBUILD=205`. By default the container will run the latest build of [Paper server](https://papermc.io/downloads)
but you can also choose to run a specific build with `-e PAPERBUILD=205`.
docker run -d -v /path/on/host:/data \ docker run -d -v /path/on/host:/data \
-e TYPE=PAPER \ -e TYPE=PAPER \
-p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server -p 25565:25565 -e EULA=TRUE --name mc itzg/minecraft-server
If you are hosting your own copy of Paper you can override the download URL with `PAPER_DOWNLOAD_URL=<url>`. If you are hosting your own copy of Paper you can override the download URL with:
- -e PAPER_DOWNLOAD_URL=<url>
An example compose file is provided at
[examples/docker-compose-paper.yml](examples/docker-compose-paper.yml).
If you have attached a host directory to the `/data` volume, then you can install plugins via the `plugins` subdirectory. You can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up. If you have attached a host directory to the `/data` volume, then you can install plugins via the `plugins` subdirectory. You can also [attach a `/plugins` volume](#optional-plugins-mods-and-config-attach-points). If you add plugins while the container is running, you'll need to restart it to pick those up.
@@ -484,24 +476,12 @@ An [Airplane](https://airplane.gg) server, which is "a stable, optimized, well s
-e TYPE=AIRPLANE -e TYPE=AIRPLANE
> NOTE: The `VERSION` variable is used to select an Airplane type to download. The available options are "LATEST" and "PURPUR", both 1.17.1. Airplane does not support 1.18 -- use Paper/Pufferfish/Purpur. > NOTE: The `VERSION` variable is used to select an Airplane branch to download from. The available options are "LATEST" "1.17" "1.16" "PURPUR" and "PURPUR-1.16"
Extra variables: Extra variables:
- `AIRPLANE_BUILD=lastSuccessfulBuild` : set a specific Airplane build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded - `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 built-in [Flare](https://blog.airplane.gg/flare) profiler - `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
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
### Running a Purpur server ### Running a Purpur server
@@ -514,7 +494,7 @@ A [Purpur](https://purpur.pl3x.net/) server, which is "drop-in replacement for P
Extra variables: Extra variables:
- `PURPUR_BUILD=LATEST` : set a specific Purpur build to use - `PURPUR_BUILD=LATEST` : set a specific Purpur build to use
- `FORCE_REDOWNLOAD=false` : set to true to force the located server jar to be re-downloaded - `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 built-in [Flare](https://blog.airplane.gg/flare) profiler - `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the [Flare](https://blog.airplane.gg/flare) profiler
### Running a Magma server ### Running a Magma server
@@ -591,8 +571,6 @@ Configuration options with defaults:
- `LIMBO_SCHEMA_FILENAME`=default.schem - `LIMBO_SCHEMA_FILENAME`=default.schem
- `LEVEL`="Default;${LIMBO_SCHEMA_FILENAME}" - `LEVEL`="Default;${LIMBO_SCHEMA_FILENAME}"
> NOTE: instead of using format codes in the MOTD, Limbo requires [JSON chat content](https://minecraft.fandom.com/wiki/Raw_JSON_text_format#Java_Edition). If a plain string is provided, which is the default, then it gets converted into the required JSON structure.
### Running a Crucible server ### Running a Crucible server
A [Crucible](https://github.com/CrucibleMC/Crucible) server can be run by setting `TYPE` to `CRUCIBLE`. A [Crucible](https://github.com/CrucibleMC/Crucible) server can be run by setting `TYPE` to `CRUCIBLE`.
@@ -747,77 +725,11 @@ You may also download or copy over individual mods using the `MODS` environment
docker run -d -e MODS=https://www.example.com/mods/mod1.jar,/plugins/common,/plugins/special/mod2.jar ... docker run -d -e MODS=https://www.example.com/mods/mod1.jar,/plugins/common,/plugins/special/mod2.jar ...
### ForgeAPI usage to use non-version specific projects ### Generic pack file
**NOTE:** This potentially could lead to unexpected behavior if the Mod receives an update with unexpected behavior. To install all of the server content (jars, mods, plugins, configs, etc) from a zip file, such as a CurseForge modpack that is missing a server start script, then set `GENERIC_PACK` to the container path of the zip file. That, combined with `TYPE`, allows for custom content along with container managed server download and install.
This is more complicated because you will be pulling/using the latest mod for the release of your game. To get started make sure you have a [CursedForge API Key](https://docs.curseforge.com/#getting-started). Then use the environmental parameters in your docker build. If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of zip file paths and/or URLs to zip files.
Parameters to use the ForgeAPI:
* `MODS_FORGEAPI_KEY` - Required
* `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
Example of expected forge api project ids, releases, and key:
```yaml
MODS_FORGEAPI_PROJECTIDS: 306612,256717
MODS_FORGEAPI_RELEASES: Release
MODS_FORGEAPI_KEY: $WRX...
```
Example of expected ForgeAPI file format.
**Field Description**:
* `name` is currently unused, but can be used to document each entry.
* `projectId` id is the id found on the CurseForge website for a particular mod
* `releaseType` 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
[
{
"name": "fabric api",
"projectId": "306612",
"releaseType": "release"
},
{
"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"
}
]
```
### Generic pack files
To install all the server content (jars, mods, plugins, configs, etc.) from a zip or tgz file, then set `GENERIC_PACK` to the container path or URL of the archive file. This can also be used to apply a CurseForge modpack that is missing a server start script and/or Forge installer.
If multiple generic packs need to be applied together, set `GENERIC_PACKS` instead, with a comma separated list of archive file paths and/or URLs to files.
To avoid repetition, each entry will be prefixed by the value of `GENERIC_PACKS_PREFIX` and suffixed by the value of `GENERIC_PACKS_SUFFIX`, both of which are optional. For example, the following variables
```
GENERIC_PACKS=configs-v9.0.1,mods-v4.3.6
GENERIC_PACKS_PREFIX=https://cdn.example.org/
GENERIC_PACKS_SUFFIX=.zip
```
would expand to `https://cdn.example.org/configs-v9.0.1.zip,https://cdn.example.org/mods-v4.3.6.zip`.
If applying large generic packs, the update check can be time-consuming since a SHA1 checksum is compared. To skip the update check set `SKIP_GENERIC_PACK_UPDATE_CHECK` to "true". Conversely, the generic pack(s) can be forced to be applied without comparing the checksum by setting `FORCE_GENERIC_PACK_UPDATE` to "true".
### Mod/Plugin URL Listing File ### Mod/Plugin URL Listing File
@@ -857,19 +769,23 @@ before unpacking new content from the MODPACK or MODS.
### Downloadable world ### Downloadable world
Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP or compressed TAR file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format. Instead of mounting the `/data` volume, you can instead specify the URL of a ZIP file containing an archived world. It will be searched for a file `level.dat` and the containing subdirectory moved to the directory named by `$LEVEL`. This means that most of the archived Minecraft worlds downloadable from the Internet will already be in the correct format.
docker run -d -e WORLD=http://www.example.com/worlds/MySave.zip ... docker run -d -e WORLD=http://www.example.com/worlds/MySave.zip ...
**NOTE:** This URL must be accessible from inside the container. Therefore, you should use an IP address or a globally resolvable FQDN, or else the name of a linked container. **NOTE:** This URL must be accessible from inside the container. Therefore,
you should use an IP address or a globally resolvable FQDN, or else the
name of a linked container.
**NOTE:** If the archive contains more than one `level.dat`, then the one to select can be picked with `WORLD_INDEX`, which defaults to 1. **NOTE:** If the archive contains more than one `level.dat`, then the one to select can be picked with `WORLD_INDEX`, which defaults to 1.
### Cloning world from a container path ### Cloning world from a container path
The `WORLD` option can also be used to reference a directory, zip file, or compressed tar file that will be used as a source to clone or extract the world directory. The `WORLD` option can also be used to reference a directory or zip file that will be used as a source to clone or unzip the world directory.
For example, the following would initially clone the world's content from `/worlds/basic`. Also notice in the example that you should use a read-only volume attachment to ensure the clone source remains pristine. For example, the following would initially clone the world's content
from `/worlds/basic`. Also notice in the example that you can use a
read-only volume attachment to ensure the clone source remains pristine.
``` ```
docker run ... -v $HOME/worlds:/worlds:ro -e WORLD=/worlds/basic docker run ... -v $HOME/worlds:/worlds:ro -e WORLD=/worlds/basic
@@ -882,87 +798,6 @@ The following diagram shows how this option can be used in a compose deployment
### Overwrite world on start ### Overwrite world on start
The world will only be downloaded or copied if it doesn't exist already. Set `FORCE_WORLD_COPY=TRUE` to force overwrite the world on every server start. The world will only be downloaded or copied if it doesn't exist already. Set `FORCE_WORLD_COPY=TRUE` to force overwrite the world on every server start.
### Datapacks
Datapacks can be installed in a similar manner to mods/plugins. There are many environment variables which function in the same way they do for [mods](#working-with-mods-and-plugins):
* `DATAPACKS`
* `DATAPACKS_FILE`
* `REMOVE_OLD_DATAPACKS`
* `REMOVE_OLD_DATAPACKS_DEPTH`
* `REMOVE_OLD_DATAPACKS_INCLUDE`
* `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.
Datapacks will be placed in `/data/$LEVEL/datapacks`
Resourcepacks will be placed in `/data/resourcepacks`
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:
**Note**: ResourcePacks, DataPacks, and CraftingTweaks all have separate sharecodes
```yaml
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
```
Example of expected Vanillatweaks file format:
```yaml
VANILLATWEAKS_FILE: /config/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
```
Datapacks Json:
```json
{
"version": "1.18",
"packs": {
"survival": [
"graves",
"multiplayer sleep",
],
"items": ["armored elytra"]
}
}
```
Resourcepacks Json:
```json
{
"type": "resourcepacks",
"version": "1.18",
"packs": {
"aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
},
"result": "ok"
}
```
CraftingTweaks Json:
```json
{
"type": "craftingtweaks",
"version": "1.18",
"packs": {
"quality of life": [
"dropper to dispenser",
"double slabs",
"back to blocks"
]
},
"result": "ok"
}
```
## Server configuration ## 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. 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.
@@ -1011,35 +846,30 @@ values.
> **NOTE** it is very important to set this with servers exposed to the internet where you want only limited players to join. > **NOTE** it is very important to set this with servers exposed to the internet where you want only limited players to join.
To whitelist players for your Minecraft server, you can: To whitelist players for your Minecraft server, pass the Minecraft usernames separated by commas via the `WHITELIST` environment variable, such as
- Provide the url or path to a whitelist file via `WHITELIST_FILE` environment variable
`docker run -d -e WHITELIST_FILE=/extra/whitelist.json ...`
- Provide a list of usernames and/or UUIDs separated by commas via the `WHITELIST` environment variable
`docker run -d -e WHITELIST=user1,uuid2 ...`
To enforce the whitelist and auto-kick players not included in whitelist configuration, set `ENFORCE_WHITELIST=TRUE`. **By default** any user can join your Minecraft server if it's publicly accessible, regardless of your whitelist configuration. docker run -d -e WHITELIST=user1,user2 ...
If whitelist configuration already exists, `WHITELIST_FILE` will not be retrieved and any usernames in `WHITELIST` are **added** to the whitelist configuration. You can enforce regeneration of the whitelist on each server startup by setting `OVERRIDE_WHITELIST` to "true". This will delete the whitelist file before processing whitelist configuration. or
> NOTE: You can provide both `WHITELIST_FILE` and `WHITELIST`, which are processed in that order. docker run -d -e WHITELIST=uuid1,uuid2 ...
> NOTE: UUIDs passed via `WHITELIST` need to be the dashed variant, otherwise it not be recognised and instead added as a username. If the `WHITELIST` environment variable is not used, any user can join your Minecraft server if it's publicly accessible.
> If running Minecraft 1.7.5 or earlier, these variables will apply to `white-list.txt`, with 1.7.6 implementing support for `whitelist.json`. Make sure your `WHITELIST_FILE` is in the appropriate format. > NOTE: When using uuids in the whitelist, please make sure it is the dashed variant otherwise it will not parse correctly.
If either `WHITELIST_FILE` or `WHITELIST` is provided, the server property `white-list` is automatically set to `true`, enabline whitelist functionality. Alternatively you can set `ENABLE_WHITELIST=TRUE` to only set the server property `white-list` without modifying the whitelist file. In this case the whitelist can be managed using the `whitelist add` and `whitelist remove` commands. Remember you can set enforcement via the `ENFORCE_WHITELIST` variable. > NOTE: When `WHITELIST` is used the server properties `white-list` and `whitelist` will automatically get set to `true`.
> By default, the players in `WHITELIST` are **added** to the final `whitelist.json` file by the Minecraft server. If you set `OVERRIDE_WHITELIST` to "true" then the `whitelist.json` file will be recreated on each server startup.
Alternatively, you can set `ENABLE_WHITELIST=true` to only set the server properties `white-list` and `whitelist` without modifying the whitelist file. In this case the whitelist is solely managed using the `whitelist add` and `whitelist remove` commands.
### Op/Administrator Players ### Op/Administrator Players
Similar to the whitelist, to add users as operators (aka adminstrators) to your Minecraft server, you can: To add more "op" (aka adminstrator) users to your Minecraft server, pass the Minecraft usernames separated by commas via the `OPS` environment variable, such as
- Provide te url or path to an ops file via `OPS_FILE` environment variable
`docker run -d -e OPS_FILE=https://config.example.com/extra/ops.json ...`
- Provide a list of usernames and/or UUIDs separated by commas via the `OPS` environment variable
`docker run -d -e OPS=user1,uuid2 ...`
If ops configuration already exists, `OPS_FILE` will not be retrieved and any usernames in `OPS` are **added** to the ops configuration. You can enforce regeneration of the ops configuration on each server startup by setting `OVERRIDE_OPS` to "true". This will delete the ops file before processing ops configuration. docker run -d -e OPS=user1,user2 ...
> Similar to whitelists, you can provide both `OPS_FILE` and `OPS`, and Minecraft 1.7.5 or earlier will use `ops.txt` rather than `ops.json`. > By default, the players in `OPS` are **added** to the final `ops.json` file by the Minecraft server. If you set `OVERRIDE_OPS` to "true" then the `ops.json` file will be recreated on each server startup.
### Server icon ### Server icon
@@ -1497,8 +1327,6 @@ If you would like to `docker attach` to the Minecraft server console with color
> This will bypass graceful server shutdown handling when using `docker stop`, so be sure the server console's `stop` command. > This will bypass graceful server shutdown handling when using `docker stop`, so be sure the server console's `stop` command.
> >
> Make to enable stdin and tty with `-it` when using `docker run` or `stdin_open: true` and `tty: true` when using docker compose. > Make to enable stdin and tty with `-it` when using `docker run` or `stdin_open: true` and `tty: true` when using docker compose.
>
> This feature is incompatible with Autopause and cannot be set when `ENABLE_AUTOPAUSE=true`.
### Server Shutdown Options ### Server Shutdown Options
@@ -1559,6 +1387,10 @@ 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. 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 ### HTTP Proxy
You may configure the use of an HTTP/HTTPS proxy by passing the proxy's URL via the `PROXY` You may configure the use of an HTTP/HTTPS proxy by passing the proxy's URL via the `PROXY`
@@ -1583,28 +1415,6 @@ When the container is signalled to stop, the Minecraft process wrapper will atte
### Setup only ### Setup only
If you are using a host-attached data directory, then you can have the image setup the Minecraft server files and stop prior to launching the server process by setting `SETUP_ONLY` to `true`. If you are using a host-attached data directory, then you can have the image setup the Minecraft server files and stop prior to launching the server process by setting `SETUP_ONLY` to `true`.
### Enable Flare Flags
To enable the JVM flags required to fully support the [Flare profiling suite](https://blog.airplane.gg/flare), set the following variable:
-e USE_FLARE_FLAGS=true
Flare is built-in to Airplane/Pufferfish/Purpur, and is available in [plugin form](https://github.com/TECHNOVE/FlarePlugin) for other server types.
### Enable timestamps in init logs
Before the container starts the Minecraft Server its output is prefixed with `[init]`, such as
```
[init] Starting the Minecraft server...
```
To also include the timestamp with each log, set `LOG_TIMESTAMP` to "true". The log output will then look like:
```
[init] 2022-02-05 16:58:33+00:00 Starting the Minecraft server...
```
## Autopause ## Autopause
@@ -1634,10 +1444,6 @@ Enable the Autopause functionality by setting:
-e ENABLE_AUTOPAUSE=TRUE -e ENABLE_AUTOPAUSE=TRUE
``` ```
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: The following environment variables define the behaviour of auto-pausing:
* `AUTOPAUSE_TIMEOUT_EST`, default `3600` (seconds) * `AUTOPAUSE_TIMEOUT_EST`, default `3600` (seconds)
describes the time between the last client disconnect and the pausing of the process (read as timeout established) describes the time between the last client disconnect and the pausing of the process (read as timeout established)
@@ -1650,28 +1456,6 @@ The following environment variables define the behaviour of auto-pausing:
* `AUTOPAUSE_KNOCK_INTERFACE`, default `eth0` * `AUTOPAUSE_KNOCK_INTERFACE`, default `eth0`
<br>Describes the interface passed to the `knockd` daemon. If the default interface does not work, run the `ifconfig` command inside the container and derive the interface receiving the incoming connection from its output. The passed interface must exist inside the container. Using the loopback interface (`lo`) does likely not yield the desired results. <br>Describes the interface passed to the `knockd` daemon. If the default interface does not work, run the `ifconfig` command inside the container and derive the interface receiving the incoming connection from its output. The passed interface must exist inside the container. Using the loopback interface (`lo`) does likely not yield the desired results.
## Autostop
An option to stop the server after a specified time has been added for niche applications (e.g. billing saving on AWS Fargate). The function is incompatible with the Autopause functionality, as they basically cancel out each other.
Note that the docker container variables have to be set accordingly (restart policy set to "no") and that the container has to be manually restarted.
A starting, example compose file has been provided in [examples/docker-compose-autostop.yml](examples/docker-compose-autostop.yml).
Enable the Autostop functionality by setting:
```
-e ENABLE_AUTOSTOP=TRUE
```
The following environment variables define the behaviour of auto-stopping:
* `AUTOSTOP_TIMEOUT_EST`, default `3600` (seconds)
describes the time between the last client disconnect and the stopping of the server (read as timeout established)
* `AUTOSTOP_TIMEOUT_INIT`, default `1800` (seconds)
describes the time between server start and the stopping of the server, when no client connects inbetween (read as timeout initialized)
* `AUTOSTOP_PERIOD`, default `10` (seconds)
describes period of the daemonized state machine, that handles the stopping of the server
## Running on RaspberryPi ## Running on RaspberryPi
To run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags [list in the Java version section](#running-minecraft-server-on-different-java-version) that specify `armv7` for the architecture, which includes `itzg/minecraft-server:latest`. To run this image on a RaspberryPi 3 B+, 4, or newer, use any of the image tags [list in the Java version section](#running-minecraft-server-on-different-java-version) that specify `armv7` for the architecture, which includes `itzg/minecraft-server:latest`.

View File

@@ -12,4 +12,4 @@ if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
exit 1 exit 1
fi fi
gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'" echo "$@" > "${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"

View File

@@ -3,6 +3,12 @@
# Use this variable to indicate a list of branches that docker hub is watching # Use this variable to indicate a list of branches that docker hub is watching
branches_list=( branches_list=(
'java8' 'java8'
'java8-multiarch'
'java8-openj9'
'java11'
'java11-openj9'
'java16-openj9'
'java17'
) )
function TrapExit { function TrapExit {
@@ -124,28 +130,3 @@ EOL
fi fi
done done
if [[ $tag ]]; then
if [ -f "$HOME/.github.env" ]; then
source "$HOME/.github.env"
if [[ $GITHUB_TOKEN ]]
then
auth=(-u ":$GITHUB_TOKEN")
base=https://api.github.com
: "${owner:=itzg}"
: "${repo:=docker-minecraft-server}"
read -r -d '' releaseBody << EOF
{
"tag_name": "$tag",
"name": "$tag",
"generate_release_notes": true
}
EOF
if ! curl "${auth[@]}" -H "Accept: application/vnd.github.v3+json" \
"${base}/repos/${owner}/${repo}/releases" -d "$releaseBody"; then
echo "ERROR failed to create github release $tag"
exit 1
fi
fi
fi
fi

View File

@@ -1,20 +0,0 @@
version: '3.8'
services:
minecraft:
image: itzg/minecraft-server
ports:
- "25565:25565"
volumes:
- "mc:/data"
environment:
EULA: "TRUE"
ENABLE_AUTOSTOP: "TRUE"
# More aggressive settings for demo purposes
AUTOSTOP_TIMEOUT_INIT: "30"
AUTOSTOP_TIMEOUT_EST: "20"
# Important not to auto-restart the server!!!
restart: "no"
volumes:
mc: {}

View File

@@ -13,7 +13,6 @@ services:
VERSION: ${VERSION:-1.17.1} VERSION: ${VERSION:-1.17.1}
FORGEVERSION: ${FORGEVERSION:-37.0.90} FORGEVERSION: ${FORGEVERSION:-37.0.90}
GENERIC_PACK: /modpacks/${MODPACK:-Server-Files-0.0.21.zip} GENERIC_PACK: /modpacks/${MODPACK:-Server-Files-0.0.21.zip}
REMOVE_OLD_MODS: "${REMOVE_OLD_MODS:-false}"
ports: ports:
- "25565:25565" - "25565:25565"

View File

@@ -1,19 +1,18 @@
version: '3.8' version: '3.8'
services: services:
mc: mc:
image: itzg/minecraft-server image: itzg/minecraft-server
container_name: paper
environment: environment:
EULA: "true" EULA: "true"
ENABLE_RCON: "true"
TYPE: PAPER TYPE: PAPER
VIEW_DISTANCE: 10 VERSION: 1.9.4
MEMORY: 2G # needed for Paper versions before 1.14
CONSOLE: "false" CONSOLE: "false"
ports: ports:
- 25565:25565 - 25565:25565
volumes: volumes:
- mc-paper:/data - mc-paper:/data
restart: unless-stopped
volumes: volumes:
mc-paper: mc-paper:

View File

@@ -1,27 +0,0 @@
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"

View File

@@ -1,15 +0,0 @@
{
"version": "1.18",
"packs": {
"survival": [
"graves",
"multiplayer sleep",
"afk display",
"armor statues",
"unlock all recipes",
"fast leaf decay",
"coordinates hud"
],
"items": ["armored elytra"]
}
}

View File

@@ -5,15 +5,15 @@ current_uptime() {
} }
java_running() { java_running() {
[[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]]
} }
java_process_exists() { java_process_exists() {
[[ -n "$(ps -a -o comm | grep 'java')" ]] [[ -n "$(ps -ax -o comm | grep 'java')" ]]
} }
rcon_client_exists() { rcon_client_exists() {
[[ -n "$(ps -a -o comm | grep 'rcon-cli')" ]] [[ -n "$(ps -ax -o comm | grep 'rcon-cli')" ]]
} }
mc_server_listening() { mc_server_listening() {

View File

@@ -3,12 +3,12 @@
[unpauseMCServer-server] [unpauseMCServer-server]
sequence = 25565 sequence = 25565
seq_timeout = 1 seq_timeout = 1
command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
tcpflags = syn tcpflags = syn
[unpauseMCServer-rcon] [unpauseMCServer-rcon]
sequence = 25575 sequence = 25575
seq_timeout = 1 seq_timeout = 1
command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
tcpflags = syn tcpflags = syn
[unpauseMCServer-bedrock] [unpauseMCServer-bedrock]
sequence = 19132:udp sequence = 19132:udp

View File

@@ -2,7 +2,7 @@
. /start-utils . /start-utils
if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then
# save world # save world
rcon-cli save-all >/dev/null rcon-cli save-all >/dev/null

View File

@@ -2,7 +2,7 @@
. /start-utils . /start-utils
if [[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then
logAutopauseAction "Knocked, resuming Java process" logAutopauseAction "Knocked, resuming Java process"
pkill -CONT java pkill -CONT java
fi fi

View File

@@ -1,69 +0,0 @@
#!/bin/bash
# needed for the clients connected function residing in autopause
. /autopause/autopause-fcns.sh
. ${SCRIPTS:-/}start-utils
# wait for java process to be started
while :
do
if java_process_exists ; then
break
fi
sleep 0.1
done
STATE=INIT
while :
do
case X$STATE in
XINIT)
# Server startup
if mc_server_listening ; then
TIME_THRESH=$(($(current_uptime)+$AUTOSTOP_TIMEOUT_INIT))
logAutostop "MC Server listening for connections - stopping in $AUTOSTOP_TIMEOUT_INIT seconds"
STATE=II
fi
;;
XII)
# Initial idle
if java_clients_connected ; then
logAutostop "Client connected - waiting for disconnect"
STATE=E
else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutostop "No client connected since startup - stopping server"
/autostop/stop.sh
exit 0
fi
fi
;;
XE)
# Established
if ! java_clients_connected ; then
TIME_THRESH=$(($(current_uptime)+$AUTOSTOP_TIMEOUT_EST))
logAutostop "All clients disconnected - stopping in $AUTOSTOP_TIMEOUT_EST seconds"
STATE=I
fi
;;
XI)
# Idle
if java_clients_connected ; then
logAutostop "Client reconnected - waiting for disconnect"
STATE=E
else
if [[ $(current_uptime) -ge $TIME_THRESH ]] ; then
logAutostop "No client reconnected - stopping"
/autostop/stop.sh
exit 0
fi
fi
;;
*)
logAutostop "Error: invalid state: $STATE"
;;
esac
sleep $AUTOSTOP_PERIOD
done

View File

@@ -1,6 +0,0 @@
#!/bin/bash
. /start-utils
logAutostopAction "Stopping Java process"
kill -SIGTERM 1

View File

@@ -40,7 +40,7 @@ if ! isTrue "${SKIP_SUDO:-false}" && [ $(id -u) = 0 ]; then
echo 'hosts: files dns' > /etc/nsswitch.conf echo 'hosts: files dns' > /etc/nsswitch.conf
fi fi
exec su-exec ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration "$@" exec gosu ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration $@
else else
exec ${SCRIPTS:-/}start-configuration "$@" exec ${SCRIPTS:-/}start-configuration $@
fi fi

View File

@@ -1,34 +0,0 @@
#!/bin/bash
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
: "${SERVER_PORT:=25565}"
export SERVER_PORT
log "Autostop functionality enabled"
isDebugging && set -x
if ! [[ $AUTOSTOP_PERIOD =~ ^[0-9]+$ ]]; then
AUTOSTOP_PERIOD=10
export AUTOSTOP_PERIOD
log "Warning: AUTOSTOP_PERIOD is not numeric, set to 10 (seconds)"
fi
if [ "$AUTOSTOP_PERIOD" -eq "0" ] ; then
AUTOSTOP_PERIOD=10
export AUTOSTOP_PERIOD
log "Warning: AUTOSTOP_PERIOD must not be 0, set to 10 (seconds)"
fi
if ! [[ $AUTOSTOP_TIMEOUT_EST =~ ^[0-9]+$ ]] ; then
AUTOSTOP_TIMEOUT_EST=3600
export AUTOSTOP_TIMEOUT_EST
log "Warning: AUTOSTOP_TIMEOUT_EST is not numeric, set to 3600 (seconds)"
fi
if ! [[ $AUTOSTOP_TIMEOUT_INIT =~ ^[0-9]+$ ]] ; then
AUTOSTOP_TIMEOUT_INIT=1800
export AUTOSTOP_TIMEOUT_INIT
log "Warning: AUTOSTOP_TIMEOUT_INIT is not numeric, set to 1800 (seconds)"
fi
/autostop/autostop-daemon.sh &

View File

@@ -3,7 +3,7 @@ set -euo pipefail
IFS=$'\n\t' IFS=$'\n\t'
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils" . ${SCRIPTS:-/}start-utils
: "${EULA:=}" : "${EULA:=}"
: "${PROXY:=}" : "${PROXY:=}"
@@ -32,15 +32,6 @@ if [ ! -e /data/eula.txt ]; then
writeEula writeEula
fi fi
if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${EXEC_DIRECTLY:-false}"; then
log "EXEC_DIRECTLY=true is incompatible with ENABLE_AUTOPAUSE=true"
exit 1
fi
if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${ENABLE_AUTOSTOP}"; then
log "ENABLE_AUTOPAUSE=true is incompatible with ENABLE_AUTOSTOP=true"
exit 1
fi
if [[ $PROXY ]]; then if [[ $PROXY ]]; then
export http_proxy="$PROXY" export http_proxy="$PROXY"
@@ -66,12 +57,9 @@ if [[ $RCON_PASSWORD_FILE ]]; then
log "" log ""
fi 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 if ! which java > /dev/null; then
log "ERROR: PATH should not be explicitly passed into the container" log "Fixing PATH to include java"
log " Remove configuration of that variable." PATH="${PATH}:/opt/java/openjdk/bin"
exit 1
fi fi
export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json export VERSIONS_JSON=https://launchermeta.mojang.com/mc/game/version_manifest.json
@@ -104,10 +92,6 @@ if isTrue "${ENABLE_AUTOPAUSE}"; then
${SCRIPTS:-/}start-autopause ${SCRIPTS:-/}start-autopause
fi fi
if isTrue "${ENABLE_AUTOSTOP}"; then
${SCRIPTS:-/}start-autostop
fi
if versionLessThan 1.7; then if versionLessThan 1.7; then
echo " echo "
MC_HEALTH_EXTRA_ARGS=( MC_HEALTH_EXTRA_ARGS=(
@@ -119,31 +103,39 @@ fi
log "Resolving type given ${TYPE}" log "Resolving type given ${TYPE}"
case "${TYPE^^}" in case "${TYPE^^}" in
*BUKKIT|SPIGOT) *BUKKIT|SPIGOT)
exec "${SCRIPTS:-/}start-deployBukkitSpigot" "$@" exec ${SCRIPTS:-/}start-deployBukkitSpigot "$@"
;; ;;
PAPER) PAPER)
exec "${SCRIPTS:-/}start-deployPaper" "$@" exec ${SCRIPTS:-/}start-deployPaper "$@"
;; ;;
FORGE) FORGE)
evaluateJavaCompatibilityForForge if versionLessThan 1.17; then
exec "${SCRIPTS:-/}start-deployForge" "$@" log "**********************************************************************"
log "WARNING: The image tag itzg/minecraft-server:java8 is recommended"
log " since some mods require Java 8"
log " Exception traces reporting ClassCastException: class jdk.internal.loader.ClassLoaders\$AppClassLoader"
log " can be fixed with java8"
log "**********************************************************************"
fi
exec ${SCRIPTS:-/}start-deployForge "$@"
;; ;;
FABRIC) FABRIC)
exec "${SCRIPTS:-/}start-deployFabric" "$@" exec ${SCRIPTS:-/}start-deployFabric "$@"
;; ;;
FTBA) FTBA)
log "ERROR: TYPE=FTBA is not supported with this image variant." exec ${SCRIPTS:-/}start-deployFTBA "$@"
log " Use itzg/minecraft-server:java8-multiarch instead."
exit 1
;; ;;
FTB|CURSEFORGE) FTB|CURSEFORGE)
evaluateJavaCompatibilityForForge log "**********************************************************************"
exec "${SCRIPTS:-/}start-deployCF" "$@" log "NOTE: Some mods and modpacks may require Java 8."
log " If so, use itzg/minecraft-server:java8"
log "**********************************************************************"
exec ${SCRIPTS:-/}start-deployCF "$@"
;; ;;
VANILLA) VANILLA)
@@ -151,50 +143,48 @@ case "${TYPE^^}" in
;; ;;
SPONGEVANILLA) SPONGEVANILLA)
exec "${SCRIPTS:-/}start-deploySpongeVanilla" "$@" exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@"
;; ;;
CUSTOM) CUSTOM)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployCustom "$@"
exec "${SCRIPTS:-/}start-deployCustom" "$@"
;; ;;
MAGMA) MAGMA)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployMagma "$@"
exec "${SCRIPTS:-/}start-deployMagma" "$@"
;; ;;
MOHIST) MOHIST)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployMohist "$@"
exec "${SCRIPTS:-/}start-deployMohist" "$@"
;; ;;
CATSERVER) CATSERVER)
evaluateJavaCompatibilityForForge exec ${SCRIPTS:-/}start-deployCatserver "$@"
exec "${SCRIPTS:-/}start-deployCatserver" "$@"
;; ;;
PURPUR) PURPUR)
exec "${SCRIPTS:-/}start-deployPurpur" "$@" exec ${SCRIPTS:-/}start-deployPurpur "$@"
;; ;;
AIRPLANE) AIRPLANE)
exec "${SCRIPTS:-/}start-deployAirplane" "$@" exec ${SCRIPTS:-/}start-deployAirplane "$@"
;;
PUFFERFISH)
exec "${SCRIPTS:-/}start-deployPufferfish" "$@"
;; ;;
CANYON) CANYON)
exec "${SCRIPTS:-/}start-deployCanyon" "$@" exec ${SCRIPTS:-/}start-deployCanyon "$@"
;; ;;
LIMBO) LIMBO)
exec "${SCRIPTS:-/}start-deployLimbo" "$@" exec ${SCRIPTS:-/}start-deployLimbo "$@"
;; ;;
CRUCIBLE) CRUCIBLE)
log "**********************************************************************"
log "WARNING: The image tag itzg/minecraft-server:java8 is recommended"
log " since some mods require Java 8"
log " Exception traces reporting ClassCastException: class jdk.internal.loader.ClassLoaders\$AppClassLoader"
log " can be fixed with java8"
log "**********************************************************************"
exec "${SCRIPTS:-/}start-deployCrucible" "$@" exec "${SCRIPTS:-/}start-deployCrucible" "$@"
;; ;;
@@ -202,7 +192,7 @@ case "${TYPE^^}" in
log "Invalid type: '$TYPE'" log "Invalid type: '$TYPE'"
log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only)," log "Must be: VANILLA, FORGE, BUKKIT, SPIGOT, PAPER, FTBA (multiarch-only),"
log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM," log " CURSEFORGE, SPONGEVANILLA, PURPUR, CUSTOM,"
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE" log " MAGMA, MOHIST, CATSERVER, AIRPLANE, CANYON, LIMBO, CRUCIBLE"
exit 1 exit 1
;; ;;

View File

@@ -1,46 +1,52 @@
#!/bin/bash #!/bin/bash
. ${SCRIPTS:-/}start-utils
set -euo pipefail set -euo pipefail
isDebugging && set -x
IFS=$'\n\t' IFS=$'\n\t'
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "PURPUR" ] ; then . ${SCRIPTS:-/}start-utils
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=PURPUR." isDebugging && set -x
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.16" ] && [ "${VERSION}" != "1.17" ] && [ "${VERSION}" != "PURPUR" ] && [ "${VERSION}" != "PURPUR-1.16" ] ; then
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=1.17, VERSION=1.16, VERSION=PURPUR or VERSION=PURPUR-1.16. Note that these are branches, not #.#.# versions."
exit 1 exit 1
fi fi
: ${AIRPLANE_BUILD:=lastSuccessfulBuild}
: ${AIRPLANE_TYPE:=airplane} : ${AIRPLANE_TYPE:=airplane}
if [ "${VERSION}" = "LATEST" ] ; then if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.17" ]; then
AIRPLANE_TYPE="airplane" AIRPLANE_BRANCH="1.17"
fi
if [ "${VERSION}" = "1.16" ]; then
AIRPLANE_BRANCH="1.16"
fi fi
if [ "${VERSION}" = "PURPUR" ]; then if [ "${VERSION}" = "PURPUR" ]; then
AIRPLANE_BRANCH="Purpur-1.17"
AIRPLANE_TYPE="airplanepurpur" AIRPLANE_TYPE="airplanepurpur"
fi fi
log "Using ${AIRPLANE_TYPE} 1.17.1 (1.18 unsupported - use Paper/Pufferfish/Purpur for newer versions)" if [ "${VERSION}" = "PURPUR-1.16" ]; then
AIRPLANE_BRANCH="Purpur-1.16"
AIRPLANE_TYPE="airplanepurpur"
fi
export SERVER=${AIRPLANE_TYPE}-1.17.1.jar log "Using Airplane-${AIRPLANE_BRANCH} branch"
log "Removing old Airplane versions ..." export SERVER=airplane-${AIRPLANE_BRANCH}-${AIRPLANE_BUILD}.jar
shopt -s nullglob
for f in airplane*.jar; do
[[ $f != $SERVER ]] && rm $f
done
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
downloadUrl="https://airplane.gg/dl/launcher-${AIRPLANE_TYPE}1.17.1.jar" downloadUrl="https://ci.tivy.ca/job/Airplane-${AIRPLANE_BRANCH}/${AIRPLANE_BUILD}/artifact/launcher-${AIRPLANE_TYPE}.jar"
log "Downloading Airplane from $downloadUrl ..." log "Downloading Airplane from $downloadUrl ..."
if ! get -o "$SERVER" "$downloadUrl"; then curl -fsSL -o "$SERVER" "$downloadUrl"
if [ ! -f "$SERVER" ]; then
log "ERROR: failed to download from $downloadUrl (status=$?)" log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3 exit 3
fi fi
fi fi
# Normalize on Spigot for later operations # Normalize on Spigot for later operations
export FAMILY=SPIGOT export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-spiget" "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -126,6 +126,7 @@ else
fi fi
# Normalize on Spigot for operations below # Normalize on Spigot for operations below
export FAMILY=SPIGOT export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -35,37 +35,11 @@ FTB_SERVER_MOD=${FTB_SERVER_MOD:-$CF_SERVER_MOD}
log "Looking for Feed-The-Beast / CurseForge server modpack." log "Looking for Feed-The-Beast / CurseForge server modpack."
requireVar FTB_SERVER_MOD requireVar FTB_SERVER_MOD
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 if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
downloadModpack if ! [ -f "${FTB_SERVER_MOD}" ]; then
log "ERROR unable to find requested modpack file ${FTB_SERVER_MOD}"
exit 2
fi
needsInstall=true needsInstall=true
installMarker=/data/.curseforge-installed installMarker=/data/.curseforge-installed
@@ -73,7 +47,7 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
if [ "$(cat $installMarker)" != "${FTB_SERVER_MOD}" ]; then if [ "$(cat $installMarker)" != "${FTB_SERVER_MOD}" ]; then
log "Upgrading modpack" log "Upgrading modpack"
serverJar=$(find "${FTB_BASE_DIR}" -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print) serverJar=$(find "${FTB_BASE_DIR}" -not -name "forge*installer.jar" -name "forge*.jar")
if [[ "${serverJar}" ]]; then if [[ "${serverJar}" ]]; then
rm -rf "$(dirname "${serverJar}")"/{mods,*.jar,libraries,resources,scripts,config} rm -rf "$(dirname "${serverJar}")"/{mods,*.jar,libraries,resources,scripts,config}
fi fi
@@ -111,8 +85,6 @@ if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
exit 2 exit 2
fi fi
forgeInstallerJar=$(ls -t "${forgeInstallerJar}" | head -1)
log "Installing forge server" log "Installing forge server"
dirOfInstaller=$(dirname "${forgeInstallerJar}") dirOfInstaller=$(dirname "${forgeInstallerJar}")
(cd "${dirOfInstaller}"; java -jar "$(basename "${forgeInstallerJar}")" --installServer) (cd "${dirOfInstaller}"; java -jar "$(basename "${forgeInstallerJar}")" --installServer)
@@ -160,9 +132,32 @@ fi
# also check for the start script rather than just the folder # 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 # this allows saving just the world separate from the rest of the data directory
if [[ $startScriptCount = 0 ]]; then if [[ $startScriptCount = 0 ]]; then
downloadModpack
srv_modpack=${FTB_SERVER_MOD} 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} ..." log "Unpacking FTB server modpack ${srv_modpack} ..."
mkdir -p "${FTB_BASE_DIR}" mkdir -p "${FTB_BASE_DIR}"
unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}' unzip -o "${srv_modpack}" -d "${FTB_BASE_DIR}" | awk '{printf "."} END {print ""}'
@@ -238,5 +233,4 @@ elif [ -e "${FTB_DIR}/Install.sh" ]; then
popd popd
fi fi
export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -43,6 +43,7 @@ if [ ! -f "$SERVER" ]; then
fi fi
# Normalize on Spigot for later operations # Normalize on Spigot for later operations
export FAMILY=SPIGOT export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
set -o pipefail set -o pipefail
set -e set -e
@@ -27,6 +26,7 @@ if [ ! -f ${SERVER} ]; then
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId} curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId}
fi fi
export FAMILY=HYBRID export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-setupWorld" "$@" # Continue to Final Setup
exec ${SCRIPTS:-/}start-setupWorld "$@"

View File

@@ -47,7 +47,6 @@ if [ ! -d "$librariesDir" ]; then
exit 1 exit 1
fi fi
mkdir "$librariesDir"
if ! unzip /tmp/libraries.zip -d "$librariesDir"; then if ! unzip /tmp/libraries.zip -d "$librariesDir"; then
log "ERROR: failed to unzip Crucible libraries" log "ERROR: failed to unzip Crucible libraries"
exit 1 exit 1
@@ -56,6 +55,6 @@ if [ ! -d "$librariesDir" ]; then
fi fi
export SERVER export SERVER
export FAMILY=HYBRID export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@" exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

View File

@@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x isDebugging && set -x
if isURL ${CUSTOM_SERVER}; then if isURL ${CUSTOM_SERVER}; then
@@ -31,6 +30,6 @@ else
fi fi
export FAMILY=HYBRID export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-setupWorld $@ exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -2,8 +2,7 @@
ftbInstallMarker=".ftb-installed" ftbInstallMarker=".ftb-installed"
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x isDebugging && set -x
set -e set -e
@@ -80,6 +79,4 @@ if ! [ -v SERVER ]; then
exit 2 exit 2
fi fi
export FAMILY=FORGE
exec ${SCRIPTS:-/}start-setupWorld $@ exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -2,31 +2,27 @@
set -eu set -eu
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils" . ${SCRIPTS:-/}start-utils
requireVar VANILLA_VERSION requireVar VANILLA_VERSION
export TYPE=FABRIC export TYPE=FABRIC
: "${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}" export SERVER=fabric-server-${VANILLA_VERSION}.jar
: "${FABRIC_INSTALLER:=}"
: "${FABRIC_INSTALLER_URL:=}"
: "${FABRIC_LOADER_VERSION:=LATEST}"
isDebugging && set -x isDebugging && set -x
log "Checking Fabric version information." if [[ ! -e ${SERVER} ]]; then
if [[ $FABRIC_INSTALLER ]]; then
FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER" | mc-image-helper hash)
elif [[ $FABRIC_INSTALLER_URL ]]; then
FABRIC_INSTALLER_VERSION=$(echo -n "$FABRIC_INSTALLER_URL" | mc-image-helper hash)
elif [[ ${FABRIC_INSTALLER_VERSION^^} = LATEST ]]; then
FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
fi
export SERVER=fabric-server-${VANILLA_VERSION}-${FABRIC_INSTALLER_VERSION}.jar : ${FABRIC_INSTALLER:=}
: ${FABRIC_INSTALLER_URL:=}
if [ ! \( -e ${SERVER} -a -e "server-${VANILLA_VERSION}.jar" \) ]; then : ${FABRIC_LOADER_VERSION:=LATEST}
: ${FABRIC_INSTALLER_VERSION:=${FABRICVERSION:-LATEST}}
if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then if [[ -z $FABRIC_INSTALLER && -z $FABRIC_INSTALLER_URL ]]; then
log "Checking Fabric version information."
if [[ ${FABRIC_INSTALLER_VERSION^^} = LATEST ]]; then
FABRIC_INSTALLER_VERSION=$(maven-metadata-release https://maven.fabricmc.net/net/fabricmc/fabric-installer/maven-metadata.xml)
fi
FABRIC_INSTALLER="fabric-installer-${FABRIC_INSTALLER_VERSION}.jar" FABRIC_INSTALLER="fabric-installer-${FABRIC_INSTALLER_VERSION}.jar"
FABRIC_INSTALLER_URL="https://maven.fabricmc.net/net/fabricmc/fabric-installer/${FABRIC_INSTALLER_VERSION}/fabric-installer-${FABRIC_INSTALLER_VERSION}.jar" FABRIC_INSTALLER_URL="https://maven.fabricmc.net/net/fabricmc/fabric-installer/${FABRIC_INSTALLER_VERSION}/fabric-installer-${FABRIC_INSTALLER_VERSION}.jar"
elif [[ -z $FABRIC_INSTALLER ]]; then elif [[ -z $FABRIC_INSTALLER ]]; then
@@ -70,12 +66,7 @@ if [ ! \( -e ${SERVER} -a -e "server-${VANILLA_VERSION}.jar" \) ]; then
exit 10 exit 10
fi fi
mv server.jar "server-${VANILLA_VERSION}.jar"
mv fabric-server-launch.jar "${SERVER}" mv fabric-server-launch.jar "${SERVER}"
fi fi
# Specify which server jar to run exec ${SCRIPTS:-/}start-setupWorld "$@"
echo "serverJar=server-${VANILLA_VERSION}.jar" > fabric-server-launcher.properties
export FAMILY=FABRIC
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -38,23 +38,18 @@ install() {
get_installer "$normForgeVersion" "$shortForgeVersion" get_installer "$normForgeVersion" "$shortForgeVersion"
fi fi
log "Installing Forge $shortForgeVersion. This might take a minute or two..." log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER"
mkdir -p mods mkdir -p mods
tries=3 tries=3
while true; do while ((--tries >= 0)); do
if ! java -jar "$FORGE_INSTALLER" --installServer &> forge-installer.log; then if java -jar "$FORGE_INSTALLER" --installServer; then
if ((--tries <= 0)); then break
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 fi
done 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 # NOTE $shortForgeVersion will be empty if installer location was given to us
log "Finding installed server jar..." log "Finding installed server jar..."
unset -v latest unset -v latest
@@ -152,6 +147,4 @@ else
fi fi
fi fi
export FAMILY=FORGE
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -58,5 +58,6 @@ if [[ ${LEVEL} != *\;* ]]; then
fi fi
export LEVEL export LEVEL
export FAMILY=LIMBO export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-setupWorld $@ exec ${SCRIPTS:-/}start-setupWorld $@

View File

@@ -1,12 +1,13 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils" export SKIP_LOG4J_CONFIG=true
isDebugging && set -x isDebugging && set -x
: "${VANILLA_VERSION?}" : ${VANILLA_VERSION?}
# stable, dev # stable, dev
: "${MAGMA_CHANNEL:=stable}" : ${MAGMA_CHANNEL:=stable}
magmaDownloadServer() { magmaDownloadServer() {
@@ -88,6 +89,4 @@ else
fi fi
fi fi
export FAMILY=HYBRID exec ${SCRIPTS:-/}start-setupWorld $@
exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -38,6 +38,6 @@ if [ ! -f "${SERVER}" ]; then
get -o "${SERVER}" "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}" get -o "${SERVER}" "${mohistJob}${MOHIST_BUILD}/artifact/${buildRelPath}"
fi fi
export FAMILY=HYBRID export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@" exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"

View File

@@ -73,6 +73,7 @@ else
fi fi
# Normalize on Spigot for downstream operations # Normalize on Spigot for downstream operations
export FAMILY=SPIGOT export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec ${SCRIPTS:-/}start-spiget "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -1,44 +0,0 @@
#!/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 FAMILY=SPIGOT
exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -2,19 +2,20 @@
set -euo pipefail set -euo pipefail
IFS=$'\n\t' IFS=$'\n\t'
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x isDebugging && set -x
: "${VANILLA_VERSION:?}" : ${VANILLA_VERSION:?}
: "${PURPUR_BUILD:=LATEST}" : ${PURPUR_BUILD:=LATEST}
: "${FORCE_REDOWNLOAD:=false}" : ${FORCE_REDOWNLOAD:=false}
if [[ ${PURPUR_BUILD} == LATEST ]]; then if [[ ${PURPUR_BUILD} == LATEST ]]; then
if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then PURPUR_BUILD=$(curl -fsSL "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}" |
jq -r '.builds.latest' || echo "")
if [[ -z ${PURPUR_BUILD} ]]; then
log "ERROR: Failed to locate a Purpur build for ${VANILLA_VERSION}." 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/" log " Please check if a download is available at https://purpur.pl3x.net/downloads/"
exit 1 exit 3
fi fi
fi fi
@@ -23,13 +24,14 @@ export SERVER="purpur-${VANILLA_VERSION}-${PURPUR_BUILD}.jar"
if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then if [ ! -f "$SERVER" ] || isTrue "$FORCE_REDOWNLOAD"; then
downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download" downloadUrl="https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}/${PURPUR_BUILD}/download"
log "Downloading Purpur from $downloadUrl ..." log "Downloading Purpur from $downloadUrl ..."
if ! get -o "$SERVER" "$downloadUrl"; then if ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
log "ERROR: failed to download from $downloadUrl (status=$?)" log "ERROR: failed to download from $downloadUrl (status=$?)"
exit 3 exit 3
fi fi
fi fi
# Normalize on Spigot for later operations # Normalize on Spigot for later operations
export FAMILY=SPIGOT export TYPE=SPIGOT
export SKIP_LOG4J_CONFIG=true
exec "${SCRIPTS:-/}start-spiget" "$@" exec ${SCRIPTS:-/}start-spiget "$@"

View File

@@ -37,5 +37,4 @@ if [ ! -e $SERVER ] || [ -n "$FORCE_REDOWNLOAD" ]; then
curl -sSL -o $SERVER https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER curl -sSL -o $SERVER https://repo.spongepowered.org/maven/org/spongepowered/$TYPE/$SPONGEVERSION/$SERVER
fi fi
export FAMILY=SPONGE exec ${SCRIPTS:-/}start-setupWorld $@
exec ${SCRIPTS:-/}start-setupWorld "$@"

View File

@@ -52,5 +52,5 @@ elif [[ -L /data/minecraft_server.jar ]]; then
fi fi
isDebugging && ls -l isDebugging && ls -l
export FAMILY=VANILLA
exec "${SCRIPTS:-/}start-setupWorld" "$@" exec "${SCRIPTS:-/}start-setupWorld" "$@"

View File

@@ -1,9 +1,32 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x isDebugging && set -x
if [ -n "$OPS" ]; then
log "Updating ops"
rm -f /data/ops.txt.converted
echo $OPS | awk -v RS=, '{print}' > /data/ops.txt
fi
if isTrue "${OVERRIDE_OPS}"; then
log "Recreating ops.json file at server startup"
rm -f /data/ops.json
fi
if [ -n "$WHITELIST" ]; then
log "Updating whitelist"
rm -f /data/white-list.txt.converted
if [[ $WHITELIST == *"-"* ]]; then
echo $WHITELIST | awk -v RS=, '{print}' | xargs -l -i curl -s https://playerdb.co/api/player/minecraft/{} | jq -r '.["data"]["player"] | {"uuid": .id, "name": .username}' | jq -s . > "whitelist.json"
else
echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt
fi
fi
if isTrue "${OVERRIDE_WHITELIST}"; then
log "Recreating whitelist.json file at server startup"
rm -f /data/whitelist.json
fi
if [ -n "$ICON" ]; then if [ -n "$ICON" ]; then
if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then
log "Using server icon from $ICON..." log "Using server icon from $ICON..."
@@ -19,47 +42,7 @@ if [ -n "$ICON" ]; then
fi fi
fi fi
canUseRollingLogs=true
useFallbackJvmFlag=false
patchLog4jConfig() {
file=${1?}
url=${2?}
if ! get -o "$file" "$url"; then
log "ERROR: failed to download corrected log4j config, fallback to JVM flag"
useFallbackJvmFlag=true
return 1
fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
canUseRollingLogs=false
}
# Patch Log4j remote code execution vulnerability
# See https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition
if versionLessThan 1.7; then
: # No patch required here.
elif isFamily VANILLA && versionLessThan 1.12; then
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
elif isFamily VANILLA && versionLessThan 1.17; then
patchLog4jConfig log4j2_112-116.xml https://launcher.mojang.com/v1/objects/02937d122c86ce73319ef9975b58896fc1b491d1/log4j2_112-116.xml
# See https://purpurmc.org/docs/Log4j/
elif isType PURPUR && versionLessThan 1.17; then
patchLog4jConfig purpur_log4j2_1141-1165.xml https://purpurmc.org/docs/xml/purpur_log4j2_1141-1165.xml
elif isType PURPUR && versionLessThan 1.18.1; then
patchLog4jConfig purpur_log4j2_117.xml https://purpurmc.org/docs/xml/purpur_log4j2_117.xml
elif versionLessThan 1.18.1; then
useFallbackJvmFlag=true
fi
if ${useFallbackJvmFlag}; then
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
fi
if isTrue ${ENABLE_ROLLING_LOGS:-false}; then if isTrue ${ENABLE_ROLLING_LOGS:-false}; then
if ! ${canUseRollingLogs}; then
log "ERROR: Using rolling logs is currently not possible in the selected version due to CVE-2021-44228"
exit 1
fi
# Set up log configuration # Set up log configuration
LOGFILE="/data/log4j2.xml" LOGFILE="/data/log4j2.xml"
if [ ! -e "$LOGFILE" ]; then if [ ! -e "$LOGFILE" ]; then
@@ -87,7 +70,7 @@ if versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then
fi fi
# Optional disable GUI for headless servers # Optional disable GUI for headless servers
if [[ ${GUI,,} = false ]]; then if [[ ${GUI} = false || ${GUI} = FALSE ]]; then
EXTRA_ARGS+=" nogui" EXTRA_ARGS+=" nogui"
fi fi
@@ -102,6 +85,26 @@ if [ -n "$JVM_DD_OPTS" ]; then
done done
fi fi
patchLog4jConfig() {
file=${1?}
url=${2?}
if ! get -o "$file" "$url"; then
log "ERROR: failed to download corrected log4j config"
exit 1
fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
}
# Patch Log4j remote code execution vulnerability
# NOTE: Paper, bukkit, and spigot are normalized to SPIGOT
if [[ ${TYPE^^} != SPIGOT ]] && versionLessThan 1.12; then
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
elif [[ ${TYPE^^} != SPIGOT ]] && versionLessThan 1.17; then
patchLog4jConfig log4j2_112-116.xml https://launcher.mojang.com/v1/objects/02937d122c86ce73319ef9975b58896fc1b491d1/log4j2_112-116.xml
elif versionLessThan 1.18.1; then
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
fi
if isTrue ${ENABLE_JMX}; then if isTrue ${ENABLE_JMX}; then
: ${JMX_PORT:=7091} : ${JMX_PORT:=7091}
JVM_OPTS="${JVM_OPTS} JVM_OPTS="${JVM_OPTS}
@@ -159,6 +162,12 @@ if isTrue "${USE_AIKAR_FLAGS}"; then
" "
fi fi
if isTrue "${USE_LARGE_PAGES}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseLargePagesInMetaspace
"
fi
if isTrue "${USE_FLARE_FLAGS}"; then if isTrue "${USE_FLARE_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS} JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UnlockDiagnosticVMOptions -XX:+UnlockDiagnosticVMOptions
@@ -246,14 +255,10 @@ EOF
else else
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}" exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
fi fi
elif [[ $SERVER =~ run.sh ]]; then elif [[ -x run.sh ]]; then
log "Using Forge supplied run.sh script..." log "Using Forge supplied run.sh script..."
echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt echo $JVM_XX_OPTS $JVM_OPTS $expandedDOpts > user_jvm_args.txt
if isTrue ${SETUP_ONLY:=false}; then exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash run.sh
echo "SETUP_ONLY: bash ${SERVER}"
exit
fi
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash "${SERVER}"
else else
# If we have a bootstrap.txt file... feed that in to the server stdin # If we have a bootstrap.txt file... feed that in to the server stdin
if [ -f /data/bootstrap.txt ]; then if [ -f /data/bootstrap.txt ]; then

View File

@@ -1,77 +0,0 @@
#!/bin/bash
set -e -o pipefail
: "${REMOVE_OLD_DATAPACKS:=false}"
: "${DATAPACKS_FILE:=}"
: "${REMOVE_OLD_DATAPACKS_DEPTH:=1} "
: "${REMOVE_OLD_DATAPACKS_INCLUDE:=*.zip}"
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
out_dir=/data/${LEVEL:-world}/datapacks
# Remove old datapacks
if isTrue "${REMOVE_OLD_DATAPACKS}" && [ -z "${DATAPACKS_FILE}" ]; then
if [ -d "$out_dir" ]; then
find "$out_dir" -mindepth 1 -maxdepth ${REMOVE_OLD_DATAPACKS_DEPTH:-16} -wholename "${REMOVE_OLD_DATAPACKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_DATAPACKS_EXCLUDE:-}" -delete
fi
fi
if [[ "$DATAPACKS" ]]; then
mkdir -p "$out_dir"
for i in ${DATAPACKS//,/ }
do
if isURL "$i"; then
log "Downloading datapack $i ..."
if ! get -o "${out_dir}" "$i"; then
log "ERROR: failed to download from $i into $out_dir"
exit 2
fi
elif [[ -f "$i" && "$i" =~ .*\.zip ]]; then
log "Copying datapack located at $i ..."
out_file=$(basename "$i")
if ! cp "$i" "${out_dir}/$out_file"; then
log "ERROR: failed to copy from $i into $out_dir"
exit 2
fi
elif [[ -d "$i" ]]; then
log "Copying datapacks from $i ..."
cp "$i"/*.zip "${out_dir}"
else
log "ERROR Invalid URL or path given in DATAPACKS: $i"
exit 2
fi
done
elif [[ "$DATAPACKS_FILE" ]]; then
if [ ! -f "$DATAPACKS_FILE" ]; then
log "ERROR: given DATAPACKS_FILE file does not exist"
exit 2
fi
mkdir -p "$out_dir"
args=(
-o "${out_dir}"
--log-progress-each
--skip-existing
--uris-file "${DATAPACKS_FILE}"
)
if isTrue "${REMOVE_OLD_DATAPACKS}"; then
args+=(
--prune-others "${REMOVE_OLD_DATAPACKS_INCLUDE}"
--prune-depth "${REMOVE_OLD_DATAPACKS_DEPTH}"
)
fi
if ! get "${args[@]}" ; then
log "ERROR: failed to retrieve one or more datapacks"
exit 1
fi
fi
exec "${SCRIPTS:-/}start-setupForgeApiMods" "$@"

View File

@@ -32,4 +32,4 @@ if [[ ${PATCH_DEFINITIONS} ]]; then
"${PATCH_DEFINITIONS}" "${PATCH_DEFINITIONS}"
fi fi
exec "${SCRIPTS:-/}start-setupRbac" "$@" exec "${SCRIPTS:-/}start-finalExec" "$@"

View File

@@ -1,221 +0,0 @@
#!/bin/bash
set -e -o pipefail
: "${MODS_FORGEAPI_KEY:=}"
: "${REMOVE_OLD_FORGEAPI_MODS:=false}"
: "${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}"
# FORGEAPI_BASE_URL used in manifest downloads below
FORGEAPI_BASE_URL=${FORGEAPI_BASE_URL:-https://api.curseforge.com/v1}
RELEASE_NUMBER_FILTER=1
MINECRAFT_GAME_ID=432
out_dir=/data/mods
# shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils"
isDebugging && set -x
# Remove old mods/plugins
if isTrue "${REMOVE_OLD_FORGEAPI_MODS}" && [ -z "${MODS_FORGEAPI_FILE}" ]; then
removeOldMods /data/mods
fi
ensureModKey(){
if [ -z "$MODS_FORGEAPI_KEY" ]; then
log "ERROR: MODS_FORGEAPI_KEY REQUIRED to Connect to FORGE API, you supplied: ${MODS_FORGEAPI_KEY}"
exit 2
fi
}
# Set the global release type per the text.
# NOTE: downcasing release type for comparing types.
updateReleaseNumber(){
releaseType=$1
if [ "release" = "${releaseType,,}" ] || [ 1 = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=1
elif [ "beta" = "${releaseType,,}" ] || [ 2 = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=2
elif [ "alpha" = "${releaseType,,}" ] || [ 3 = "${releaseType,,}" ]; then
RELEASE_NUMBER_FILTER=3
fi
}
retrieveVersionTypeNumber(){
VERSION_NAME="Minecraft ${VANILLA_VERSION%.*}"
minecraft_types=$(curl -X GET -s \
"${FORGEAPI_BASE_URL}/games/${MINECRAFT_GAME_ID}/version-types" \
-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. 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')
if [ ! "$TYPE_ID" ]; then
log "ERROR: unable to retrieve version types for ${VERSION_NAME} from ForgeAPI"
exit 2
fi
}
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.
if [ ! "$TYPE_ID" ]; then
retrieveVersionTypeNumber
fi
# JQ is struggling with larger page sizes so having to pagination for mods with a lot of releases
pageSize=42
index=0
total_count=1
while [ $index -lt $total_count ]; do
project_files=$(curl -X GET -s \
"${FORGEAPI_BASE_URL}/mods/${project_id}/files?gameVersionTypeId=${TYPE_ID}&index=${index}&pageSize=${pageSize}" \
-H 'Accept: application/json' -H 'x-api-key: '${MODS_FORGEAPI_KEY}'')
if [ ! "$project_files" ]; then
log "ERROR: unable to retrieve any project id files for ${project_id} from ForgeAPI"
exit 2
fi
# Use project files to grab out the total count of mods.
total_count=$(jq -n "$project_files" | jq -c '.pagination.totalCount' )
# Checking for a individual release type input, if not use global
if [ $project_id_release_type ]; then
updateReleaseNumber $project_id_release_type
else
updateReleaseNumber $MODS_FORGEAPI_RELEASES
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.
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
elif [ "$current_project_file" ]; then
current_project_file_id=$(jq -n "$current_project_file" | jq -jc '.id' )
PROJECT_FILE_ID=$(jq -n "$PROJECT_FILE" | jq -jc '.id' )
if (( current_project_file_id > PROJECT_FILE_ID )); then
PROJECT_FILE=$current_project_file
fi
fi
# check to see if we have gone to far or lost our index and exit with an error
if [ -z "$index" ] || [ -z "$total_count" ] || [ $index -ge $total_count ]; then
log "ERROR: Unable to retrieve any files for ${project_id} from ForgeAPI also Validate files have release type associated with no. ${RELEASE_NUMBER_FILTER}"
exit 2
fi
# Increment start index to new set.
index=$(($index + $pageSize))
done
}
downloadModPackfromModFile() {
if [ ! "$PROJECT_FILE" ]; then
log "ERROR: Project File not found from the ForgeAPI"
exit 2
fi
# grabs needed values from our json return
file_name=$(jq -n "$PROJECT_FILE" | jq -jc '.fileName' )
download_url=$(jq -n "$PROJECT_FILE" | jq -jc '.downloadUrl' )
# trys to make the output directory incase it doesnt exist.
mkdir -p "$out_dir"
echo "Downloading ${download_url}"
if ! get -o "${out_dir}/${file_name}" $download_url ; then
log "ERROR: failed to download from ${download_url}"
exit 2
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
if [ ! -f "$MODS_FORGEAPI_FILE" ]; then
log "ERROR: given MODS_FORGEAPI_FILE file does not exist"
exit 2
fi
# Needs loop here to look up release types befor calling download.
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
# Use only project ids and global release data.
if [ "$MODS_FORGEAPI_PROJECTIDS" ] && [ -z "$MODS_FORGEAPI_FILE" ]; then
ensureModKey
for project_id in ${MODS_FORGEAPI_PROJECTIDS//,/ }; do
modFileByProjectID $project_id
downloadModPackfromModFile
if isTrue "${MODS_FORGEAPI_DOWNLOAD_DEPENDENCIES}"; then
downloadDependencies
fi
done
fi
exec "${SCRIPTS:-/}start-setupModpack" "$@"

View File

@@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
# If supplied with a URL for a config (simple zip of configurations), download it and unpack # If supplied with a URL for a config (simple zip of configurations), download it and unpack
if [[ "$MODCONFIG" ]]; then if [[ "$MODCONFIG" ]]; then
@@ -10,7 +9,7 @@ case "X$MODCONFIG" in
log "Downloading mod/plugin configs via HTTP" log "Downloading mod/plugin configs via HTTP"
log " from $MODCONFIG ..." log " from $MODCONFIG ..."
curl -sSL -o /tmp/modconfig.zip "$MODCONFIG" curl -sSL -o /tmp/modconfig.zip "$MODCONFIG"
if [ "$FAMILY" = "SPIGOT" ]; then if [ "$TYPE" = "SPIGOT" ]; then
mkdir -p /data/plugins mkdir -p /data/plugins
unzip -o -d /data/plugins /tmp/modconfig.zip unzip -o -d /data/plugins /tmp/modconfig.zip
else else
@@ -25,4 +24,4 @@ case "X$MODCONFIG" in
esac esac
fi fi
exec "${SCRIPTS:-/}start-setupMounts" "$@" exec ${SCRIPTS:-/}start-setupMounts $@

View File

@@ -6,7 +6,6 @@ set -e -o pipefail
: "${MODS_FILE:=}" : "${MODS_FILE:=}"
: "${REMOVE_OLD_MODS_DEPTH:=1} " : "${REMOVE_OLD_MODS_DEPTH:=1} "
: "${REMOVE_OLD_MODS_INCLUDE:=*.jar}" : "${REMOVE_OLD_MODS_INCLUDE:=*.jar}"
sum_file=/data/.generic_pack.sum
# shellcheck source=start-utils # shellcheck source=start-utils
. "${SCRIPTS:-/}start-utils" . "${SCRIPTS:-/}start-utils"
@@ -19,17 +18,16 @@ CURSE_URL_BASE=${CURSE_URL_BASE:-https://minecraft.curseforge.com/projects}
if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then if isTrue "${REMOVE_OLD_MODS}" && [ -z "${MODS_FILE}" ]; then
removeOldMods /data/mods removeOldMods /data/mods
removeOldMods /data/plugins removeOldMods /data/plugins
rm -f "$sum_file"
fi fi
# If packwiz url passed, bootstrap packwiz and update mods before other modpack processing # If packwiz url passed, bootstrap packwiz and update mods before other modpack processing
if [[ "${PACKWIZ_URL}" ]]; then if [[ "${PACKWIZ_URL}" ]]; then
# Ensure we have the latest packwiz bootstrap installer # Ensure we have the latest packwiz bootstrap installer
latestPackwiz=$(curl -fsSL https://api.github.com/repos/packwiz/packwiz-installer-bootstrap/releases/latest) latestPackwiz=$(curl -fsSL https://api.github.com/repos/comp500/packwiz-installer-bootstrap/releases/latest)
if [[ -z "${latestPackwiz}" ]]; then if [[ -z "${latestPackwiz}" ]]; then
log "WARNING: Could not retrieve Packwiz bootstrap installer release information" log "WARNING: Could not retrieve Packwiz bootstrap installer release information"
else else
isDebugging && log "Latest packwiz ${latestPackwiz}" isDebugging && log "Latest packwiz ${latestPackWiz}"
latestPackwizVer=$(echo ${latestPackwiz} | jq --raw-output '.tag_name') latestPackwizVer=$(echo ${latestPackwiz} | jq --raw-output '.tag_name')
latestPackwizUrl=$(echo ${latestPackwiz} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url') latestPackwizUrl=$(echo ${latestPackwiz} | jq --raw-output '.assets[] | select(.name | match("packwiz-installer-bootstrap.jar")) | .url')
: "${PACKWIZ_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}" : "${PACKWIZ_JAR:=packwiz-installer-bootstrap_${latestPackwizVer}.jar}"
@@ -67,7 +65,7 @@ if [[ "$MODPACK" ]]; then
exit 1 exit 1
fi fi
if [ "$FAMILY" = "SPIGOT" ]; then if [ "$TYPE" = "SPIGOT" ]; then
mkdir -p /data/plugins mkdir -p /data/plugins
if ! unzip -o -d /data/plugins /tmp/modpack.zip; then if ! unzip -o -d /data/plugins /tmp/modpack.zip; then
log "ERROR: failed to unzip the modpack from ${MODPACK}" log "ERROR: failed to unzip the modpack from ${MODPACK}"
@@ -81,7 +79,7 @@ if [[ "$MODPACK" ]]; then
rm -f /tmp/modpack.zip rm -f /tmp/modpack.zip
elif [[ "$MODS" ]]; then elif [[ "$MODS" ]]; then
if [ "$FAMILY" = "SPIGOT" ]; then if [ "$TYPE" = "SPIGOT" ]; then
out_dir=/data/plugins out_dir=/data/plugins
else else
out_dir=/data/mods out_dir=/data/mods
@@ -92,7 +90,7 @@ elif [[ "$MODS" ]]; then
do do
if isURL "$i"; then if isURL "$i"; then
log "Downloading mod/plugin $i ..." log "Downloading mod/plugin $i ..."
if ! get --skip-up-to-date -o "${out_dir}" "$i"; then if ! get -o "${out_dir}" "$i"; then
log "ERROR: failed to download from $i into $out_dir" log "ERROR: failed to download from $i into $out_dir"
exit 2 exit 2
fi fi
@@ -118,7 +116,7 @@ elif [[ "$MODS_FILE" ]]; then
exit 2 exit 2
fi fi
if [ "$FAMILY" = "SPIGOT" ]; then if [ "$TYPE" = "SPIGOT" ]; then
out_dir=/data/plugins out_dir=/data/plugins
else else
out_dir=/data/mods out_dir=/data/mods
@@ -128,7 +126,7 @@ elif [[ "$MODS_FILE" ]]; then
args=( args=(
-o "${out_dir}" -o "${out_dir}"
--log-progress-each --log-progress-each
--skip-up-to-date --skip-existing
--uris-file "${MODS_FILE}" --uris-file "${MODS_FILE}"
) )
if isTrue "${REMOVE_OLD_MODS}"; then if isTrue "${REMOVE_OLD_MODS}"; then
@@ -188,19 +186,15 @@ esac
fi fi
: "${GENERIC_PACKS:=${GENERIC_PACK}}" : "${GENERIC_PACKS:=${GENERIC_PACK}}"
: "${GENERIC_PACKS_PREFIX:=}"
: "${GENERIC_PACKS_SUFFIX:=}"
if [[ "${GENERIC_PACKS}" ]]; then if [[ "${GENERIC_PACKS}" ]]; then
IFS=',' read -ra packs <<< "${GENERIC_PACKS}" IFS=',' read -ra packs <<< "${GENERIC_PACKS}"
packFiles=() packFiles=()
for packEntry in "${packs[@]}"; do for pack in "${packs[@]}"; do
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}" if isURL "$pack"; then
if isURL "${pack}"; then
mkdir -p /data/packs mkdir -p /data/packs
log "Downloading generic pack from $pack" if ! outfile=$(get -o /data/packs --output-filename --skip-existing "$pack"); then
if ! outfile=$(get -o /data/packs --output-filename --skip-up-to-date "$pack"); then
log "ERROR: failed to download $pack" log "ERROR: failed to download $pack"
exit 2 exit 2
fi fi
@@ -210,19 +204,14 @@ if [[ "${GENERIC_PACKS}" ]]; then
fi fi
done done
sum_file=/data/.generic_pack.sum
isDebugging && [ -f "$sum_file}" ] && cat "$sum_file" isDebugging && [ -f "$sum_file}" ] && cat "$sum_file"
if ! sha256sum -c "${sum_file}" --status 2> /dev/null; then
log "Checking if generic packs are up to date"
if isTrue "${SKIP_GENERIC_PACK_UPDATE_CHECK:-false}" && [ -f "$sum_file" ]; then
log "Skipping generic pack update check"
elif isTrue "${FORCE_GENERIC_PACK_UPDATE}" || ! checkSum "${sum_file}"; then
log "Generic pack(s) are out of date. Re-applying..."
base_dir=/tmp/generic_pack_base base_dir=/tmp/generic_pack_base
mkdir -p ${base_dir} mkdir -p ${base_dir}
for pack in "${packFiles[@]}"; do for pack in "${packFiles[@]}"; do
isDebugging && ls -l "${pack}" isDebugging && ls -l "${pack}"
extract "${pack}" "${base_dir}" unzip -q -d ${base_dir} "${pack}"
done done
# recalculate the actual base directory of content # recalculate the actual base directory of content
@@ -250,8 +239,7 @@ if [[ "${GENERIC_PACKS}" ]]; then
cp -R -f "${base_dir}"/* /data cp -R -f "${base_dir}"/* /data
rm -rf /tmp/generic_pack_base rm -rf /tmp/generic_pack_base
log "Saving generic pack(s) checksum" sha256sum "${packFiles[@]}" > "${sum_file}"
sha1sum "${packFiles[@]}" > "${sum_file}"
isDebugging && cat "$sum_file" isDebugging && cat "$sum_file"
fi fi
fi fi

View File

@@ -1,15 +1,14 @@
#!/bin/bash #!/bin/bash
# shellcheck source=start-utils . ${SCRIPTS:-/}start-utils
. "${SCRIPTS:-/}start-utils"
: "${SYNC_SKIP_NEWER_IN_DESTINATION:=${PLUGINS_SYNC_UPDATE:-true}}" : ${SYNC_SKIP_NEWER_IN_DESTINATION:=${PLUGINS_SYNC_UPDATE:-true}}
: "${REPLACE_ENV_DURING_SYNC:=true}" : ${REPLACE_ENV_DURING_SYNC:=true}
: "${REPLACE_ENV_SUFFIXES:=yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml}" : ${REPLACE_ENV_SUFFIXES:=yml,yaml,txt,cfg,conf,properties,hjson,json,tml,toml}
: "${REPLACE_ENV_VARIABLE_PREFIX:=${ENV_VARIABLE_PREFIX:-CFG_}}" : ${REPLACE_ENV_VARIABLE_PREFIX:=${ENV_VARIABLE_PREFIX:-CFG_}}
: "${REPLACE_ENV_VARIABLES_EXCLUDES:=}" : ${REPLACE_ENV_VARIABLES_EXCLUDES:=}
: "${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS:=}" : ${REPLACE_ENV_VARIABLES_EXCLUDE_PATHS:=}
: "${DEBUG:=false}" : ${DEBUG:=false}
set -e set -e
isDebugging && set -x isDebugging && set -x
@@ -25,8 +24,8 @@ else
fi fi
if [ -d /plugins ]; then if [ -d /plugins ]; then
case ${FAMILY} in case ${TYPE} in
SPIGOT|HYBRID) SPIGOT|BUKKIT|PAPER|MAGMA)
mkdir -p /data/plugins mkdir -p /data/plugins
log "Copying plugins over..." log "Copying plugins over..."
mc-image-helper \ mc-image-helper \
@@ -41,7 +40,7 @@ if [ -d /plugins ]; then
fi fi
# If any modules have been provided, copy them over # If any modules have been provided, copy them over
: "${COPY_MODS_DEST:="/data/mods"}" : ${COPY_MODS_DEST:="/data/mods"}
if [ -d /mods ]; then if [ -d /mods ]; then
log "Copying any mods over..." log "Copying any mods over..."
@@ -54,7 +53,7 @@ if [ -d /mods ]; then
/mods "${COPY_MODS_DEST}" /mods "${COPY_MODS_DEST}"
fi fi
: "${COPY_CONFIG_DEST:="/data/config"}" : ${COPY_CONFIG_DEST:="/data/config"}
if [ -d /config ]; then if [ -d /config ]; then
log "Copying any configs from /config to ${COPY_CONFIG_DEST}" log "Copying any configs from /config to ${COPY_CONFIG_DEST}"
@@ -67,4 +66,4 @@ if [ -d /config ]; then
/config "${COPY_CONFIG_DEST}" /config "${COPY_CONFIG_DEST}"
fi fi
exec "${SCRIPTS:-/}start-setupServerProperties" "$@" exec ${SCRIPTS:-/}start-setupServerProperties $@

View File

@@ -1,98 +0,0 @@
#!/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" "$@"

View File

@@ -33,22 +33,19 @@ function setServerProp {
} }
function customizeServerProps { function customizeServerProps {
# Whitelist processing if [ -n "$WHITELIST" ] || isTrue "${ENABLE_WHITELIST:-false}"; then
if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST:-false}"; then log "Creating whitelist"
log "Enabling whitelist functionality" setServerPropValue "whitelist" "true"
setServerPropValue "white-list" "true" setServerPropValue "white-list" "true"
else else
log "Disabling whitelist functionality" log "Disabling whitelist"
setServerPropValue "whitelist" "false"
setServerPropValue "white-list" "false" setServerPropValue "white-list" "false"
fi fi
setServerProp "enforce-whitelist" ENFORCE_WHITELIST
if [[ $(grep "enforce-whitelist" $SERVER_PROPERTIES) != *true ]]; then
log "WARNING: whitelist enabled but not enforced. Set ENFORCE_WHITELIST=TRUE or update 'enforce-whitelist' in server.properties to enforce the whitelist."
fi
# If not provided, generate a reasonable default message-of-the-day, # If not provided, generate a reasonable default message-of-the-day,
# which shows up in the server listing in the client # which shows up in the server listing in the client
if ! [ -v MOTD ]; then if [ -z "$MOTD" ]; then
# snapshot is the odd case where we have to look at version to identify that label # snapshot is the odd case where we have to look at version to identify that label
if [[ ${ORIGINAL_TYPE} == "VANILLA" && ${VERSION} == "SNAPSHOT" ]]; then if [[ ${ORIGINAL_TYPE} == "VANILLA" && ${VERSION} == "SNAPSHOT" ]]; then
label=SNAPSHOT label=SNAPSHOT
@@ -62,13 +59,6 @@ function customizeServerProps {
MOTD="A ${label} Minecraft Server powered by Docker" MOTD="A ${label} Minecraft Server powered by Docker"
fi fi
# normalize MOTD
if [[ ${TYPE^^} = LIMBO ]]; then
if [[ $MOTD ]] && ! [[ $MOTD =~ ^{ ]]; then
MOTD="{\"text\":\"${MOTD}\"}"
fi
fi
setServerProp "server-name" SERVER_NAME setServerProp "server-name" SERVER_NAME
setServerProp "server-ip" SERVER_IP setServerProp "server-ip" SERVER_IP
setServerProp "server-port" SERVER_PORT setServerProp "server-port" SERVER_PORT
@@ -114,6 +104,7 @@ function customizeServerProps {
setServerProp "op-permission-level" OP_PERMISSION_LEVEL setServerProp "op-permission-level" OP_PERMISSION_LEVEL
setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS
setServerProp "use-native-transport" USE_NATIVE_TRANSPORT setServerProp "use-native-transport" USE_NATIVE_TRANSPORT
setServerProp "enforce-whitelist" ENFORCE_WHITELIST
setServerProp "simulation-distance" SIMULATION_DISTANCE setServerProp "simulation-distance" SIMULATION_DISTANCE
setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)" setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)"
[[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}" [[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}"

View File

@@ -1,126 +0,0 @@
#!/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
VT_VERSION=""
DATAPACKS_DIR="/data/${LEVEL:-world}/datapacks"
RESOURCEPACKS_DIR="/data/resourcepacks"
# Remove old VANILLATWEAKS
if isTrue "${REMOVE_OLD_VANILLATWEAKS}"; then
# NOTE: datapacks include crafting tweaks.
if [ -d "$DATAPACKS_DIR" ]; then
find "$DATAPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
fi
if [ -d "$RESOURCEPACKS_DIR" ]; then
find "$RESOURCEPACKS_DIR" -mindepth 1 -maxdepth ${REMOVE_OLD_VANILLATWEAKS_DEPTH:-16} -wholename "${REMOVE_OLD_VANILLATWEAKS_INCLUDE:-*}" -not -wholename "${REMOVE_OLD_VANILLATWEAKS_EXCLUDE:-}" -delete
fi
fi
# Gets the download url and downloads the actual files.
getUrlAndDownload(){
VT_FILE=$1
URL_SUFFIX=$2
OUTPUT_FILE=$3
PACKS=$(jq -jc '.packs // empty' $VT_FILE)
if [ ! "$PACKS" ]; then
log "ERROR: unable to retrieve ${URL_SUFFIX} from ${VT_FILE}"
exit 2
fi
ZIPDATA_URL="https://vanillatweaks.net/assets/server/zip${URL_SUFFIX}.php"
DOWNLOAD_URL=$(curl -X POST -F "packs=${PACKS}" -F "version=${VT_VERSION}" $ZIPDATA_URL | jq -r '.link // empty')
if [ ! "$DOWNLOAD_URL" ]; then
log "ERROR: unable to retrieve ${URL_SUFFIX} packs from vanillatweaks.net!"
exit 2
fi
if ! get -o $OUTPUT_FILE "https://vanillatweaks.net${DOWNLOAD_URL}"; then
log "ERROR: failed to download ${URL_SUFFIX} from ${DOWNLOAD_URL}"
exit 2
fi
}
# Datapacks Handler
downloadDatapacks(){
VT_FILE=$1
URL_SUFFIX="datapacks"
OUTPUT_FILE="/tmp/vanillatweaks.zip"
getUrlAndDownload $VT_FILE $URL_SUFFIX $OUTPUT_FILE
mkdir -p "$DATAPACKS_DIR"
if ! unzip -o -d "$DATAPACKS_DIR" $OUTPUT_FILE; then
log "ERROR: failed to unzip the datapacks ${DATAPACKS} from ${OUTPUT_FILE}"
fi
rm -f $OUTPUT_FILE
}
# Crafting Tweaks Handler
downloadCraftingtweaks(){
VT_FILE=$1
mkdir -p "$DATAPACKS_DIR"
getUrlAndDownload $VT_FILE "craftingtweaks" "${DATAPACKS_DIR}/craftingtweaks.zip"
}
# Resourcepacks Handler
downloadResourcepacks(){
VT_FILE=$1
mkdir -p "$RESOURCEPACKS_DIR"
getUrlAndDownload $VT_FILE "resourcepacks" "${RESOURCEPACKS_DIR}/resourcepacks.zip"
}
# Example: VANILLATWEAKS_SHARECODE=MGr52E
# Code generated from the UI website, typically a alphanumeric 6 digit code.
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
VANILLATWEAKS_FILE=()
for SHARECODE in ${VANILLATWEAKS_SHARECODE//,/ }; do
TMP_FILE="/tmp/${SHARECODE}.json"
SHARECODE_LOOKUP_URL="https://vanillatweaks.net/assets/server/sharecode.php?code=${SHARECODE}"
if ! get -o "$TMP_FILE" "$SHARECODE_LOOKUP_URL"; then
log "ERROR: Unable to use ${SHARECODE} share code provided to retrieve vanillatweaks file"
exit 2
fi
VANILLATWEAKS_FILE+="${TMP_FILE},"
done
fi
# Use vanillatweaks file to specify VT and datapacks and crafting tweaks
if [[ "$VANILLATWEAKS_FILE" ]]; then
for VT_FILE in ${VANILLATWEAKS_FILE//,/ }; do
if [ ! -f "$VT_FILE" ]; then
log "ERROR: given VANILLATWEAKS_FILE file does not exist"
exit 2
fi
VT_VERSION=$(jq -jc '.version // empty' $VT_FILE)
if [ ! "$VT_VERSION" ]; then
log "ERROR: unable to retrieve version from $VT_FILE"
exit 2
fi
TYPE=$(jq -jc '.type // empty' $VT_FILE)
if [[ "$TYPE" = "datapacks" ]]; then
downloadDatapacks $VT_FILE
elif [[ "$TYPE" = "craftingtweaks" ]]; then
downloadCraftingtweaks $VT_FILE
elif [[ "$TYPE" = "resourcepacks" ]]; then
downloadResourcepacks $VT_FILE
fi
# cleans up temp vanilla tweaks file download to get stored packs
if [[ "$VANILLATWEAKS_SHARECODE" ]]; then
rm -f $VT_FILE
fi
done
fi
exec "${SCRIPTS:-/}start-setupDatapack" "$@"

View File

@@ -5,7 +5,7 @@
set -e set -e
isDebugging && set -x isDebugging && set -x
if [ "$TYPE" = "CURSEFORGE" ]; then if [ $TYPE = "CURSEFORGE" ]; then
worldDest=$FTB_DIR/${LEVEL:-world} worldDest=$FTB_DIR/${LEVEL:-world}
else else
worldDest=/data/${LEVEL:-world} worldDest=/data/${LEVEL:-world}
@@ -19,102 +19,49 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
"${worldDest}_the_end" "${worldDest}_the_end"
fi fi
if isURL "$WORLD"; then if isURL $WORLD; then
log "Downloading world from $WORLD" curl -fsSL "$WORLD" -o /tmp/world.zip
if ! get -o /tmp/world.bin "$WORLD"; then zipSrc=/tmp/world.zip
log "ERROR: failed to download world from $WORLD" elif [[ "$WORLD" =~ .*\.zip ]]; then
exit 1 zipSrc="$WORLD"
fi
WORLD=/tmp/world.bin
fi fi
if [ -f "$WORLD" ]; then if [[ "$zipSrc" ]]; then
log "Extracting world" log "Unzipping world"
# Stage contents so that the correct subdirectory can be picked off # Stage contents so that the correct subdirectory can be picked off
mkdir -p /tmp/world-data mkdir -p /tmp/world-data
if ! extract "$WORLD" /tmp/world-data; then (cd /tmp/world-data && unzip -o -q "$zipSrc")
exit 1
fi
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*" -exec dirname "{}" \;)
if ! [[ $baseDirs ]]; then else
log "ERROR world content is not valid since level.dat could not be found" baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;)
exit 2
fi fi
count=$(echo "$baseDirs" | wc -l) count=$(echo "$baseDirs" | wc -l)
if [[ $count -gt 1 ]]; then if [[ $count -gt 1 ]]; then
baseDirsNoSpigotSuffix=$(echo "$baseDirs" | sed -re 's:(_nether|_the_end)/?$::' | sort -u) baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
if [ $(echo "$baseDirsNoSpigotSuffix" | wc -l) -eq 1 ]; then baseName=$(basename "$baseDir")
baseDir="$baseDirsNoSpigotSuffix" log "WARN multiple levels found, picking: $baseName"
baseName=$(basename "$baseDir")
log "Found Spigot naming conventions, taking $baseName as main dimension"
else
baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
baseName=$(basename "$baseDir")
log "WARN multiple levels found, picking: $baseName"
fi
elif [[ $count -gt 0 ]]; then elif [[ $count -gt 0 ]]; then
baseDir="$baseDirs" baseDir="$baseDirs"
else else
log "ERROR invalid world content" log "ERROR invalid world content"
exit 1 exit 1
fi fi
if [ -d "${baseDir}_nether/DIM-1" ]; then
if [ -d "$baseDir/DIM-1" ]; then
log "WARN found Nether dimension in both $baseDir and ${baseDir}_nether, picking ${baseDir}_nether"
rm -r "$baseDir/DIM-1"
fi
fi
if [ -d "${baseDir}_the_end/DIM1" ]; then
if [ -d "$baseDir/DIM1" ]; then
log "WARN found End dimension in both $baseDir and ${baseDir}_the_end, picking ${baseDir}_the_end"
rm -r "$baseDir/DIM1"
fi
fi
log "Copying world..."
rsync --remove-source-files --recursive --delete "$baseDir/" "$worldDest" rsync --remove-source-files --recursive --delete "$baseDir/" "$worldDest"
if [ "$TYPE" = "SPIGOT" ]; then
if [ "$FAMILY" = "SPIGOT" ]; then log "Copying end and nether ..."
if [ -d "${baseDir}_nether" ]; then [ -d "${baseDir}_nether" ] && rsync --remove-source-files --recursive --delete "${baseDir}_nether/" "${worldDest}_nether"
log "Copying Spigot Nether..." [ -d "${baseDir}_the_end" ] && rsync --remove-source-files --recursive --delete "${baseDir}_the_end/" "${worldDest}_the_end"
rsync --remove-source-files --recursive --delete "${baseDir}_nether/" "${worldDest}_nether"
elif [ -d "$worldDest/DIM-1" ]; then
log "Moving Nether to Spigot location..."
mkdir -p "${worldDest}_nether"
mv -f "$worldDest/DIM-1" "${worldDest}_nether/"
fi
if [ -d "${baseDir}_the_end" ]; then
log "Copying Spigot End..."
rsync --remove-source-files --recursive --delete "${baseDir}_the_end/" "${worldDest}_the_end"
elif [ -d "$worldDest/DIM1" ]; then
log "Moving End to Spigot location..."
mkdir -p "${worldDest}_the_end"
mv -f "$worldDest/DIM1" "${worldDest}_the_end/"
fi
else
if [ -d "${baseDir}_nether/DIM-1" ]; then
log "Copying Spigot Nether to vanilla location..."
rsync --remove-source-files --recursive --delete "${baseDir}_nether/DIM-1" "${worldDest}/"
fi
if [ -d "${baseDir}_the_end/DIM1" ]; then
log "Copying Spigot End to vanilla location..."
rsync --remove-source-files --recursive --delete "${baseDir}_the_end/DIM1" "${worldDest}/"
fi
fi fi
elif [ -d "$WORLD" ]; then else
log "Cloning world directory from $WORLD ..." log "Cloning world directory from $WORLD ..."
rsync --recursive --delete "${WORLD%/}"/ "$worldDest" rsync --recursive --delete "${WORLD%/}"/ "$worldDest"
else
log "ERROR: world file/directory $WORLD is missing"
exit 1
fi fi
if [ "$FAMILY" = "SPIGOT" ]; then if [ "$TYPE" = "SPIGOT" ]; then
# Reorganise if a Spigot server # Reorganise if a Spigot server
log "Moving End and Nether maps to Spigot location" log "Moving End and Nether maps to Spigot location"
[ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "${worldDest}_the_end" [ -d "$worldDest/DIM1" ] && mv -f "$worldDest/DIM1" "${worldDest}_the_end"
@@ -122,4 +69,4 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
fi fi
fi fi
exec "${SCRIPTS:-/}start-setupVanillaTweaks" "$@" exec "${SCRIPTS:-/}start-setupModpack" "$@"

View File

@@ -22,20 +22,6 @@ containsJars() {
return 1 return 1
} }
containsPlugin() {
file=${1?}
pat='plugin.yml$'
while read -r line; do
if [[ $line =~ $pat ]]; then
return 0
fi
done <<<$(unzip -l "$file")
return 1
}
getResourceFromSpiget() { getResourceFromSpiget() {
resource=${1?} resource=${1?}
@@ -95,12 +81,9 @@ downloadResourceFromSpiget() {
log "Extracting contents of resource ${resource} into plugins" log "Extracting contents of resource ${resource} into plugins"
unzip -o -q -d /data/plugins "${tmpfile}" unzip -o -q -d /data/plugins "${tmpfile}"
rm "${tmpfile}" rm "${tmpfile}"
elif containsPlugin "${tmpfile}"; then else
log "Moving resource ${resource} into plugins" log "Moving resource ${resource} into plugins"
mv "${tmpfile}" "/data/plugins/${resource}.jar" mv "${tmpfile}" "/data/plugins/${resource}.jar"
else
log "ERROR downloaded resource '${resource}' seems to be not a valid plugin"
exit 2
fi fi
} }

View File

@@ -40,10 +40,6 @@ function getFilenameFromUrl() {
} }
function isTrue() { function isTrue() {
local oldState
oldState=$(shopt -po xtrace)
shopt -u -o xtrace
local value=${1,,} local value=${1,,}
result= result=
@@ -57,7 +53,6 @@ function isTrue() {
;; ;;
esac esac
eval "$oldState"
return ${result} return ${result}
} }
@@ -87,18 +82,7 @@ function logn() {
} }
function log() { function log() {
local oldState echo "[init] $*"
# The return status when listing options is zero if all optnames are enabled, non- zero otherwise.
oldState=$(shopt -po xtrace || true)
shopt -u -o xtrace
if isDebugging || isTrue "${LOG_TIMESTAMP:-false}"; then
ts=" $(date --rfc-2822)"
else
ts=
fi
echo "[init]${ts} $*"
eval "$oldState"
} }
function logAutopause() { function logAutopause() {
@@ -109,14 +93,6 @@ function logAutopauseAction() {
echo "[$(date -Iseconds)] [Autopause] $*" echo "[$(date -Iseconds)] [Autopause] $*"
} }
function logAutostop() {
echo "[Autostop loop] $*"
}
function logAutostopAction() {
echo "[$(date -Iseconds)] [Autostop] $*"
}
function normalizeMemSize() { function normalizeMemSize() {
local scale=1 local scale=1
case ${1,,} in case ${1,,} in
@@ -136,7 +112,34 @@ function normalizeMemSize() {
} }
function versionLessThan() { function versionLessThan() {
mc-image-helper compare-versions "${VANILLA_VERSION}" lt "${1?}" local activeParts
version=${VANILLA_VERSION%%-*} # for snapshot/rc versions
version=${version##b} # for versions like b1.7.3
IFS=. read -ra activeParts <<<"${version}"
local givenParts
IFS=. read -ra givenParts <<<"$1"
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
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
return 0
else
return 1
fi
fi
} }
requireVar() { requireVar() {
@@ -160,7 +163,7 @@ requireEnum() {
fi fi
done done
log "ERROR: $var must be set to one of $*" log "ERROR: $var must be set to one of $@"
# exit 1 # exit 1
} }
@@ -186,70 +189,4 @@ function get() {
flags+=("--debug") flags+=("--debug")
fi fi
mc-image-helper "${flags[@]}" get "$@" mc-image-helper "${flags[@]}" get "$@"
} }
function isFamily() {
for f in "${@}"; do
if [[ $FAMILY == "$f" ]]; then
return 0
fi
done
return 1
}
function isType() {
for t in "${@}"; do
# shellcheck disable=SC2153
if [[ $TYPE == "$t" ]]; then
return 0
fi
done
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}")
case "${type}" in
application/zip)
unzip -q -d "${destDir}" "${src}"
;;
application/x-tar|application/gzip|application/x-gzip|application/x-bzip2|application/zstd|application/x-zstd)
tar -C "${destDir}" -xf "${src}"
;;
*)
log "ERROR: unsupported archive type: $type"
return 1
;;
esac
}
function checkSum() {
local sum_file=${1?}
# Get distro
distro=$(cat /etc/os-release | grep -E "^ID=" | cut -d= -f2 | sed -e 's/"//g')
if [ "${distro}" == "debian" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0
elif [ "${distro}" == "ubuntu" ] && sha1sum -c "${sum_file}" --status 2> /dev/null; then
return 0
elif [ "${distro}" == "alpine" ] && sha1sum -c "${sum_file}" -s 2> /dev/null; then
return 0
else
return 1
fi
}

1
tests/.gitignore vendored
View File

@@ -1 +0,0 @@
data/

View File

@@ -1,4 +1,4 @@
version: "3" version: "3.8"
services: services:
monitor: monitor:

View File

@@ -1,43 +0,0 @@
#!/bin/bash
# go to script root directory
cd "$(dirname "$0")" || exit 1
# compose down function for reuse
down() {
docker-compose down -v --remove-orphans
}
checkandExitOnFailure(){
failed=$1
# docker-compose logs outputs messages from the specified container
if $failed; then
docker-compose logs mc
down
cd ..
exit 2
fi
}
# tests to completely spin up Minecraft and use the monitor to validate the service is running.
fullMinecraftUpTest(){
folder=$1
cd "$folder"
failed=false
# run the monitor to validate the Minecraft image is healthy
docker-compose run monitor || failed=true
echo "${folder} Result: failed=$failed"
checkandExitOnFailure $failed
down
cd ..
}
# go through each folder in fulltests and run fullbuilds
FOLDERS=$(ls)
for folder in $FOLDERS; do
# If folder is a directory
if [ -d "$folder" ]; then
echo "Starting Tests on ${folder}"
fullMinecraftUpTest $folder
fi
done

View File

@@ -0,0 +1,15 @@
version: "3"
services:
mc:
image: itzg/minecraft-server
environment:
EULA: "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: {}

View File

@@ -1,15 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
TYPE: "PAPER"
WORLD: /worlds/world-for-testing.zip
volumes:
- ./worlds:/worlds:ro
- ./data:/data

View File

@@ -1,5 +0,0 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world_nether/DIM-1/some_spigot_nether_file && \
mc-image-helper assert fileExists world_the_end/DIM1/some_spigot_end_file && \
! mc-image-helper assert fileExists world_nether/DIM-1/some_vanilla_nether_file && \
! mc-image-helper assert fileExists world_the_end/DIM1/some_vanilla_end_file

View File

@@ -1,14 +0,0 @@
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.zip
volumes:
- ./worlds:/worlds:ro
- ./data:/data

View File

@@ -1,5 +0,0 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world/DIM-1/some_spigot_nether_file && \
mc-image-helper assert fileExists world/DIM1/some_spigot_end_file && \
! mc-image-helper assert fileExists world/DIM-1/some_vanilla_nether_file && \
! mc-image-helper assert fileExists world/DIM1/some_vanilla_end_file

View File

@@ -1,18 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
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:
- ./forgeapi_mods.json:/config/forgeapi_mods.json:ro

View File

@@ -1,17 +0,0 @@
[{
"name": "fabric api",
"projectId": "306612",
"releaseType": "release"
},
{
"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"
}
]

View File

@@ -1 +0,0 @@
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

@@ -1,16 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
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}
REMOVE_OLD_FORGEAPI_MODS: "TRUE"

View File

@@ -1 +0,0 @@
[[ $MODS_FORGEAPI_KEY ]] || exit 1

View File

@@ -1,14 +0,0 @@
version: "3"
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "TRUE"
GENERIC_PACKS: testing
GENERIC_PACKS_PREFIX: /packs/
GENERIC_PACKS_SUFFIX: .zip
volumes:
- ./packs:/packs
- ./data:/data

View File

@@ -1 +0,0 @@
mc-image-helper assert fileExists one.txt mods/two.txt

View File

@@ -1,24 +0,0 @@
version: "3"
services:
web:
image: nginx
volumes:
- ./web:/usr/share/nginx/html
mc:
depends_on:
- web
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
GENERIC_PACKS: http://web/configs.zip,/packs/testing.zip
LOG_TIMESTAMP: "true"
# the following are only used to speed up test execution
TYPE: CUSTOM
CUSTOM_SERVER: /servers/fake.jar
VERSION: 1.18.1
volumes:
- ./packs:/packs
- ./data:/data
- ./fake.jar:/servers/fake.jar

View File

@@ -1,2 +0,0 @@
mc-image-helper assert fileExists one.txt mods/two.txt
mc-image-helper assert fileExists config/opt.yml

View File

@@ -1,13 +0,0 @@
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

View File

@@ -1,3 +0,0 @@
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

View File

@@ -1,15 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
TYPE: "PAPER"
WORLD: /worlds/world-for-testing.zip
volumes:
- ./worlds:/worlds:ro
- ./data:/data

View File

@@ -1,4 +0,0 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world/some_overworld_file && \
mc-image-helper assert fileExists world_nether/DIM-1/some_nether_file && \
mc-image-helper assert fileExists world_the_end/DIM1/some_end_file

View File

@@ -1,14 +0,0 @@
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.zip
volumes:
- ./worlds:/worlds:ro
- ./data:/data

View File

@@ -1,4 +0,0 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world/some_overworld_file && \
mc-image-helper assert fileExists world/DIM-1/some_nether_file && \
mc-image-helper assert fileExists world/DIM1/some_end_file

View File

@@ -1,61 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
# go to script root directory
cd "$(dirname "$0")" || exit 1
# tests that only run the setup files for things like downloads and configuration.
setupOnlyMinecraftTest(){
folder=$1
cd "$folder"
result=0
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
::::::::::::::::::::::::::::::::::
"
result=1
elif [ -f verify.sh ]; then
if ! docker run --rm --entrypoint bash -v "${PWD}/data":/data -v "${PWD}/verify.sh":/verify "${IMAGE_TO_TEST:-itzg/minecraft-server}" -e /verify; then
echo "${folder} verify FAILED"
result=1
else
echo "${folder} verify PASS"
fi
else
echo "${folder} PASS"
fi
docker-compose down -v --remove-orphans
cd ..
return $result
}
# go through each folder in setuponly and test setups
if (( $# > 0 )); then
for folder in "$@"; do
echo "Starting Tests in ${folder}"
setupOnlyMinecraftTest "$folder"
done
else
readarray -t folders < <(find . -maxdepth 2 -mindepth 2 -name docker-compose.yml -printf '%h\n')
for folder in "${folders[@]}"; do
echo "Starting Tests in ${folder}"
setupOnlyMinecraftTest "$folder"
done
fi

View File

@@ -1,15 +0,0 @@
version: "3"
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
TYPE: "PAPER"
WORLD: /worlds/world-for-testing.zip
volumes:
- ./worlds:/worlds:ro
- ./data:/data

View File

@@ -1,3 +0,0 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world_nether/DIM-1/some_nether_file && \
mc-image-helper assert fileExists world_the_end/DIM1/some_end_file

View File

@@ -1,14 +0,0 @@
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.zip
volumes:
- ./worlds:/worlds:ro
- ./data:/data

View File

@@ -1,3 +0,0 @@
mc-image-helper assert fileExists world/level.dat && \
mc-image-helper assert fileExists world/DIM-1/some_nether_file && \
mc-image-helper assert fileExists world/DIM1/some_end_file

View File

@@ -1,17 +0,0 @@
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/vt-datapacks.json,/config/vt-craftingtweaks.json,/config/vt-resourcepacks.json
REMOVE_OLD_VANILLATWEAKS: "FALSE"
volumes:
- ./data:/data
- ./vt-datapacks.json:/config/vt-datapacks.json:ro
- ./vt-craftingtweaks.json:/config/vt-craftingtweaks.json:ro
- ./vt-resourcepacks.json:/config/vt-resourcepacks.json:ro

View File

@@ -1,4 +0,0 @@
mc-image-helper assert fileExists "/data/world/datapacks/afk*"
mc-image-helper assert fileExists "/data/world/datapacks/graves*"
mc-image-helper assert fileExists "/data/world/datapacks/craftingtweaks*"
mc-image-helper assert fileExists "/data/resourcepacks/resourcepacks*"

Some files were not shown because too many files have changed in this diff Show More