mirror of
https://github.com/itzg/docker-minecraft-server.git
synced 2026-02-17 15:13:55 +00:00
Compare commits
229 Commits
2021.26.0-
...
java8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48414b3e87 | ||
|
|
4cb227629f | ||
|
|
932cd8f89e | ||
|
|
f2f8d58d3b | ||
|
|
b7bbe1b0a6 | ||
|
|
1dd9a2e6e0 | ||
|
|
aa7b997697 | ||
|
|
c2bf2bbcc5 | ||
|
|
68b926f2b1 | ||
|
|
306671ffe7 | ||
|
|
be99d171f5 | ||
|
|
882f3b1cd8 | ||
|
|
eb6c7c98f0 | ||
|
|
3472c67ca8 | ||
|
|
8995e63b72 | ||
|
|
b65f108917 | ||
|
|
2b374a2073 | ||
|
|
b5b164d5d3 | ||
|
|
0cde40604e | ||
|
|
22f2eb7308 | ||
|
|
4a1d2d2b80 | ||
|
|
10922b261b | ||
|
|
13883b20e7 | ||
|
|
de0188de3d | ||
|
|
2b093ad421 | ||
|
|
0ec73b141f | ||
|
|
de0bb14abd | ||
|
|
26809ef1f0 | ||
|
|
dca4f86fa6 | ||
|
|
eb0c30d134 | ||
|
|
c55cce628d | ||
|
|
c52c3fb04a | ||
|
|
240238013b | ||
|
|
67c8879c6b | ||
|
|
18f0f0ceee | ||
|
|
aca8701072 | ||
|
|
c424fe1c7b | ||
|
|
eb694463c5 | ||
|
|
469afb3200 | ||
|
|
8f8acc40f5 | ||
|
|
7dbd8256ea | ||
|
|
66468975e0 | ||
|
|
6d27ce8461 | ||
|
|
b0817f2a83 | ||
|
|
21602a79e7 | ||
|
|
8a42dfe232 | ||
|
|
d02bbb798e | ||
|
|
d2452ba18f | ||
|
|
cbbc817279 | ||
|
|
18d8aba20f | ||
|
|
09834c289a | ||
|
|
880dca1ae5 | ||
|
|
7f940626d8 | ||
|
|
b1e33d4049 | ||
|
|
284c260886 | ||
|
|
05bbb45046 | ||
|
|
d11fe229df | ||
|
|
7246d836ec | ||
|
|
b7801565c2 | ||
|
|
bd4760e504 | ||
|
|
edc25b216f | ||
|
|
c01e97ca94 | ||
|
|
5499867ae8 | ||
|
|
e4c575c130 | ||
|
|
f29f098b26 | ||
|
|
1d751ab2bc | ||
|
|
b59eefd556 | ||
|
|
4f87662664 | ||
|
|
ce6ef7d81c | ||
|
|
7e2937aa8d | ||
|
|
529781adda | ||
|
|
977d082638 | ||
|
|
0a2e6721fb | ||
|
|
5461107b83 | ||
|
|
c506cf11ac | ||
|
|
967d5159ea | ||
|
|
79f978359c | ||
|
|
4c7bb313be | ||
|
|
83d3555eab | ||
|
|
e93cc569c6 | ||
|
|
5c0cf03548 | ||
|
|
00cae995a7 | ||
|
|
4ba0a9c98c | ||
|
|
6520655d6c | ||
|
|
6bd722b11b | ||
|
|
4576882f07 | ||
|
|
224553f695 | ||
|
|
cc100fd8bb | ||
|
|
a7a0e54cb9 | ||
|
|
ce32eb8d4f | ||
|
|
39519427bb | ||
|
|
5356c76dd6 | ||
|
|
2f1fed822c | ||
|
|
bf5824b6e5 | ||
|
|
52bf2ae094 | ||
|
|
fa4a0e92ce | ||
|
|
c15e231d7e | ||
|
|
cc885276f5 | ||
|
|
9dee47cb6d | ||
|
|
bd97029446 | ||
|
|
6537cfb5b5 | ||
|
|
6729ba462e | ||
|
|
4b28d5e472 | ||
|
|
51002c956e | ||
|
|
de62cf8dc7 | ||
|
|
3f2022da40 | ||
|
|
0f7464403c | ||
|
|
c9d5ad7530 | ||
|
|
1be933bd63 | ||
|
|
99b792dec1 | ||
|
|
ee5267cf41 | ||
|
|
0a46d0382e | ||
|
|
cc61497f7e | ||
|
|
2c2cbadd9a | ||
|
|
bfc29d289d | ||
|
|
84a1313261 | ||
|
|
39bcfddf3c | ||
|
|
e6ea8197aa | ||
|
|
0184c095fc | ||
|
|
524a7e21f3 | ||
|
|
f817cae945 | ||
|
|
675d05920b | ||
|
|
106a7132d4 | ||
|
|
0e04a10efa | ||
|
|
0d8df635d6 | ||
|
|
e0dedc194d | ||
|
|
ef32e8ed4c | ||
|
|
489b583ad7 | ||
|
|
8c4dff22fb | ||
|
|
455f31c9d8 | ||
|
|
bac1bfb5dc | ||
|
|
9994c64b51 | ||
|
|
92079fc01f | ||
|
|
98378130f2 | ||
|
|
42856da49d | ||
|
|
83b05609d3 | ||
|
|
21fab1bf41 | ||
|
|
2849359a11 | ||
|
|
cd337f34da | ||
|
|
7a9aa760a2 | ||
|
|
2fd405ec5b | ||
|
|
cbfe9a069c | ||
|
|
2db61fd72f | ||
|
|
6e2073fda5 | ||
|
|
ae48a8710e | ||
|
|
3b54a9fd67 | ||
|
|
a66efb1a4f | ||
|
|
83938d8989 | ||
|
|
8335b81bd8 | ||
|
|
b9c379ec6c | ||
|
|
b9ecbf7497 | ||
|
|
eca00e88bf | ||
|
|
2a3169344d | ||
|
|
8ec4f0d244 | ||
|
|
d45250ebf2 | ||
|
|
03110aef99 | ||
|
|
f344e7e823 | ||
|
|
c7fcaf1ec6 | ||
|
|
9d700041a7 | ||
|
|
4af4ed69a5 | ||
|
|
d215c14996 | ||
|
|
4716254b5b | ||
|
|
3c2b7f0718 | ||
|
|
0fd43f5a05 | ||
|
|
fae6479453 | ||
|
|
d9df5bf773 | ||
|
|
13d7248c38 | ||
|
|
3c54954057 | ||
|
|
84823a559d | ||
|
|
d543df768b | ||
|
|
74968389a2 | ||
|
|
1701718515 | ||
|
|
ed6937654c | ||
|
|
73eb6e2e45 | ||
|
|
8b982472a4 | ||
|
|
ab406727d6 | ||
|
|
5fc74a45f7 | ||
|
|
17ecd48cd8 | ||
|
|
4732ce27a6 | ||
|
|
6e10768e7f | ||
|
|
bb47a3705d | ||
|
|
c3e1e92547 | ||
|
|
9ddd768f44 | ||
|
|
62e1ff8ffa | ||
|
|
5f95d135f5 | ||
|
|
8e32d26b0f | ||
|
|
573f064970 | ||
|
|
0bc6f4075b | ||
|
|
4ebcc0ef48 | ||
|
|
57720cf394 | ||
|
|
64b2783f19 | ||
|
|
1dbdd7628a | ||
|
|
4252ec710f | ||
|
|
11d455c284 | ||
|
|
08bc419dc8 | ||
|
|
67c23017d0 | ||
|
|
6e1ba3667c | ||
|
|
0c2f8b903b | ||
|
|
b9335d9cd6 | ||
|
|
0d92092b90 | ||
|
|
e653a41b3f | ||
|
|
82e63c54c4 | ||
|
|
f9c573f598 | ||
|
|
bf8b9cf20d | ||
|
|
0dd5a412d9 | ||
|
|
b389561091 | ||
|
|
6ee055761d | ||
|
|
49f9ff645e | ||
|
|
004cbdb9f7 | ||
|
|
45856a1a81 | ||
|
|
1e615e76e8 | ||
|
|
1c85a685de | ||
|
|
7cd207f40b | ||
|
|
140a8aa90c | ||
|
|
76dcff9d18 | ||
|
|
a9a86d249b | ||
|
|
595760d301 | ||
|
|
6d3f194ce3 | ||
|
|
21c1620f0c | ||
|
|
e78e5af96d | ||
|
|
0fb9700fc7 | ||
|
|
18925ef32c | ||
|
|
f06b990f8a | ||
|
|
75844ae81a | ||
|
|
6bb2323c46 | ||
|
|
7814ca21b5 | ||
|
|
b8806629ec | ||
|
|
4a7f838a0f | ||
|
|
2d07dee4df |
4
.github/release.yml
vendored
Normal file
4
.github/release.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
changelog:
|
||||||
|
exclude:
|
||||||
|
authors:
|
||||||
|
- dependabot
|
||||||
96
.github/workflows/build-multiarch.yml
vendored
96
.github/workflows/build-multiarch.yml
vendored
@@ -3,30 +3,60 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- java8-multiarch
|
- test/**
|
||||||
- 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
|
||||||
@@ -39,10 +69,13 @@ jobs:
|
|||||||
images: |
|
images: |
|
||||||
itzg/minecraft-server
|
itzg/minecraft-server
|
||||||
tags: |
|
tags: |
|
||||||
type=ref,event=branch
|
type=ref,event=tag,enable=${{ matrix.variant == 'java17' }}
|
||||||
type=ref,event=tag
|
type=ref,event=tag,suffix=-${{ matrix.variant }}
|
||||||
|
type=raw,value=${{ matrix.variant }}
|
||||||
flavor: |
|
flavor: |
|
||||||
latest=${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
|
latest=${{ matrix.variant == 'java17' }}
|
||||||
|
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
|
||||||
@@ -57,38 +90,37 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
- name: Build for test
|
- name: Build for test
|
||||||
uses: docker/build-push-action@v2.7.0
|
uses: docker/build-push-action@v2.9.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
|
||||||
cache-from: type=gha
|
build-args: |
|
||||||
|
BASE_IMAGE=${{ matrix.baseImage }}
|
||||||
|
cache-from: type=gha,scope=${{ matrix.variant }}
|
||||||
# no cache-to to avoid cross-cache update from next build step
|
# no cache-to to avoid cross-cache update from next build step
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
# It is assumed that image variants are merged from master and tested there
|
env:
|
||||||
if: github.ref_name == 'master'
|
MINECRAFT_VERSION: ${{ matrix.mcVersion }}
|
||||||
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.7.0
|
uses: docker/build-push-action@v2.9.0
|
||||||
with:
|
with:
|
||||||
context: .
|
platforms: ${{ matrix.platforms }}
|
||||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
push: ${{ github.ref_type == 'tag' || github.ref_name == 'master' }}
|
||||||
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: |
|
||||||
- name: Image digest
|
BASE_IMAGE=${{ matrix.baseImage }}
|
||||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
cache-from: type=gha,scope=${{ matrix.variant }}
|
||||||
|
cache-to: type=gha,mode=max,scope=${{ matrix.variant }}
|
||||||
|
|||||||
43
.github/workflows/ci.yml
vendored
Normal file
43
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
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
|
||||||
26
.github/workflows/discord.yml
vendored
Normal file
26
.github/workflows/discord.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
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 }} 💣💥"
|
||||||
2
.github/workflows/generate-toc.yml
vendored
2
.github/workflows/generate-toc.yml
vendored
@@ -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.12.0
|
- uses: stefanzweifel/git-auto-commit-action@v4.13.1
|
||||||
with:
|
with:
|
||||||
commit_message: "docs: Auto update markdown TOC"
|
commit_message: "docs: Auto update markdown TOC"
|
||||||
25
.github/workflows/issue-label.yml
vendored
Normal file
25
.github/workflows/issue-label.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
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"
|
||||||
15
.github/workflows/main.yml
vendored
15
.github/workflows/main.yml
vendored
@@ -4,16 +4,9 @@ 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 }}
|
||||||
@@ -53,7 +46,7 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
- name: Build for test
|
- name: Build for test
|
||||||
uses: docker/build-push-action@v2.7.0
|
uses: docker/build-push-action@v2.9.0
|
||||||
if: github.ref_name == 'java8'
|
if: github.ref_name == 'java8'
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
@@ -75,7 +68,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
id: docker_build
|
id: docker_build
|
||||||
uses: docker/build-push-action@v2.7.0
|
uses: docker/build-push-action@v2.9.0
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
@@ -92,6 +85,4 @@ 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 }}
|
|
||||||
|
|||||||
40
.github/workflows/pr.yml
vendored
40
.github/workflows/pr.yml
vendored
@@ -1,15 +1,21 @@
|
|||||||
name: Validate PR
|
name: PullRequest
|
||||||
|
|
||||||
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-latest
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2.4.0
|
- uses: actions/checkout@v2.4.0
|
||||||
@@ -18,15 +24,41 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
uses: docker/build-push-action@v2.7.0
|
uses: docker/build-push-action@v2.9.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 }}
|
||||||
|
|||||||
2
.github/workflows/stale-check.yml
vendored
2
.github/workflows/stale-check.yml
vendored
@@ -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'
|
exempt-issue-labels: 'enhancement,keep,status/needs triage,priority/high'
|
||||||
|
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
|
.vscode
|
||||||
/data/
|
/data/
|
||||||
/.idea/
|
/.idea/
|
||||||
*.iml
|
*.iml
|
||||||
/gh-md-toc
|
/gh-md-toc
|
||||||
|
|||||||
@@ -15,8 +15,24 @@ 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:
|
||||||
|
|
||||||
```shell script
|
PowerShell:
|
||||||
docker build -t mc-dev .
|
```powershell
|
||||||
|
$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.
|
||||||
@@ -116,4 +132,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
|
||||||
```
|
```
|
||||||
|
|||||||
72
Dockerfile
72
Dockerfile
@@ -1,30 +1,32 @@
|
|||||||
FROM eclipse-temurin:17-jdk
|
ARG BASE_IMAGE=openjdk:8-jdk-alpine
|
||||||
|
FROM ${BASE_IMAGE}
|
||||||
|
|
||||||
LABEL org.opencontainers.image.authors="Geoff Bourne <itzgeoff@gmail.com>"
|
RUN apk add --no-cache -U \
|
||||||
|
openssl \
|
||||||
RUN apt-get update \
|
|
||||||
&& DEBIAN_FRONTEND=noninteractive \
|
|
||||||
apt-get install -y \
|
|
||||||
imagemagick \
|
imagemagick \
|
||||||
gosu \
|
file \
|
||||||
sudo \
|
lsof \
|
||||||
net-tools \
|
su-exec \
|
||||||
iputils-ping \
|
# GNU compatible 'find'
|
||||||
curl wget \
|
findutils \
|
||||||
|
shadow \
|
||||||
|
bash \
|
||||||
|
curl iputils \
|
||||||
git \
|
git \
|
||||||
jq \
|
jq \
|
||||||
dos2unix \
|
|
||||||
mysql-client \
|
mysql-client \
|
||||||
tzdata \
|
tzdata \
|
||||||
rsync \
|
rsync \
|
||||||
nano \
|
nano \
|
||||||
unzip \
|
sudo \
|
||||||
knockd \
|
knock \
|
||||||
ttf-dejavu \
|
ttf-dejavu \
|
||||||
&& apt-get clean
|
zstd
|
||||||
|
|
||||||
RUN addgroup --gid 1000 minecraft \
|
RUN addgroup -g 1000 minecraft \
|
||||||
&& adduser --system --shell /bin/false --uid 1000 --ingroup minecraft --home /data minecraft
|
&& adduser -Ss /bin/false -u 1000 -G minecraft -h /home/minecraft minecraft \
|
||||||
|
&& mkdir -m 777 /data \
|
||||||
|
&& chown minecraft:minecraft /data /home/minecraft
|
||||||
|
|
||||||
COPY --chmod=644 files/sudoers* /etc/sudoers.d
|
COPY --chmod=644 files/sudoers* /etc/sudoers.d
|
||||||
|
|
||||||
@@ -32,9 +34,9 @@ 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
|
ARG TARGETOS=linux
|
||||||
ARG TARGETARCH
|
ARG TARGETARCH=amd64
|
||||||
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
|
||||||
@@ -45,26 +47,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.11.0
|
ARG MC_HELPER_VERSION=1.16.5
|
||||||
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
|
||||||
@@ -72,11 +74,12 @@ WORKDIR /data
|
|||||||
STOPSIGNAL SIGTERM
|
STOPSIGNAL SIGTERM
|
||||||
|
|
||||||
ENV UID=1000 GID=1000 \
|
ENV UID=1000 GID=1000 \
|
||||||
MEMORY="1G" \
|
JVM_XX_OPTS="-XX:+UseG1GC" 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 --chmod=755 scripts/start* /
|
||||||
COPY --chmod=755 bin/ /usr/local/bin/
|
COPY --chmod=755 bin/ /usr/local/bin/
|
||||||
@@ -84,8 +87,9 @@ COPY --chmod=755 bin/mc-health /health.sh
|
|||||||
COPY --chmod=644 files/server.properties /tmp/server.properties
|
COPY --chmod=644 files/server.properties /tmp/server.properties
|
||||||
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
|
COPY --chmod=644 files/log4j2.xml /tmp/log4j2.xml
|
||||||
COPY --chmod=755 files/autopause /autopause
|
COPY --chmod=755 files/autopause /autopause
|
||||||
|
COPY --chmod=755 files/autostop /autostop
|
||||||
|
|
||||||
RUN dos2unix /start* /autopause/*
|
RUN dos2unix /start* /autopause/* /autostop/*
|
||||||
|
|
||||||
ENTRYPOINT [ "/start" ]
|
ENTRYPOINT [ "/start" ]
|
||||||
HEALTHCHECK --start-period=1m CMD mc-health
|
HEALTHCHECK --start-period=1m CMD mc-health
|
||||||
|
|||||||
263
README.md
263
README.md
@@ -24,6 +24,7 @@ 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)
|
||||||
@@ -45,6 +46,7 @@ By default, the container will download the latest version of the "vanilla" [Min
|
|||||||
* [Running a Bukkit/Spigot server](#running-a-bukkitspigot-server)
|
* [Running a 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)
|
||||||
@@ -66,13 +68,16 @@ 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)
|
||||||
* [Generic pack file](#generic-pack-file)
|
* [ForgeAPI usage to use non-version specific projects](#forgeapi-usage-to-use-non-version-specific-projects)
|
||||||
|
* [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)
|
||||||
@@ -128,16 +133,23 @@ 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: Tue Dec 14 02:14:33 UTC 2021 -->
|
<!-- Added by: runner, at: Sun Feb 6 18:45:39 UTC 2022 -->
|
||||||
|
|
||||||
<!--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
|
||||||
@@ -233,6 +245,8 @@ 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
|
||||||
@@ -275,14 +289,14 @@ When using the image `itzg:/minecraft-server` without a tag, the `latest` image
|
|||||||
|
|
||||||
| Tag name | Java version | Linux | JVM Type | Architecture |
|
| Tag name | Java version | Linux | JVM Type | Architecture |
|
||||||
| -------------- | -------------|--------|----------|-------------------|
|
| -------------- | -------------|--------|----------|-------------------|
|
||||||
| latest | 17 | Debian | Hotspot | amd64,arm64,armv7 |
|
| latest | 16 | Debian | Hotspot | amd64,arm64,armv7 |
|
||||||
| java8 | 8 | Alpine | Hotspot | amd64 |
|
| java8 | 8 | Alpine | Hotspot | amd64 |
|
||||||
| java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 |
|
| java8-multiarch | 8 | Debian | Hotspot | amd64,arm64,armv7 |
|
||||||
| 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:
|
||||||
|
|
||||||
@@ -300,7 +314,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/java16-openj9
|
||||||
|
|
||||||
## Healthcheck
|
## Healthcheck
|
||||||
|
|
||||||
@@ -380,7 +394,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/wiki/) mode by adding a `-e TYPE=FORGE` to your command-line.
|
Enable [Forge server](http://www.minecraftforge.net/) 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`.
|
||||||
|
|
||||||
@@ -470,12 +484,24 @@ 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 branch to download from. The available options are "LATEST" "1.17" and "PURPUR"
|
> 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.
|
||||||
|
|
||||||
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 [Flare](https://blog.airplane.gg/flare) profiler
|
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [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
|
||||||
|
|
||||||
@@ -488,7 +514,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 [Flare](https://blog.airplane.gg/flare) profiler
|
- `USE_FLARE_FLAGS=false` : set to true to add appropriate flags for the built-in [Flare](https://blog.airplane.gg/flare) profiler
|
||||||
|
|
||||||
### Running a Magma server
|
### Running a Magma server
|
||||||
|
|
||||||
@@ -565,6 +591,8 @@ 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`.
|
||||||
@@ -719,11 +747,77 @@ 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 ...
|
||||||
|
|
||||||
### Generic pack file
|
### ForgeAPI usage to use non-version specific projects
|
||||||
|
|
||||||
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.
|
**NOTE:** This potentially could lead to unexpected behavior if the Mod receives an update with unexpected behavior.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
@@ -763,23 +857,19 @@ 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 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 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.
|
||||||
|
|
||||||
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,
|
**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.
|
||||||
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 or zip file that will be used as a source to clone or unzip the world directory.
|
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.
|
||||||
|
|
||||||
For example, the following would initially clone the world's content
|
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.
|
||||||
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
|
||||||
@@ -792,6 +882,87 @@ 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.
|
||||||
@@ -1388,10 +1559,6 @@ To enable remote JMX, such as for profiling with VisualVM or JMC, add the enviro
|
|||||||
|
|
||||||
When `MEMORY` is greater than or equal to 12G, then the Aikar flags will be adjusted according to the article.
|
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`
|
||||||
@@ -1416,6 +1583,28 @@ 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
|
||||||
|
|
||||||
@@ -1447,6 +1636,8 @@ Enable the Autopause functionality by setting:
|
|||||||
|
|
||||||
Autopause is not compatible with `EXEC_DIRECTLY=true` and the two cannot be set together.
|
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)
|
||||||
@@ -1459,6 +1650,28 @@ 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`.
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ if [ ! -p "${CONSOLE_IN_NAMED_PIPE}" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "$@" > "${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}"
|
gosu minecraft bash -c "echo $* > '${CONSOLE_IN_NAMED_PIPE:-/tmp/minecraft-console-in}'"
|
||||||
@@ -3,12 +3,6 @@
|
|||||||
# 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 {
|
||||||
|
|||||||
20
examples/docker-compose-autostop.yml
Normal file
20
examples/docker-compose-autostop.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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: {}
|
||||||
@@ -13,6 +13,7 @@ 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"
|
||||||
|
|
||||||
|
|||||||
27
examples/vanilla-tweaks/docker-compose.yml
Normal file
27
examples/vanilla-tweaks/docker-compose.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
version: "3.3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
vanillatweaks_file:
|
||||||
|
restart: "no"
|
||||||
|
image: itzg/minecraft-server
|
||||||
|
ports:
|
||||||
|
- "25565:25565/tcp"
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
VANILLATWEAKS_FILE: /config/vanillatweaks-datapacks.json
|
||||||
|
REMOVE_OLD_VANILLATWEAKS: "TRUE"
|
||||||
|
volumes:
|
||||||
|
- data:/data
|
||||||
|
- ./vanillatweaks-datapacks.json:/config/vanillatweaks-datapacks.json:ro
|
||||||
|
vanillatweaks_sharecode:
|
||||||
|
# port is set to 25566 to not conflict with vanillatweaks_file example
|
||||||
|
ports:
|
||||||
|
- "25566:25565/tcp"
|
||||||
|
restart: "no"
|
||||||
|
image: itzg/minecraft-server
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
VANILLATWEAKS_SHARECODE: MGr52E
|
||||||
|
REMOVE_OLD_VANILLATWEAKS: "TRUE"
|
||||||
15
examples/vanilla-tweaks/vanillatweaks-datapacks.json
Normal file
15
examples/vanilla-tweaks/vanillatweaks-datapacks.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"version": "1.18",
|
||||||
|
"packs": {
|
||||||
|
"survival": [
|
||||||
|
"graves",
|
||||||
|
"multiplayer sleep",
|
||||||
|
"afk display",
|
||||||
|
"armor statues",
|
||||||
|
"unlock all recipes",
|
||||||
|
"fast leaf decay",
|
||||||
|
"coordinates hud"
|
||||||
|
],
|
||||||
|
"items": ["armored elytra"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,15 +5,15 @@ current_uptime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
java_running() {
|
java_running() {
|
||||||
[[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]]
|
[[ $( ps -a -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
java_process_exists() {
|
java_process_exists() {
|
||||||
[[ -n "$(ps -ax -o comm | grep 'java')" ]]
|
[[ -n "$(ps -a -o comm | grep 'java')" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
rcon_client_exists() {
|
rcon_client_exists() {
|
||||||
[[ -n "$(ps -ax -o comm | grep 'rcon-cli')" ]]
|
[[ -n "$(ps -a -o comm | grep 'rcon-cli')" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
mc_server_listening() {
|
mc_server_listening() {
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
[unpauseMCServer-server]
|
[unpauseMCServer-server]
|
||||||
sequence = 25565
|
sequence = 25565
|
||||||
seq_timeout = 1
|
seq_timeout = 1
|
||||||
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
|
command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh
|
||||||
tcpflags = syn
|
tcpflags = syn
|
||||||
[unpauseMCServer-rcon]
|
[unpauseMCServer-rcon]
|
||||||
sequence = 25575
|
sequence = 25575
|
||||||
seq_timeout = 1
|
seq_timeout = 1
|
||||||
command = /usr/sbin/gosu minecraft:minecraft /autopause/resume.sh
|
command = /sbin/su-exec minecraft:minecraft /autopause/resume.sh
|
||||||
tcpflags = syn
|
tcpflags = syn
|
||||||
[unpauseMCServer-bedrock]
|
[unpauseMCServer-bedrock]
|
||||||
sequence = 19132:udp
|
sequence = 19132:udp
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
. /start-utils
|
. /start-utils
|
||||||
|
|
||||||
if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^S.*$ ]] ; then
|
if [[ $( ps -a -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
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
. /start-utils
|
. /start-utils
|
||||||
|
|
||||||
if [[ $( ps -ax -o stat,comm | grep 'java' | awk '{ print $1 }') =~ ^T.*$ ]] ; then
|
if [[ $( ps -a -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
|
||||||
|
|||||||
69
files/autostop/autostop-daemon.sh
Executable file
69
files/autostop/autostop-daemon.sh
Executable file
@@ -0,0 +1,69 @@
|
|||||||
|
#!/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
|
||||||
6
files/autostop/stop.sh
Executable file
6
files/autostop/stop.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
. /start-utils
|
||||||
|
|
||||||
|
logAutostopAction "Stopping Java process"
|
||||||
|
kill -SIGTERM 1
|
||||||
@@ -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 gosu ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration $@
|
exec su-exec ${runAsUser}:${runAsGroup} ${SCRIPTS:-/}start-configuration "$@"
|
||||||
else
|
else
|
||||||
exec ${SCRIPTS:-/}start-configuration $@
|
exec ${SCRIPTS:-/}start-configuration "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
34
scripts/start-autostop
Executable file
34
scripts/start-autostop
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#!/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 &
|
||||||
@@ -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:=}"
|
||||||
@@ -37,6 +37,11 @@ if isTrue "${ENABLE_AUTOPAUSE}" && isTrue "${EXEC_DIRECTLY:-false}"; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
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"
|
||||||
export https_proxy="$PROXY"
|
export https_proxy="$PROXY"
|
||||||
@@ -61,9 +66,12 @@ 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 "Fixing PATH to include java"
|
log "ERROR: PATH should not be explicitly passed into the container"
|
||||||
PATH="${PATH}:/opt/java/openjdk/bin"
|
log " Remove configuration of that variable."
|
||||||
|
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
|
||||||
@@ -96,6 +104,10 @@ 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=(
|
||||||
@@ -107,39 +119,31 @@ 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)
|
||||||
if versionLessThan 1.17; then
|
evaluateJavaCompatibilityForForge
|
||||||
log "**********************************************************************"
|
exec "${SCRIPTS:-/}start-deployForge" "$@"
|
||||||
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)
|
||||||
exec ${SCRIPTS:-/}start-deployFTBA "$@"
|
log "ERROR: TYPE=FTBA is not supported with this image variant."
|
||||||
|
log " Use itzg/minecraft-server:java8-multiarch instead."
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
FTB|CURSEFORGE)
|
FTB|CURSEFORGE)
|
||||||
log "**********************************************************************"
|
evaluateJavaCompatibilityForForge
|
||||||
log "NOTE: Some mods and modpacks may require Java 8."
|
exec "${SCRIPTS:-/}start-deployCF" "$@"
|
||||||
log " If so, use itzg/minecraft-server:java8"
|
|
||||||
log "**********************************************************************"
|
|
||||||
exec ${SCRIPTS:-/}start-deployCF "$@"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
VANILLA)
|
VANILLA)
|
||||||
@@ -147,48 +151,50 @@ case "${TYPE^^}" in
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
SPONGEVANILLA)
|
SPONGEVANILLA)
|
||||||
exec ${SCRIPTS:-/}start-deploySpongeVanilla "$@"
|
exec "${SCRIPTS:-/}start-deploySpongeVanilla" "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
CUSTOM)
|
CUSTOM)
|
||||||
exec ${SCRIPTS:-/}start-deployCustom "$@"
|
evaluateJavaCompatibilityForForge
|
||||||
|
exec "${SCRIPTS:-/}start-deployCustom" "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
MAGMA)
|
MAGMA)
|
||||||
exec ${SCRIPTS:-/}start-deployMagma "$@"
|
evaluateJavaCompatibilityForForge
|
||||||
|
exec "${SCRIPTS:-/}start-deployMagma" "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
MOHIST)
|
MOHIST)
|
||||||
exec ${SCRIPTS:-/}start-deployMohist "$@"
|
evaluateJavaCompatibilityForForge
|
||||||
|
exec "${SCRIPTS:-/}start-deployMohist" "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
CATSERVER)
|
CATSERVER)
|
||||||
exec ${SCRIPTS:-/}start-deployCatserver "$@"
|
evaluateJavaCompatibilityForForge
|
||||||
|
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" "$@"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
@@ -196,7 +202,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, CANYON, LIMBO, CRUCIBLE"
|
log " MAGMA, MOHIST, CATSERVER, AIRPLANE, PUFFERFISH, CANYON, LIMBO, CRUCIBLE"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|||||||
@@ -6,46 +6,41 @@ isDebugging && set -x
|
|||||||
|
|
||||||
IFS=$'\n\t'
|
IFS=$'\n\t'
|
||||||
|
|
||||||
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "1.17" ] && [ "${VERSION}" != "PURPUR" ] ; then
|
if [ "${VERSION}" != "LATEST" ] && [ "${VERSION}" != "PURPUR" ] ; then
|
||||||
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=1.17, VERSION=PURPUR. Note that these are branches, not #.#.# versions."
|
log "ERROR: Airplane server type only supports VERSION=LATEST, VERSION=PURPUR."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
: ${AIRPLANE_BUILD:=lastSuccessfulBuild}
|
|
||||||
: ${AIRPLANE_TYPE:=airplane}
|
: ${AIRPLANE_TYPE:=airplane}
|
||||||
|
|
||||||
if [ "${VERSION}" = "LATEST" ] || [ "${VERSION}" = "1.17" ]; then
|
if [ "${VERSION}" = "LATEST" ] ; then
|
||||||
AIRPLANE_BRANCH="1.17"
|
AIRPLANE_TYPE="airplane"
|
||||||
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-${AIRPLANE_BRANCH} branch"
|
log "Using ${AIRPLANE_TYPE} 1.17.1 (1.18 unsupported - use Paper/Pufferfish/Purpur for newer versions)"
|
||||||
|
|
||||||
export SERVER=airplane-${AIRPLANE_BRANCH}-${AIRPLANE_BUILD}.jar
|
export SERVER=${AIRPLANE_TYPE}-1.17.1.jar
|
||||||
|
|
||||||
log "Removing old Airplane versions ..."
|
log "Removing old Airplane versions ..."
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
for f in airplane-*.jar; do
|
for f in airplane*.jar; do
|
||||||
[[ $f != $SERVER ]] && rm $f
|
[[ $f != $SERVER ]] && rm $f
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
|
if [ ! -f "$SERVER" ] || isTrue "${FORCE_REDOWNLOAD:-false}"; then
|
||||||
downloadUrl="https://ci.tivy.ca/job/Airplane-${AIRPLANE_BRANCH}/${AIRPLANE_BUILD}/artifact/launcher-${AIRPLANE_TYPE}.jar"
|
downloadUrl="https://airplane.gg/dl/launcher-${AIRPLANE_TYPE}1.17.1.jar"
|
||||||
log "Downloading Airplane from $downloadUrl ..."
|
log "Downloading Airplane from $downloadUrl ..."
|
||||||
curl -fsSL -o "$SERVER" "$downloadUrl"
|
if ! get -o "$SERVER" "$downloadUrl"; then
|
||||||
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 TYPE=SPIGOT
|
|
||||||
export FAMILY=SPIGOT
|
export FAMILY=SPIGOT
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
exec "${SCRIPTS:-/}start-spiget" "$@"
|
||||||
|
|||||||
@@ -126,8 +126,6 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Normalize on Spigot for operations below
|
# Normalize on Spigot for operations below
|
||||||
export TYPE=SPIGOT
|
|
||||||
export FAMILY=SPIGOT
|
export FAMILY=SPIGOT
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||||
|
|||||||
@@ -35,11 +35,37 @@ 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
|
||||||
|
|
||||||
if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
|
downloadModpack() {
|
||||||
if ! [ -f "${FTB_SERVER_MOD}" ]; then
|
srv_modpack=${FTB_SERVER_MOD}
|
||||||
log "ERROR unable to find requested modpack file ${FTB_SERVER_MOD}"
|
if isURL "${srv_modpack}"; then
|
||||||
exit 2
|
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
|
fi
|
||||||
|
if [[ "${srv_modpack:0:5}" == "data/" ]]; then
|
||||||
|
# Prepend with "/"
|
||||||
|
srv_modpack="/${srv_modpack}"
|
||||||
|
fi
|
||||||
|
if [[ ! "${srv_modpack:0:1}" == "/" ]]; then
|
||||||
|
# If not an absolute path, assume file is in "/data"
|
||||||
|
srv_modpack=/data/${srv_modpack}
|
||||||
|
fi
|
||||||
|
if [[ ! -f "${srv_modpack}" ]]; then
|
||||||
|
log "FTB server modpack ${srv_modpack} not found."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
if [[ ! "${srv_modpack: -4}" == ".zip" ]]; then
|
||||||
|
log "FTB server modpack ${srv_modpack} is not a zip archive."
|
||||||
|
log "Please set FTB_SERVER_MOD to a file with a .zip extension."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
FTB_SERVER_MOD=${srv_modpack}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! isTrue "${USE_MODPACK_START_SCRIPT:-true}"; then
|
||||||
|
downloadModpack
|
||||||
|
|
||||||
needsInstall=true
|
needsInstall=true
|
||||||
installMarker=/data/.curseforge-installed
|
installMarker=/data/.curseforge-installed
|
||||||
@@ -47,7 +73,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}" -not -name "forge*installer.jar" -name "forge*.jar")
|
serverJar=$(find "${FTB_BASE_DIR}" -type f \( -path "*/libraries/*" -o -path "*/mods/*" \) -prune -o -name "forge*.jar" -not -name "forge*installer.jar" -print)
|
||||||
if [[ "${serverJar}" ]]; then
|
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
|
||||||
@@ -85,6 +111,8 @@ 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)
|
||||||
@@ -132,32 +160,9 @@ 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 ""}'
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ if [ ! -f "$SERVER" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Normalize on Spigot for later operations
|
# Normalize on Spigot for later operations
|
||||||
export TYPE=SPIGOT
|
|
||||||
export FAMILY=SPIGOT
|
export FAMILY=SPIGOT
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
# shellcheck source=start-utils
|
||||||
|
. "${SCRIPTS:-/}start-utils"
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -26,8 +27,6 @@ if [ ! -f ${SERVER} ]; then
|
|||||||
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId}
|
curl -H "Accept:application/octet-stream" -o "$SERVER" -fsSL https://api.github.com/repos/Luohuayu/CatServer/releases/assets/${latestJarId}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
|
|
||||||
export FAMILY=HYBRID
|
export FAMILY=HYBRID
|
||||||
# Continue to Final Setup
|
|
||||||
exec ${SCRIPTS:-/}start-setupWorld "$@"
|
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ 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
|
||||||
@@ -55,7 +56,6 @@ if [ ! -d "$librariesDir" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
export SERVER
|
export SERVER
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
export FAMILY=HYBRID
|
export FAMILY=HYBRID
|
||||||
|
|
||||||
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"
|
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
# shellcheck source=start-utils
|
||||||
|
. "${SCRIPTS:-/}start-utils"
|
||||||
isDebugging && set -x
|
isDebugging && set -x
|
||||||
|
|
||||||
if isURL ${CUSTOM_SERVER}; then
|
if isURL ${CUSTOM_SERVER}; then
|
||||||
@@ -30,6 +31,6 @@ else
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
export FAMILY=HYBRID
|
export FAMILY=HYBRID
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-setupWorld $@
|
exec ${SCRIPTS:-/}start-setupWorld $@
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
ftbInstallMarker=".ftb-installed"
|
ftbInstallMarker=".ftb-installed"
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
# shellcheck source=start-utils
|
||||||
|
. "${SCRIPTS:-/}start-utils"
|
||||||
isDebugging && set -x
|
isDebugging && set -x
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -80,4 +81,5 @@ if ! [ -v SERVER ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
export FAMILY=FORGE
|
export FAMILY=FORGE
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-setupWorld $@
|
exec ${SCRIPTS:-/}start-setupWorld $@
|
||||||
|
|||||||
@@ -38,18 +38,23 @@ install() {
|
|||||||
get_installer "$normForgeVersion" "$shortForgeVersion"
|
get_installer "$normForgeVersion" "$shortForgeVersion"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "Installing Forge $shortForgeVersion using $FORGE_INSTALLER"
|
log "Installing Forge $shortForgeVersion. This might take a minute or two..."
|
||||||
mkdir -p mods
|
mkdir -p mods
|
||||||
tries=3
|
tries=3
|
||||||
while ((--tries >= 0)); do
|
while true; do
|
||||||
if java -jar "$FORGE_INSTALLER" --installServer; then
|
if ! java -jar "$FORGE_INSTALLER" --installServer &> forge-installer.log; then
|
||||||
break
|
if ((--tries <= 0)); then
|
||||||
|
cat forge-installer.log
|
||||||
|
log "
|
||||||
|
ERROR Forge failed to install after several tries.
|
||||||
|
"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
log "Install failed. Trying again..."
|
||||||
|
else
|
||||||
|
break # out of this loop
|
||||||
fi
|
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
|
||||||
@@ -148,4 +153,5 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
export FAMILY=FORGE
|
export FAMILY=FORGE
|
||||||
|
|
||||||
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||||
|
|||||||
@@ -58,7 +58,5 @@ if [[ ${LEVEL} != *\;* ]]; then
|
|||||||
fi
|
fi
|
||||||
export LEVEL
|
export LEVEL
|
||||||
|
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
|
|
||||||
export FAMILY=LIMBO
|
export FAMILY=LIMBO
|
||||||
exec ${SCRIPTS:-/}start-setupWorld $@
|
exec ${SCRIPTS:-/}start-setupWorld $@
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
# shellcheck source=start-utils
|
||||||
export SKIP_LOG4J_CONFIG=true
|
. "${SCRIPTS:-/}start-utils"
|
||||||
|
|
||||||
isDebugging && set -x
|
isDebugging && set -x
|
||||||
|
|
||||||
: ${VANILLA_VERSION?}
|
: "${VANILLA_VERSION?}"
|
||||||
# stable, dev
|
# stable, dev
|
||||||
: ${MAGMA_CHANNEL:=stable}
|
: "${MAGMA_CHANNEL:=stable}"
|
||||||
|
|
||||||
|
|
||||||
magmaDownloadServer() {
|
magmaDownloadServer() {
|
||||||
@@ -90,4 +89,5 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
export FAMILY=HYBRID
|
export FAMILY=HYBRID
|
||||||
exec ${SCRIPTS:-/}start-setupWorld "$@"
|
|
||||||
|
exec "${SCRIPTS:-/}start-setupWorld" "$@"
|
||||||
|
|||||||
@@ -38,7 +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 SKIP_LOG4J_CONFIG=true
|
|
||||||
|
|
||||||
export FAMILY=HYBRID
|
export FAMILY=HYBRID
|
||||||
|
|
||||||
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"
|
exec "${SCRIPTS:-$(dirname "$0")}/start-setupWorld" "$@"
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Normalize on Spigot for downstream operations
|
# Normalize on Spigot for downstream operations
|
||||||
export TYPE=SPIGOT
|
|
||||||
export FAMILY=SPIGOT
|
export FAMILY=SPIGOT
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
exec ${SCRIPTS:-/}start-spiget "$@"
|
||||||
|
|||||||
44
scripts/start-deployPufferfish
Executable file
44
scripts/start-deployPufferfish
Executable file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/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 "$@"
|
||||||
@@ -2,20 +2,19 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
IFS=$'\n\t'
|
IFS=$'\n\t'
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
# shellcheck source=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
|
||||||
PURPUR_BUILD=$(curl -fsSL "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}" |
|
if ! PURPUR_BUILD=$(get --json-path=".builds.latest" "https://api.purpurmc.org/v2/purpur/${VANILLA_VERSION}"); then
|
||||||
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 3
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -24,15 +23,13 @@ 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 ! curl -fsSL -o "$SERVER" "$downloadUrl"; then
|
if ! get -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 TYPE=SPIGOT
|
|
||||||
export FAMILY=SPIGOT
|
export FAMILY=SPIGOT
|
||||||
export SKIP_LOG4J_CONFIG=true
|
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-spiget "$@"
|
exec "${SCRIPTS:-/}start-spiget" "$@"
|
||||||
|
|||||||
@@ -1,97 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
# shellcheck source=start-utils
|
||||||
|
. "${SCRIPTS:-/}start-utils"
|
||||||
isDebugging && set -x
|
isDebugging && set -x
|
||||||
|
|
||||||
if versionLessThan 1.7.6; then
|
|
||||||
opsFile=ops.txt
|
|
||||||
whitelistFile=white-list.txt
|
|
||||||
else
|
|
||||||
opsFile=ops.json
|
|
||||||
whitelistFile=whitelist.json
|
|
||||||
fi
|
|
||||||
|
|
||||||
function process_user_file() {
|
|
||||||
local output=$1
|
|
||||||
local source=$2
|
|
||||||
|
|
||||||
if isURL "$source"; then
|
|
||||||
log "Downloading $output from $source"
|
|
||||||
if ! get -o /data/$output "$source"; then
|
|
||||||
log "ERROR: failed to download from $source"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log "Copying $output from $source"
|
|
||||||
if ! cp "$source" /data/$output; then
|
|
||||||
log "ERROR: failed to copy from $source"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function process_user_csv() {
|
|
||||||
local output=$1
|
|
||||||
local list=$2
|
|
||||||
local playerDataList
|
|
||||||
|
|
||||||
if [[ "$output" == *"ops"* ]]; then
|
|
||||||
# Extra data for ops.json
|
|
||||||
userData='{"uuid": .id, "name": .username, "level": 4}'
|
|
||||||
else
|
|
||||||
userData='{"uuid": .id, "name": .username}'
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Updating ${output%.*}"
|
|
||||||
for i in ${list//,/ }
|
|
||||||
do
|
|
||||||
if [ -e "$output" ] && grep -q "$i" "$output"; then
|
|
||||||
log "$i already present in $output, skipping"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then
|
|
||||||
log "WARNING: Could not lookup user $i for ${output} addition"
|
|
||||||
else
|
|
||||||
playerDataList=$playerDataList$(echo $playerData | jq -r "$userData")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
local newUsers=$(echo $playerDataList | jq -s .)
|
|
||||||
if [[ $output =~ .*\.txt ]]; then
|
|
||||||
# username list for txt config (Minecraft <= 1.7.5)
|
|
||||||
echo $newUsers | jq -r '.[].name' >> /data/${output}
|
|
||||||
sort -u /data/${output} -o /data/${output}
|
|
||||||
elif [ -e /data/${output} ]; then
|
|
||||||
# Merge with existing json file
|
|
||||||
local currentUsers=$(cat /data/${output})
|
|
||||||
jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > /data/${output}
|
|
||||||
else
|
|
||||||
# New json file
|
|
||||||
echo $newUsers > /data/${output}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if isTrue "${OVERRIDE_OPS}"; then
|
|
||||||
log "Recreating ${opsFile} file at server startup"
|
|
||||||
rm -f /data/${opsFile}
|
|
||||||
fi
|
|
||||||
if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then
|
|
||||||
process_user_file ${opsFile} "$OPS_FILE"
|
|
||||||
fi
|
|
||||||
if [ -n "${OPS}" ]; then
|
|
||||||
process_user_csv ${opsFile} "$OPS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if isTrue "${OVERRIDE_WHITELIST}"; then
|
|
||||||
log "Recreating ${whitelistFile} file at server startup"
|
|
||||||
rm -f /data/${whitelistFile}
|
|
||||||
fi
|
|
||||||
if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then
|
|
||||||
process_user_file ${whitelistFile} "$WHITELIST_FILE"
|
|
||||||
fi
|
|
||||||
if [ -n "${WHITELIST}" ]; then
|
|
||||||
process_user_csv ${whitelistFile} "$WHITELIST"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$ICON" ]; then
|
if [ -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..."
|
||||||
@@ -108,13 +20,15 @@ if [ -n "$ICON" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
canUseRollingLogs=true
|
canUseRollingLogs=true
|
||||||
|
useFallbackJvmFlag=false
|
||||||
|
|
||||||
patchLog4jConfig() {
|
patchLog4jConfig() {
|
||||||
file=${1?}
|
file=${1?}
|
||||||
url=${2?}
|
url=${2?}
|
||||||
if ! get -o "$file" "$url"; then
|
if ! get -o "$file" "$url"; then
|
||||||
log "ERROR: failed to download corrected log4j config"
|
log "ERROR: failed to download corrected log4j config, fallback to JVM flag"
|
||||||
exit 1
|
useFallbackJvmFlag=true
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
|
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
|
||||||
canUseRollingLogs=false
|
canUseRollingLogs=false
|
||||||
@@ -128,7 +42,16 @@ elif isFamily VANILLA && versionLessThan 1.12; then
|
|||||||
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
|
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
|
||||||
elif isFamily VANILLA && versionLessThan 1.17; then
|
elif isFamily VANILLA && versionLessThan 1.17; then
|
||||||
patchLog4jConfig log4j2_112-116.xml https://launcher.mojang.com/v1/objects/02937d122c86ce73319ef9975b58896fc1b491d1/log4j2_112-116.xml
|
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
|
elif versionLessThan 1.18.1; then
|
||||||
|
useFallbackJvmFlag=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ${useFallbackJvmFlag}; then
|
||||||
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
|
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -164,7 +87,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 || ${GUI} = FALSE ]]; then
|
if [[ ${GUI,,} = false ]]; then
|
||||||
EXTRA_ARGS+=" nogui"
|
EXTRA_ARGS+=" nogui"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -236,12 +159,6 @@ 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
|
||||||
@@ -329,10 +246,14 @@ EOF
|
|||||||
else
|
else
|
||||||
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
|
exec mc-server-runner "${mcServerRunnerArgs[@]}" "${finalArgs[@]}"
|
||||||
fi
|
fi
|
||||||
elif [[ -x run.sh ]]; then
|
elif [[ $SERVER =~ 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
|
||||||
exec mc-server-runner "${mcServerRunnerArgs[@]}" --shell bash run.sh
|
if isTrue ${SETUP_ONLY:=false}; then
|
||||||
|
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
|
||||||
|
|||||||
77
scripts/start-setupDatapack
Executable file
77
scripts/start-setupDatapack
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
#!/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" "$@"
|
||||||
@@ -32,4 +32,4 @@ if [[ ${PATCH_DEFINITIONS} ]]; then
|
|||||||
"${PATCH_DEFINITIONS}"
|
"${PATCH_DEFINITIONS}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "${SCRIPTS:-/}start-finalExec" "$@"
|
exec "${SCRIPTS:-/}start-setupRbac" "$@"
|
||||||
|
|||||||
221
scripts/start-setupForgeApiMods
Normal file
221
scripts/start-setupForgeApiMods
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
#!/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" "$@"
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
# shellcheck source=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
|
||||||
@@ -9,7 +10,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 [ "$TYPE" = "SPIGOT" ]; then
|
if [ "$FAMILY" = "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
|
||||||
@@ -24,4 +25,4 @@ case "X$MODCONFIG" in
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-setupMounts $@
|
exec "${SCRIPTS:-/}start-setupMounts" "$@"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ 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"
|
||||||
@@ -18,16 +19,17 @@ 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/comp500/packwiz-installer-bootstrap/releases/latest)
|
latestPackwiz=$(curl -fsSL https://api.github.com/repos/packwiz/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}"
|
||||||
@@ -65,7 +67,7 @@ if [[ "$MODPACK" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$TYPE" = "SPIGOT" ]; then
|
if [ "$FAMILY" = "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}"
|
||||||
@@ -79,7 +81,7 @@ if [[ "$MODPACK" ]]; then
|
|||||||
rm -f /tmp/modpack.zip
|
rm -f /tmp/modpack.zip
|
||||||
|
|
||||||
elif [[ "$MODS" ]]; then
|
elif [[ "$MODS" ]]; then
|
||||||
if [ "$TYPE" = "SPIGOT" ]; then
|
if [ "$FAMILY" = "SPIGOT" ]; then
|
||||||
out_dir=/data/plugins
|
out_dir=/data/plugins
|
||||||
else
|
else
|
||||||
out_dir=/data/mods
|
out_dir=/data/mods
|
||||||
@@ -90,7 +92,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 -o "${out_dir}" "$i"; then
|
if ! get --skip-up-to-date -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
|
||||||
@@ -116,7 +118,7 @@ elif [[ "$MODS_FILE" ]]; then
|
|||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$TYPE" = "SPIGOT" ]; then
|
if [ "$FAMILY" = "SPIGOT" ]; then
|
||||||
out_dir=/data/plugins
|
out_dir=/data/plugins
|
||||||
else
|
else
|
||||||
out_dir=/data/mods
|
out_dir=/data/mods
|
||||||
@@ -126,7 +128,7 @@ elif [[ "$MODS_FILE" ]]; then
|
|||||||
args=(
|
args=(
|
||||||
-o "${out_dir}"
|
-o "${out_dir}"
|
||||||
--log-progress-each
|
--log-progress-each
|
||||||
--skip-existing
|
--skip-up-to-date
|
||||||
--uris-file "${MODS_FILE}"
|
--uris-file "${MODS_FILE}"
|
||||||
)
|
)
|
||||||
if isTrue "${REMOVE_OLD_MODS}"; then
|
if isTrue "${REMOVE_OLD_MODS}"; then
|
||||||
@@ -186,15 +188,19 @@ 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 pack in "${packs[@]}"; do
|
for packEntry in "${packs[@]}"; do
|
||||||
if isURL "$pack"; then
|
pack="${GENERIC_PACKS_PREFIX}${packEntry}${GENERIC_PACKS_SUFFIX}"
|
||||||
|
if isURL "${pack}"; then
|
||||||
mkdir -p /data/packs
|
mkdir -p /data/packs
|
||||||
if ! outfile=$(get -o /data/packs --output-filename --skip-existing "$pack"); then
|
log "Downloading generic pack from $pack"
|
||||||
|
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
|
||||||
@@ -204,14 +210,19 @@ 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}"
|
||||||
unzip -q -d ${base_dir} "${pack}"
|
extract "${pack}" "${base_dir}"
|
||||||
done
|
done
|
||||||
|
|
||||||
# recalculate the actual base directory of content
|
# recalculate the actual base directory of content
|
||||||
@@ -239,7 +250,8 @@ 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
|
||||||
|
|
||||||
sha256sum "${packFiles[@]}" > "${sum_file}"
|
log "Saving generic pack(s) checksum"
|
||||||
|
sha1sum "${packFiles[@]}" > "${sum_file}"
|
||||||
isDebugging && cat "$sum_file"
|
isDebugging && cat "$sum_file"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
. ${SCRIPTS:-/}start-utils
|
# shellcheck source=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
|
||||||
@@ -24,8 +25,8 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -d /plugins ]; then
|
if [ -d /plugins ]; then
|
||||||
case ${TYPE} in
|
case ${FAMILY} in
|
||||||
SPIGOT|BUKKIT|PAPER|MAGMA)
|
SPIGOT|HYBRID)
|
||||||
mkdir -p /data/plugins
|
mkdir -p /data/plugins
|
||||||
log "Copying plugins over..."
|
log "Copying plugins over..."
|
||||||
mc-image-helper \
|
mc-image-helper \
|
||||||
@@ -40,7 +41,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..."
|
||||||
@@ -53,7 +54,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}"
|
||||||
@@ -66,4 +67,4 @@ if [ -d /config ]; then
|
|||||||
/config "${COPY_CONFIG_DEST}"
|
/config "${COPY_CONFIG_DEST}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec ${SCRIPTS:-/}start-setupServerProperties $@
|
exec "${SCRIPTS:-/}start-setupServerProperties" "$@"
|
||||||
|
|||||||
98
scripts/start-setupRbac
Normal file
98
scripts/start-setupRbac
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# shellcheck source=start-utils
|
||||||
|
. "${SCRIPTS:-/}start-utils"
|
||||||
|
isDebugging && set -x
|
||||||
|
|
||||||
|
if versionLessThan 1.7.6; then
|
||||||
|
opsFile=ops.txt
|
||||||
|
whitelistFile=white-list.txt
|
||||||
|
else
|
||||||
|
opsFile=ops.json
|
||||||
|
whitelistFile=whitelist.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
function process_user_file() {
|
||||||
|
local output=$1
|
||||||
|
local source=$2
|
||||||
|
|
||||||
|
if isURL "$source"; then
|
||||||
|
log "Downloading $output from $source"
|
||||||
|
if ! get -o "/data/$output" "$source"; then
|
||||||
|
log "ERROR: failed to download from $source"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "Copying $output from $source"
|
||||||
|
if ! cp "$source" "/data/$output"; then
|
||||||
|
log "ERROR: failed to copy from $source"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function process_user_csv() {
|
||||||
|
local output=$1
|
||||||
|
local list=$2
|
||||||
|
local playerDataList
|
||||||
|
|
||||||
|
if [[ "$output" == *"ops"* ]]; then
|
||||||
|
# Extra data for ops.json
|
||||||
|
userData='{"uuid": .id, "name": .username, "level": 4}'
|
||||||
|
else
|
||||||
|
userData='{"uuid": .id, "name": .username}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Updating ${output%.*}"
|
||||||
|
for i in ${list//,/ }
|
||||||
|
do
|
||||||
|
if [ -e "$output" ] && grep -q "$i" "$output"; then
|
||||||
|
log "$i already present in $output, skipping"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then
|
||||||
|
log "WARNING: Could not lookup user $i for ${output} addition"
|
||||||
|
else
|
||||||
|
playerDataList=$playerDataList$(echo "$playerData" | jq -r "$userData")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
local newUsers=$(echo "$playerDataList" | jq -s .)
|
||||||
|
if [[ $output =~ .*\.txt ]]; then
|
||||||
|
# username list for txt config (Minecraft <= 1.7.5)
|
||||||
|
echo $newUsers | jq -r '.[].name' >> "/data/${output}"
|
||||||
|
sort -u /data/${output} -o /data/${output}
|
||||||
|
elif [ -e /data/${output} ]; then
|
||||||
|
# Merge with existing json file
|
||||||
|
local currentUsers=$(cat "/data/${output}")
|
||||||
|
jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > "/data/${output}"
|
||||||
|
else
|
||||||
|
# New json file
|
||||||
|
echo $newUsers > "/data/${output}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if isTrue "${OVERRIDE_OPS}"; then
|
||||||
|
log "Recreating ${opsFile} file at server startup"
|
||||||
|
rm -f /data/${opsFile}
|
||||||
|
fi
|
||||||
|
if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then
|
||||||
|
process_user_file ${opsFile} "$OPS_FILE"
|
||||||
|
fi
|
||||||
|
if [ -n "${OPS}" ]; then
|
||||||
|
process_user_csv ${opsFile} "$OPS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isTrue "${OVERRIDE_WHITELIST}"; then
|
||||||
|
log "Recreating ${whitelistFile} file at server startup"
|
||||||
|
rm -f /data/${whitelistFile}
|
||||||
|
fi
|
||||||
|
if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then
|
||||||
|
process_user_file ${whitelistFile} "$WHITELIST_FILE"
|
||||||
|
fi
|
||||||
|
if [ -n "${WHITELIST}" ]; then
|
||||||
|
process_user_csv ${whitelistFile} "$WHITELIST"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
exec "${SCRIPTS:-/}start-finalExec" "$@"
|
||||||
@@ -48,7 +48,7 @@ function customizeServerProps {
|
|||||||
|
|
||||||
# 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 [ -z "$MOTD" ]; then
|
if ! [ -v 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,6 +62,13 @@ 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
|
||||||
|
|||||||
126
scripts/start-setupVanillaTweaks
Normal file
126
scripts/start-setupVanillaTweaks
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
#!/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" "$@"
|
||||||
@@ -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,49 +19,102 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
|
|||||||
"${worldDest}_the_end"
|
"${worldDest}_the_end"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if isURL $WORLD; then
|
if isURL "$WORLD"; then
|
||||||
curl -fsSL "$WORLD" -o /tmp/world.zip
|
log "Downloading world from $WORLD"
|
||||||
zipSrc=/tmp/world.zip
|
if ! get -o /tmp/world.bin "$WORLD"; then
|
||||||
elif [[ "$WORLD" =~ .*\.zip ]]; then
|
log "ERROR: failed to download world from $WORLD"
|
||||||
zipSrc="$WORLD"
|
exit 1
|
||||||
|
fi
|
||||||
|
WORLD=/tmp/world.bin
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$zipSrc" ]]; then
|
if [ -f "$WORLD" ]; then
|
||||||
log "Unzipping world"
|
log "Extracting 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
|
||||||
(cd /tmp/world-data && unzip -o -q "$zipSrc")
|
if ! extract "$WORLD" /tmp/world-data; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$TYPE" = "SPIGOT" ]; then
|
baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;)
|
||||||
baseDirs=$(find /tmp/world-data -name "level.dat" -not -path "*_nether*" -not -path "*_the_end*" -exec dirname "{}" \;)
|
|
||||||
else
|
if ! [[ $baseDirs ]]; then
|
||||||
baseDirs=$(find /tmp/world-data -name "level.dat" -exec dirname "{}" \;)
|
log "ERROR world content is not valid since level.dat could not be found"
|
||||||
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
count=$(echo "$baseDirs" | wc -l)
|
count=$(echo "$baseDirs" | wc -l)
|
||||||
if [[ $count -gt 1 ]]; then
|
if [[ $count -gt 1 ]]; then
|
||||||
baseDir="$(echo "$baseDirs" | sed -n ${WORLD_INDEX:-1}p)"
|
baseDirsNoSpigotSuffix=$(echo "$baseDirs" | sed -re 's:(_nether|_the_end)/?$::' | sort -u)
|
||||||
baseName=$(basename "$baseDir")
|
if [ $(echo "$baseDirsNoSpigotSuffix" | wc -l) -eq 1 ]; then
|
||||||
log "WARN multiple levels found, picking: $baseName"
|
baseDir="$baseDirsNoSpigotSuffix"
|
||||||
|
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
|
||||||
rsync --remove-source-files --recursive --delete "$baseDir/" "$worldDest"
|
|
||||||
if [ "$TYPE" = "SPIGOT" ]; then
|
if [ -d "${baseDir}_nether/DIM-1" ]; then
|
||||||
log "Copying end and nether ..."
|
if [ -d "$baseDir/DIM-1" ]; then
|
||||||
[ -d "${baseDir}_nether" ] && rsync --remove-source-files --recursive --delete "${baseDir}_nether/" "${worldDest}_nether"
|
log "WARN found Nether dimension in both $baseDir and ${baseDir}_nether, picking ${baseDir}_nether"
|
||||||
[ -d "${baseDir}_the_end" ] && rsync --remove-source-files --recursive --delete "${baseDir}_the_end/" "${worldDest}_the_end"
|
rm -r "$baseDir/DIM-1"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
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"
|
||||||
|
|
||||||
|
if [ "$FAMILY" = "SPIGOT" ]; then
|
||||||
|
if [ -d "${baseDir}_nether" ]; then
|
||||||
|
log "Copying Spigot Nether..."
|
||||||
|
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
|
||||||
|
elif [ -d "$WORLD" ]; then
|
||||||
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 [ "$TYPE" = "SPIGOT" ]; then
|
if [ "$FAMILY" = "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"
|
||||||
@@ -69,4 +122,4 @@ if [[ "$WORLD" ]] && ( isTrue "${FORCE_WORLD_COPY}" || [ ! -d "$worldDest" ] );
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "${SCRIPTS:-/}start-setupModpack" "$@"
|
exec "${SCRIPTS:-/}start-setupVanillaTweaks" "$@"
|
||||||
|
|||||||
@@ -22,6 +22,20 @@ 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?}
|
||||||
|
|
||||||
@@ -81,9 +95,12 @@ 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}"
|
||||||
else
|
elif containsPlugin "${tmpfile}"; then
|
||||||
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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ function getFilenameFromUrl() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isTrue() {
|
function isTrue() {
|
||||||
|
local oldState
|
||||||
|
oldState=$(shopt -po xtrace)
|
||||||
|
shopt -u -o xtrace
|
||||||
|
|
||||||
local value=${1,,}
|
local value=${1,,}
|
||||||
|
|
||||||
result=
|
result=
|
||||||
@@ -53,6 +57,7 @@ function isTrue() {
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
eval "$oldState"
|
||||||
return ${result}
|
return ${result}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +87,18 @@ function logn() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function log() {
|
function log() {
|
||||||
echo "[init] $*"
|
local oldState
|
||||||
|
# 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() {
|
||||||
@@ -93,6 +109,14 @@ 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
|
||||||
@@ -170,5 +194,62 @@ function isFamily() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
return 1
|
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
Normal file
1
tests/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
data/
|
||||||
43
tests/fulltests/test.sh
Normal file
43
tests/fulltests/test.sh
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/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
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
version: "3.8"
|
version: "3"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
monitor:
|
monitor:
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
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: {}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mc:
|
||||||
|
restart: "no"
|
||||||
|
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
SETUP_ONLY: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
TYPE: "PAPER"
|
||||||
|
WORLD: /worlds/world-for-testing.zip
|
||||||
|
volumes:
|
||||||
|
- ./worlds:/worlds:ro
|
||||||
|
- ./data:/data
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
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
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mc:
|
||||||
|
restart: "no"
|
||||||
|
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
SETUP_ONLY: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
WORLD: /worlds/world-for-testing.zip
|
||||||
|
volumes:
|
||||||
|
- ./worlds:/worlds:ro
|
||||||
|
- ./data:/data
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
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
|
||||||
Binary file not shown.
@@ -0,0 +1,18 @@
|
|||||||
|
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
|
||||||
17
tests/setuponlytests/forgeapimods_file/forgeapi_mods.json
Normal file
17
tests/setuponlytests/forgeapimods_file/forgeapi_mods.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
]
|
||||||
1
tests/setuponlytests/forgeapimods_file/require.sh
Normal file
1
tests/setuponlytests/forgeapimods_file/require.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[[ $MODS_FORGEAPI_KEY ]] || exit 1
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
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"
|
||||||
1
tests/setuponlytests/forgeapimods_projectids/require.sh
Normal file
1
tests/setuponlytests/forgeapimods_projectids/require.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[[ $MODS_FORGEAPI_KEY ]] || exit 1
|
||||||
14
tests/setuponlytests/generic-packs-prefix/docker-compose.yml
Normal file
14
tests/setuponlytests/generic-packs-prefix/docker-compose.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
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
|
||||||
1
tests/setuponlytests/generic-packs-prefix/verify.sh
Normal file
1
tests/setuponlytests/generic-packs-prefix/verify.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
mc-image-helper assert fileExists one.txt mods/two.txt
|
||||||
24
tests/setuponlytests/generic-packs/docker-compose.yml
Normal file
24
tests/setuponlytests/generic-packs/docker-compose.yml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
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
|
||||||
0
tests/setuponlytests/generic-packs/fake.jar
Normal file
0
tests/setuponlytests/generic-packs/fake.jar
Normal file
BIN
tests/setuponlytests/generic-packs/packs/testing.zip
Normal file
BIN
tests/setuponlytests/generic-packs/packs/testing.zip
Normal file
Binary file not shown.
2
tests/setuponlytests/generic-packs/verify.sh
Normal file
2
tests/setuponlytests/generic-packs/verify.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
mc-image-helper assert fileExists one.txt mods/two.txt
|
||||||
|
mc-image-helper assert fileExists config/opt.yml
|
||||||
BIN
tests/setuponlytests/generic-packs/web/configs.zip
Normal file
BIN
tests/setuponlytests/generic-packs/web/configs.zip
Normal file
Binary file not shown.
13
tests/setuponlytests/ops_from_scratch/docker-compose.yml
Normal file
13
tests/setuponlytests/ops_from_scratch/docker-compose.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mc:
|
||||||
|
restart: "no"
|
||||||
|
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
SETUP_ONLY: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
OPS: itzg
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
3
tests/setuponlytests/ops_from_scratch/verify.sh
Normal file
3
tests/setuponlytests/ops_from_scratch/verify.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].name' --expect=itzg
|
||||||
|
mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].uuid' --expect=5cddfd26-fc86-4981-b52e-c42bb10bfdef
|
||||||
|
mc-image-helper assert jsonPathEquals --file=ops.json --path='$[0].level' --expect=4
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mc:
|
||||||
|
restart: "no"
|
||||||
|
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
SETUP_ONLY: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
TYPE: "PAPER"
|
||||||
|
WORLD: /worlds/world-for-testing.zip
|
||||||
|
volumes:
|
||||||
|
- ./worlds:/worlds:ro
|
||||||
|
- ./data:/data
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
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
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mc:
|
||||||
|
restart: "no"
|
||||||
|
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
SETUP_ONLY: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
WORLD: /worlds/world-for-testing.zip
|
||||||
|
volumes:
|
||||||
|
- ./worlds:/worlds:ro
|
||||||
|
- ./data:/data
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
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
|
||||||
Binary file not shown.
61
tests/setuponlytests/test.sh
Normal file
61
tests/setuponlytests/test.sh
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#!/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
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mc:
|
||||||
|
restart: "no"
|
||||||
|
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
SETUP_ONLY: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
TYPE: "PAPER"
|
||||||
|
WORLD: /worlds/world-for-testing.zip
|
||||||
|
volumes:
|
||||||
|
- ./worlds:/worlds:ro
|
||||||
|
- ./data:/data
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
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
|
||||||
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mc:
|
||||||
|
restart: "no"
|
||||||
|
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
SETUP_ONLY: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
WORLD: /worlds/world-for-testing.zip
|
||||||
|
volumes:
|
||||||
|
- ./worlds:/worlds:ro
|
||||||
|
- ./data:/data
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
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
|
||||||
Binary file not shown.
17
tests/setuponlytests/vanillatweaks_file/docker-compose.yml
Normal file
17
tests/setuponlytests/vanillatweaks_file/docker-compose.yml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
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
|
||||||
4
tests/setuponlytests/vanillatweaks_file/verify.sh
Normal file
4
tests/setuponlytests/vanillatweaks_file/verify.sh
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
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*"
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"type": "craftingtweaks",
|
||||||
|
"version": "1.18",
|
||||||
|
"packs": {
|
||||||
|
"quality of life": [
|
||||||
|
"dropper to dispenser",
|
||||||
|
"double slabs",
|
||||||
|
"back to blocks"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"result": "ok"
|
||||||
|
}
|
||||||
17
tests/setuponlytests/vanillatweaks_file/vt-datapacks.json
Normal file
17
tests/setuponlytests/vanillatweaks_file/vt-datapacks.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"type": "datapacks",
|
||||||
|
"version": "1.18",
|
||||||
|
"packs": {
|
||||||
|
"survival": [
|
||||||
|
"graves",
|
||||||
|
"multiplayer sleep",
|
||||||
|
"afk display",
|
||||||
|
"armor statues",
|
||||||
|
"unlock all recipes",
|
||||||
|
"fast leaf decay",
|
||||||
|
"coordinates hud"
|
||||||
|
],
|
||||||
|
"items": ["armored elytra"]
|
||||||
|
},
|
||||||
|
"result": "ok"
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"type": "resourcepacks",
|
||||||
|
"version": "1.18",
|
||||||
|
"packs": {
|
||||||
|
"aesthetic": ["CherryPicking", "BlackNetherBricks", "AlternateBlockDestruction"]
|
||||||
|
},
|
||||||
|
"result": "ok"
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
version: "3"
|
||||||
|
|
||||||
|
services:
|
||||||
|
mc:
|
||||||
|
restart: "no"
|
||||||
|
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
|
||||||
|
environment:
|
||||||
|
EULA: "TRUE"
|
||||||
|
SETUP_ONLY: "TRUE"
|
||||||
|
VERSION: ${MINECRAFT_VERSION:-LATEST}
|
||||||
|
VANILLATWEAKS_SHARECODE: MGr52E,tF1zL2,LnEDwT
|
||||||
|
REMOVE_OLD_VANILLATWEAKS: "FALSE"
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user