Compare commits

..
Author SHA1 Message Date
dependabot[bot] 0559797542 build(deps): bump python-dateutil from 3.0.0 to 4.0.0 in /docs
Bumps [python-dateutil](https://github.com/dateutil/dateutil) from 3.0.0 to 4.0.0.
- [Release notes](https://github.com/dateutil/dateutil/releases)
- [Changelog](https://github.com/dateutil/dateutil/blob/master/NEWS)
- [Commits](https://github.com/dateutil/dateutil/compare/3.0.0...4.0.0)

---
updated-dependencies:
- dependency-name: python-dateutil
  dependency-version: 4.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-11-04 12:54:45 +00:00
dependabot[bot] 0e124927f7 build(deps): bump the patches group in /docs with 2 updates (#4376) 2026-11-04 06:52:31 -06:00
spatterlight 3d43aea36b Update MASH documentation links (#4374) 2026-11-03 10:42:25 -06:00
Deniz 926a34b885 Force-include wakes-reforged for Better MC [FORGE] BMC4 (#4373) 2026-11-02 06:56:15 -06:00
spa77k 88cc9d112a Split log4j and JVM flags handling out of start-finalExec (#4372) 2026-11-02 06:54:44 -06:00
renovate[bot] 795d2aee38 Update dependency itzg/mc-image-helper to v1.75.0 (#4371) 2026-10-29 17:14:01 -05:00
renovate[bot] 4b75711f37 Update dependency itzg/mc-image-helper to v1.74.4 (#4370) 2026-10-29 07:09:38 -05:00
dependabot[bot] 5692cf852e build(deps): bump python-dateutil from 2.9.0.post0 to 3.0.0 in /docs (#4369) 2026-10-28 15:40:10 -05:00
dependabot[bot] c5d913ad5e build(deps): bump the patches group in /docs with 7 updates (#4368) 2026-10-28 07:11:42 -05:00
dependabot[bot] 4197034221 build(deps): bump docker/login-action from 4.6.0 to 4.7.0 in the updates group (#4367) 2026-10-28 07:11:18 -05:00
Kim 2e04d8c973 po3 from local zip file with cleanroom loader (#4366) 2026-10-25 18:47:13 -05:00
renovate[bot] e4a381805e Update dependency itzg/mc-image-helper to v1.74.3 (#4365) 2026-10-25 16:56:52 -05:00
renovate[bot] e6610b4964 Update tianon/gosu Docker tag to v1.20 (#4364) 2026-10-25 08:32:26 -05:00
Vitalii Kotenko 7c486b27b7 Add JAVA_AGENTS and JVM_AGENTS to load agents from URLs and paths (#4356) 2026-10-24 14:10:42 -05:00
Geoff Bourne b64207b3c9 Document the setup-only and fulltest development and usage (#4362) 2026-10-24 11:20:56 -05:00
b692386094 Resolve Modrinth projects for NeoForge servers with the NeoForge loader (#4358)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Geoff Bourne <988985+itzg@users.noreply.github.com>
2026-10-24 10:44:43 -05:00
Geoff Bourne 4cd372a7ef java8: bump mcHelperVersion to 1.51.6.-java8 (#4360) 2026-10-24 10:34:39 -05:00
renovate[bot] 151ef70368 Update dependency itzg/mc-image-helper to v1.74.2 (#4359)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-24 10:12:58 -05:00
dependabot[bot] 3cb9486e4a build(deps): bump the patches group in /docs with 4 updates (#4352) 2026-10-23 07:37:12 -05:00
Jaden Grossman bab1e16209 Update the download link for spigot/craftbucket with LATEST version (#4353) 2026-10-21 16:34:23 -05:00
renovate[bot] b040fb02dd Update all non-major dependencies (#4350) 2026-10-21 16:28:04 -05:00
625b10ae45 handleModrinthProjects Cleanroom support (#4351)
Co-authored-by: etzabo <ethan@etzabo.com>
Co-authored-by: Geoff Bourne <988985+itzg@users.noreply.github.com>
2026-10-21 15:11:08 -05:00
Geoff Bourne 057d9c3a74 cf: temporarily removing essential-mod from global exclusions (#4349) 2026-10-19 18:17:31 -05:00
22 changed files with 544 additions and 357 deletions

No files matched your search

+6 -6
View File
@@ -94,25 +94,25 @@ jobs:
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.16.5
# Pin version for pre-Java 17
mcHelperVersion: 1.51.5-java8
mcHelperVersion: 1.51.6-java8
# JAVA 11
- variant: java11
baseImage: adoptopenjdk:11-jre-hotspot
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.16.4
# Pin version for pre-Java 17
mcHelperVersion: 1.51.5-java8
mcHelperVersion: 1.51.6-java8
# JAVA 8: NOTE: Unable to go past 8u312 because of Forge dependencies
- variant: java8
baseImage: eclipse-temurin:8-jre
platforms: linux/amd64,linux/arm/v7,linux/arm64
mcVersion: 1.12.2
mcHelperVersion: 1.51.5-java8
mcHelperVersion: 1.51.6-java8
- variant: java8-jdk
baseImage: eclipse-temurin:8-jdk
platforms: linux/amd64,linux/arm64
mcVersion: 1.12.2
mcHelperVersion: 1.51.5-java8
mcHelperVersion: 1.51.6-java8
env:
# Assume they line up, but when forked change to your Docker Hub username
DOCKER_HUB_ORG: ${{ github.repository_owner }}
@@ -193,14 +193,14 @@ jobs:
tests/test.sh
- name: Login to DockerHub
uses: docker/login-action@v4.6.0
uses: docker/login-action@v4.7.0
if: env.HAS_IMAGE_REPO_ACCESS == 'true'
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v4.6.0
uses: docker/login-action@v4.7.0
if: env.HAS_IMAGE_REPO_ACCESS == 'true'
with:
registry: ghcr.io
+1 -1
View File
@@ -62,7 +62,7 @@ jobs:
# For GLIBC_2.34 support
knockdRepoOrg: Metalcape/knock
# Pin version for Java 8, be sure to also set in build.yml
mcHelperVersion: 1.51.5-java8
mcHelperVersion: 1.51.6-java8
env:
IMAGE_TO_TEST: ${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}
runs-on: ubuntu-22.04
+6 -6
View File
@@ -17,7 +17,7 @@ ARG KNOCKD_REPO_ORG=Metalcape/knock
RUN --mount=target=/build,source=build \
TARGET=${TARGETARCH}${TARGETVARIANT} \
/build/run.sh install-packages
COPY --from=tianon/gosu:1.19 /gosu /usr/local/bin/
COPY --from=tianon/gosu:1.20 /gosu /usr/local/bin/
RUN --mount=target=/build,source=build \
/build/run.sh setup-user
@@ -28,18 +28,18 @@ ARG APPS_REV=1
ARG GITHUB_BASEURL=https://github.com
# renovate: datasource=github-releases packageName=itzg/easy-add
ARG EASY_ADD_VERSION=0.8.18
ARG EASY_ADD_VERSION=0.8.19
ADD ${GITHUB_BASEURL}/itzg/easy-add/releases/download/${EASY_ADD_VERSION}/easy-add_${TARGETOS}_${TARGETARCH}${TARGETVARIANT} /usr/bin/easy-add
RUN chmod +x /usr/bin/easy-add
# renovate: datasource=github-releases packageName=itzg/restify
ARG RESTIFY_VERSION=1.7.20
ARG RESTIFY_VERSION=1.7.21
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${RESTIFY_VERSION} --var app=restify --file {{.app}} \
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/rcon-cli
ARG RCON_CLI_VERSION=1.7.8
ARG RCON_CLI_VERSION=1.7.9
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${RCON_CLI_VERSION} --var app=rcon-cli --file {{.app}} \
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
@@ -51,13 +51,13 @@ RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/mc-server-runner
ARG MC_SERVER_RUNNER_VERSION=1.16.1
ARG MC_SERVER_RUNNER_VERSION=1.16.2
RUN easy-add --var os=${TARGETOS} --var arch=${TARGETARCH}${TARGETVARIANT} \
--var version=${MC_SERVER_RUNNER_VERSION} --var app=mc-server-runner --file {{.app}} \
--from ${GITHUB_BASEURL}/itzg/{{.app}}/releases/download/{{.version}}/{{.app}}_{{.version}}_{{.os}}_{{.arch}}.tar.gz
# renovate: datasource=github-releases packageName=itzg/mc-image-helper versioning=loose
ARG MC_HELPER_VERSION=1.74.0
ARG MC_HELPER_VERSION=1.75.0
ARG MC_HELPER_BASE_URL=${GITHUB_BASEURL}/itzg/mc-image-helper/releases/download/${MC_HELPER_VERSION}
# used for cache busting local copy of mc-image-helper
ARG MC_HELPER_REV=1
+27
View File
@@ -89,6 +89,33 @@ you can use
JVM_DD_OPTS: fml.queryResult=confirm,name=value
```
## Java and JVM Agents
Java agents, such as [authlib-injector](https://github.com/yushijinhun/authlib-injector), can be loaded into the server by setting `JAVA_AGENTS`, and native JVM agents by setting `JVM_AGENTS`. Like [the `MODS` / `PLUGINS` variables](../mods-and-plugins/index.md#modsplugins-list), both are a comma or newline delimited list of
- URL of an agent file
- container path to an agent file
- container path to a directory containing agent jar files for `JAVA_AGENTS`, or `.so` files for `JVM_AGENTS`
The agents are copied into `/data/agents/java` and `/data/agents/jvm`, and each one is passed to the JVM as `-javaagent:<file>` or `-agentpath:<file>`, in file name order.
!!! example
```yaml
environment:
JAVA_AGENTS: |
https://www.example.com/agents/agent.jar
/agents
```
!!! note "Auto-removal"
Entries that are removed from the `JAVA_AGENTS` or `JVM_AGENTS` list will be automatically removed from the agents directory, so they are no longer loaded.
!!! note "Agent options"
An agent that needs options, such as `-javaagent:agent.jar=options`, can still be passed with `JVM_OPTS` instead.
## Enable Remote JMX for Profiling
To enable remote JMX, such as for profiling with VisualVM or JMC, set the environment variable `ENABLE_JMX` to "true", set `JMX_HOST` to the IP/host running the Docker container, and add a port forwarding of TCP port 7091, such as:
+34
View File
@@ -21,6 +21,40 @@ docker compose -f compose-dev.yml run --rm -it [-e key=value] mc-dev
To speed up the development cycle, it is recommended to set `SETUP_ONLY` to `true` as part of the run command above.
## Testing changes
Most changes should be covered by a test under `tests/setuponlytests`. Each test scenario needs its own `compose.yml` or `docker-compose.yml`, which defines the container configuration and inputs for that case. These tests run server setup with `SETUP_ONLY=true`, so they can verify configuration, downloads, and generated files without starting Minecraft.
A scenario can include a `require.sh` to check whether its prerequisites are available in the test environment, such as a required environment variable. It runs before the scenario; a non-zero exit status skips that test. For example, this skips a test when `CF_API_KEY` is not set:
```bash title="require.sh"
[[ -n "${CF_API_KEY:-}" ]] || exit 1
```
Since `require.sh` runs on the host, it sees the variables provided by the CI workflow. These are the ones typically checked:
- `EXTENDED_TESTS`: opt-in flag for slower or network-heavy scenarios; the CI workflows don't set it, so those scenarios only run when it is exported locally
- `CF_API_KEY`: CurseForge API key, which is only available to trusted runs
- `MINECRAFT_VERSION`: the Minecraft version of the CI matrix entry, such as `latest` or `1.12.2`
- `VARIANT`: the image variant of the CI matrix entry, such as `java21-alpine`
- `GH_TOKEN`: GitHub token used for API calls that would otherwise be rate limited
A `require_inside.sh` works the same way, but runs inside a container of the image under test, which is useful when a test depends on the image's contents or Java variant. Checking for JVM runtime files is a good use of it. For example, this skips a test that needs the JDWP agent, which some Java variants such as GraalVM do not include:
```bash title="require_inside.sh"
[[ -f /opt/java/openjdk/lib/libjdwp.so ]] || exit 1
```
Add a `verify.sh` to assert that setup produced the expected files or contents. It runs only after setup succeeds, with the scenario's `data` directory mounted at `/data`; a non-zero exit status fails the test. See the [`mc-image-helper assert` command documentation](https://github.com/itzg/mc-image-helper#assert) for available assertions. For example, use it to check that setup downloaded an expected mod:
```bash title="verify.sh"
mc-image-helper assert fileExists "/data/mods/ExplorersCompass-1.16.5-1.1.2-forge.jar"
```
Run the test suite with `tests/test.sh`. For a focused setup-only check, run `bash tests/setuponlytests/test.sh <scenario>` from the repository root, where `<scenario>` is the directory name under `tests/setuponlytests` (for example, `defaults`). The pull request workflow runs the suite, so prefer setup-only tests for new scenarios.
Tests under `tests/fulltests` start Minecraft and wait for the monitor to confirm that the server is healthy. Keep this suite limited to maintained tests that provide essential full-startup coverage; adding every scenario there would increase pull request validation time.
## Building the image with a new release of a tool
In this exapmle, let's say that [mc-image-helper](https://github.com/itzg/mc-image-helper) has been [released](https://github.com/itzg/mc-image-helper/releases) at 1.56.0, but the corresponding changes in the image [scripts](https://github.com/itzg/docker-minecraft-server/tree/23205471db9814cff9c6602361dbc6cdd6c4230a/scripts) need to be tested against that version while updating [the Dockerfile](https://github.com/itzg/docker-minecraft-server/blob/23205471db9814cff9c6602361dbc6cdd6c4230a/Dockerfile#L58).
+2 -2
View File
@@ -21,8 +21,8 @@
[The MASH Playbook](https://github.com/mother-of-all-self-hosting/mash-playbook) is a premade playbook with the option to deploy a [wide variety of open-source services](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/supported-services.md) to your server(s), including [docker-minecraft-server](https://github.com/mother-of-all-self-hosting/ansible-role-minecraft), making it a good option if you want all the bells and whistles alongside your Minecraft server.
- Check out the [Installation Guide](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/README.md) for the MASH playbook to get started.
- You can then enable [Minecraft](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/minecraft.md) in your vars.yml.
- Enable any supporting services that you might find useful, such as [user authentication](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/authelia.md), [remote backups](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/backup-borg.md), [email relay](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/exim-relay.md), [cron monitoring](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/healthchecks.md), [audio and video conferencing](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/jitsi.md), databases ([MariaDB](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/mariadb.md), [PostgresSQL](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/postgres.md)), [push notifications](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/ntfy.md), [uptime monitoring](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/uptime-kuma.md), [a website](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/wordpress.md), as well as installing any [extra files, folders, applications, services and running commands](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/auxiliary.md) automatically on deployment.
- You can then enable [Minecraft](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/minecraft/README.md) in your vars.yml.
- Enable any supporting services that you might find useful, such as [user authentication](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/authelia/README.md), [remote backups](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/backup_borg/README.md), [email relay](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/exim_relay/README.md), [cron monitoring](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/healthchecks/README.md), [audio and video conferencing](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/jitsi/README.md), databases ([MariaDB](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/mariadb/README.md), [PostgresSQL](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/postgres/README.md)), [push notifications](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/ntfy/README.md), [uptime monitoring](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/uptime_kuma/README.md), [a website](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/wordpress/README.md), as well as installing any [extra files, folders, applications, services and running commands](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/components/auxiliary/README.md) automatically on deployment.
## On CloudFormation (AWS)
+9 -9
View File
@@ -2,24 +2,24 @@ click==8.5.0
colorama==0.4.6
deepmerge==3.0.1
ghp-import==2.1.0
griffe==2.3.2
griffe==2.4.1
Jinja2==3.1.6
Markdown==3.11
Markdown==3.11.2
MarkupSafe==3.0.4
mergedeep==1.3.4
mkdocs==1.6.1
mkdocs-autorefs==1.4.4
mkdocs-autorefs==1.4.5
mkdocs-get-deps==0.2.2
mkdocstrings==1.0.7
mkdocstrings-python==2.0.9
mkdocstrings==1.0.8
mkdocstrings-python==2.0.10
packaging==26.3
pathspec==1.1.1
platformdirs==4.13.0
platformdirs==4.14.2
Pygments==2.21.0
pymdown-extensions==12.2
python-dateutil==2.9.0.post0
pymdown-extensions==12.3
python-dateutil==4.0.0
PyYAML==6.0.3
pyyaml_env_tag==1.1
six==1.17.0
watchdog==6.0.0
zensical==0.0.69
zensical==0.0.74
+12
View File
@@ -147,6 +147,18 @@ alternatively, you can mount: <code>/etc/localtime:/etc/localtime:ro
<td><code></code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>JAVA_AGENTS</code></td>
<td>Comma or newline delimited list of Java agent jar URLs, container paths to jars, or container paths to directories of jars, which are loaded with <code>-javaagent</code></td>
<td><code></code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>JVM_AGENTS</code></td>
<td>Comma or newline delimited list of native JVM agent URLs, container paths to agents, or container paths to directories of <code>.so</code> agents, which are loaded with <code>-agentpath</code></td>
<td><code></code></td>
<td>⬜️</td>
</tr>
<tr>
<td><code>EXTRA_ARGS</code></td>
<td>Arguments that would usually be passed to the jar file (those which are written after the filename)</td>
@@ -0,0 +1,27 @@
services:
minecraft:
image: itzg/minecraft-server:java25
tty: true
stdin_open: true
ports:
- "25565:25565"
environment:
EULA: true
MOD_PLATFORM: AUTO_CURSEFORGE
CF_SLUG: "custom"
CF_MODPACK_ZIP: "/downloads/modpacks/PO3-3.5.1.zip"
APPLY_CLEANROOM: true
# Mod needed for this pack
CF_FORCE_INCLUDE_MODS: hwyla
MEMORY: 8G
OVERRIDE_SERVER_PROPERTIES: true
LEVEL_TYPE: botania-skyblock
volumes:
- ./downloads:/downloads
- ./data:/data
# Uses managed volume by default
#- mc-data:/data
# Managed volume by default
#volumes:
#mc-data:
+4 -1
View File
@@ -28,6 +28,7 @@
"chunk-animator",
"clickable-advancements",
"colorwheel",
"colorwheel-patcher",
"compass-coords",
"config-menus-forge",
"configured",
@@ -59,7 +60,6 @@
"entity-texture-features-fabric",
"entityculling",
"equipment-compare",
"essential-mod",
"euphoria-patches",
"extreme-sound-muffler",
"ezzoom",
@@ -181,6 +181,9 @@
"all-of-fabric-6": {
"forceIncludes": ["revelationary"]
},
"better-mc-forge-bmc4": {
"forceIncludes": ["wakes-reforged"]
},
"beyond-depth": {
"forceIncludes": ["particular-reforged"]
},
+3 -3
View File
@@ -67,7 +67,6 @@ function buildSpigotFromSource {
function downloadSpigot {
local match
local getBukkitBaseUrl="https://getbukkit.org/download/"
local getBukkitSpigotUrl="${getBukkitBaseUrl}spigot"
case "$TYPE" in
*BUKKIT|*bukkit)
match="CraftBukkit"
@@ -82,8 +81,9 @@ function downloadSpigot {
esac
if [[ ${VERSION^^} = LATEST ]]; then
if ! downloadUrl=$(restify "${getBukkitBaseUrl}/${getbukkitFlavor}" --id='downloadr' | jq -r '.[0] | .href '); then
logError "Failed to retrieve latest version from ${getBukkitSpigotUrl} -- site might be down"
if ! downloadUrl=$(curl -fsSL "https://getbukkit.org/api/jars" \
| jq -er --arg f "$getbukkitFlavor" '.[$f][0].downloadUrl | "https://getbukkit.org" + .'); then
logError "Failed to retrieve latest version from ${getBukkitBaseUrl}${getbukkitFlavor} -- site might be down"
exit 1
fi
fi
+30 -326
View File
@@ -65,141 +65,47 @@ if [ -n "$ICON" ]; then
fi
fi
useGeneratedLogs=${GENERATE_LOG4J2_CONFIG:-${ENABLE_ROLLING_LOGS:-false}}
useFallbackJvmFlag=false
SERVER_DIR="$baseDataDir"
if [[ ${FTB_DIR:-} ]]; then
SERVER_DIR="$FTB_DIR"
fi
function addAgents() {
local agents=$1 outDir=$2 glob=$3 option=$4
patchLog4jConfig() {
file=${1?}
url=${2?}
if ! get -o "${SERVER_DIR}/${file}" "$url"; then
logError "Failed to download corrected log4j config, fallback to JVM flag"
useFallbackJvmFlag=true
return 1
mkdir -p "$outDir"
if ! mc-image-helper mcopy \
--glob="$glob" \
--scope=var-list \
--to="$outDir" \
"$agents"; then
logError "Failed to get agents from $agents"
exit 1
fi
# The manifest lists the files that the list resolved to, also in subdirectories, as for destination<source entries
local manifest="$outDir/.var-list-manifest.json"
if [ -f "$manifest" ]; then
while read -r agent; do
JVM_OPTS="${JVM_OPTS} ${option}:${outDir}/${agent}"
done < <(jq -r '.files[]' "$manifest" | sort)
fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
useGeneratedLogs=false
}
# Temporarily disable debugging output
oldState=$(shopt -po xtrace || true)
shopt -u -o xtrace
# Patch Log4j remote code execution vulnerability
# See https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition
if isFamily NATIVE; then
: # Native server, so there is no log4j to patch
elif versionLessThan 1.7; then
: # No patch required here.
elif isFamily VANILLA && versionLessThan 1.12; then
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
elif isFamily VANILLA && versionLessThan 1.17; then
patchLog4jConfig log4j2_112-116.xml https://launcher.mojang.com/v1/objects/02937d122c86ce73319ef9975b58896fc1b491d1/log4j2_112-116.xml
# See https://purpurmc.org/docs/Log4j/
elif isType PURPUR && versionLessThan 1.17; then
patchLog4jConfig purpur_log4j2_1141-1165.xml https://purpurmc.org/docs/xml/purpur_log4j2_1141-1165.xml
elif isType PURPUR && versionLessThan 1.18.1; then
patchLog4jConfig purpur_log4j2_117.xml https://purpurmc.org/docs/xml/purpur_log4j2_117.xml
elif versionLessThan 1.18.1; then
useFallbackJvmFlag=true
fi
eval "$oldState"
if ${useFallbackJvmFlag}; then
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
fi
if isFamily NATIVE; then
: # Native server, so no Log4jPatcher agent
elif versionLessThan 1.7; then
: # No patch required here.
elif versionLessThan 1.18.1; then
if isTrue "${SKIP_LOG4J_PATCHER:-false}"; then
log "Skipping Log4jPatcher, make sure you are not affected"
else
JVM_OPTS="-javaagent:/image/Log4jPatcher.jar ${JVM_OPTS}"
fi
fi
# Set up log4j2 configuration with templating support
LOGFILE="${SERVER_DIR}/log4j2.xml"
if isFamily NATIVE; then
: # Native server, so no log4j configuration
elif ${useGeneratedLogs}; then
# Set up log configuration defaults
: "${LOG_LEVEL:=info}"
: "${ROLLING_LOG_MAX_FILES:=1000}"
# Note: Can't use ${VAR:=default} syntax for values containing } as it breaks parsing
if [ -z "${ROLLING_LOG_FILE_PATTERN}" ]; then
ROLLING_LOG_FILE_PATTERN='logs/%d{yyyy-MM-dd}-%i.log.gz'
fi
# Pattern format defaults (compatible with vanilla Minecraft)
# Note: Can't use ${VAR:=default} syntax because } in the value breaks parsing
if [ -z "${LOG_CONSOLE_FORMAT}" ]; then
LOG_CONSOLE_FORMAT='[%d{HH:mm:ss}] [%t/%level]: %msg%n'
fi
if [ -z "${LOG_TERMINAL_FORMAT}" ]; then
LOG_TERMINAL_FORMAT='[%d{HH:mm:ss} %level]: %msg%n'
fi
if [ -z "${LOG_FILE_FORMAT}" ]; then
LOG_FILE_FORMAT='[%d{HH:mm:ss}] [%t/%level]: %msg%n'
fi
export LOG_LEVEL ROLLING_LOG_FILE_PATTERN ROLLING_LOG_MAX_FILES
export LOG_CONSOLE_FORMAT LOG_TERMINAL_FORMAT LOG_FILE_FORMAT
# Always regenerate if file doesn't exist
if [ ! -e "$LOGFILE" ] || isTrue "${REGENERATE_LOG4J2:-true}"; then
log "Generating log4j2.xml from template in ${LOGFILE}"
# Generate log4j2.xml using heredoc for reliable variable substitution
cat > "$LOGFILE" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="SysOut" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_CONSOLE_FORMAT}" />
</Console>
<Queue name="TerminalConsole">
<PatternLayout pattern="${LOG_TERMINAL_FORMAT}" />
</Queue>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="${ROLLING_LOG_FILE_PATTERN}">
<PatternLayout pattern="${LOG_FILE_FORMAT}" />
<Policies>
<TimeBasedTriggeringPolicy />
<OnStartupTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy max="${ROLLING_LOG_MAX_FILES}"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="${LOG_LEVEL}">
<filters>
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
</filters>
<AppenderRef ref="SysOut"/>
<AppenderRef ref="File"/>
<AppenderRef ref="TerminalConsole"/>
</Root>
</Loggers>
</Configuration>
EOF
else
log "log4j2.xml already exists and is up to date, skipping generation"
fi
# Apply the log4j2 configuration
JVM_OPTS="-Dlog4j.configurationFile=log4j2.xml ${JVM_OPTS}"
: # Native server, so no JVM to load agents into
else
rm -f "${LOGFILE}"
if [[ -v JVM_AGENTS ]]; then
addAgents "$JVM_AGENTS" /data/agents/jvm '*.so' -agentpath
fi
if [[ -v JAVA_AGENTS ]]; then
addAgents "$JAVA_AGENTS" /data/agents/java '*.jar' -javaagent
fi
fi
# shellcheck source=start-finalExec-log4j
. "$(dirname "$0")/start-finalExec-log4j"
# Optional disable console
if ! isFamily NATIVE && versionLessThan 1.14 && [[ ${CONSOLE,,} = false ]]; then
EXTRA_ARGS+=" --noconsole"
@@ -232,210 +138,8 @@ if isTrue "${ENABLE_JMX}"; then
log "JMX is enabled. Make sure you have port forwarding for ${JMX_PORT}"
fi
: "${USE_AIKAR_FLAGS:=false}"
: "${USE_MEOWICE_FLAGS:=false}"
: "${USE_MEOWICE_GRAALVM_FLAGS:=false}"
if isTrue "${USE_MEOWICE_FLAGS}" || isTrue "${USE_MEOWICE_GRAALVM_FLAGS}"; then
java_major_version=$(mc-image-helper java-release)
fi
if isTrue "${USE_MEOWICE_FLAGS}"; then
if [[ $java_major_version -gt 16 ]]; then
log "Java version $java_major_version using MeowIce's flags for Java 17+"
else
log "Your Java version is $java_major_version, MeowIce's flags are for Java 17+ falling back to Aikar's"
USE_MEOWICE_FLAGS=FALSE
USE_AIKAR_FLAGS=TRUE
fi
fi
if isTrue "${USE_AIKAR_FLAGS}" || isTrue "${USE_MEOWICE_FLAGS}"; then
# From https://mcflags.emc.gs/
if isTrue "${USE_MEOWICE_FLAGS}"; then
log "Using MeowIce's flags"
G1NewSizePercent=28
G1MaxNewSizePercent=50
G1HeapRegionSize=16M
G1ReservePercent=15
InitiatingHeapOccupancyPercent=20
G1MixedGCCountTarget=3
G1RSetUpdatingPauseTimePercent=0
elif [[ $MAX_MEMORY ]] && (( $(normalizeMemSize "${MAX_MEMORY}") >= $(normalizeMemSize 12g) )); then
log "Using Aikar's >12GB flags"
G1NewSizePercent=40
G1MaxNewSizePercent=50
G1HeapRegionSize=16M
G1ReservePercent=15
InitiatingHeapOccupancyPercent=20
G1MixedGCCountTarget=4
G1RSetUpdatingPauseTimePercent=5
else
log "Using Aikar's flags"
G1NewSizePercent=30
G1MaxNewSizePercent=40
G1HeapRegionSize=8M
G1ReservePercent=20
InitiatingHeapOccupancyPercent=15
G1MixedGCCountTarget=4
G1RSetUpdatingPauseTimePercent=5
fi
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseG1GC
-XX:+ParallelRefProcEnabled
-XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions
-XX:+DisableExplicitGC
-XX:+AlwaysPreTouch
-XX:G1NewSizePercent=${G1NewSizePercent}
-XX:G1MaxNewSizePercent=${G1MaxNewSizePercent}
-XX:G1HeapRegionSize=${G1HeapRegionSize}
-XX:G1ReservePercent=${G1ReservePercent}
-XX:G1HeapWastePercent=5
-XX:G1MixedGCCountTarget=${G1MixedGCCountTarget}
-XX:InitiatingHeapOccupancyPercent=${InitiatingHeapOccupancyPercent}
-XX:G1MixedGCLiveThresholdPercent=90
-XX:G1RSetUpdatingPauseTimePercent=${G1RSetUpdatingPauseTimePercent}
-XX:SurvivorRatio=32
-XX:+PerfDisableSharedMem
-XX:MaxTenuringThreshold=1
"
if isTrue "${USE_AIKAR_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-Dusing.aikars.flags=https://mcflags.emc.gs
-Daikars.new.flags=true
"
fi
fi
if isTrue "${USE_MEOWICE_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UnlockDiagnosticVMOptions
-XX:+UnlockExperimentalVMOptions
-XX:G1SATBBufferEnqueueingThresholdPercent=30
-XX:G1ConcMarkStepDurationMillis=5
-XX:+UseNUMA
-XX:-DontCompileHugeMethods
-XX:MaxNodeLimit=240000
-XX:NodeLimitFudgeFactor=8000
-XX:ReservedCodeCacheSize=400M
-XX:NonNMethodCodeHeapSize=12M
-XX:ProfiledCodeHeapSize=194M
-XX:NonProfiledCodeHeapSize=194M
-XX:NmethodSweepActivity=1
-XX:+UseFastUnorderedTimeStamps
-XX:+UseCriticalJavaThreadPriority
-XX:AllocatePrefetchStyle=3
-XX:+AlwaysActAsServerClassMachine
-XX:+UseTransparentHugePages
-XX:LargePageSizeInBytes=2M
-XX:+UseLargePages
-XX:+EagerJVMCI
-XX:+UseStringDeduplication
-XX:+UseAES
-XX:+UseAESIntrinsics
-XX:+UseFMA
-XX:+UseLoopPredicate
-XX:+RangeCheckElimination
-XX:+OptimizeStringConcat
-XX:+UseCompressedOops
-XX:+UseThreadPriorities
-XX:+OmitStackTraceInFastThrow
-XX:+RewriteBytecodes
-XX:+RewriteFrequentPairs
-XX:+UseFPUForSpilling
-XX:+UseVectorCmov
-XX:+UseXMMForArrayCopy
-XX:+EliminateLocks
-XX:+DoEscapeAnalysis
-XX:+AlignVector
-XX:+OptimizeFill
-XX:+EnableVectorSupport
-XX:+UseCharacterCompareIntrinsics
-XX:+UseCopySignIntrinsic
-XX:+UseVectorStubs
"
if [[ $(arch) == "x86_64" ]]; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseFastStosb
-XX:+UseNewLongLShift
-XX:+UseXmmI2D
-XX:+UseXmmI2F
-XX:+UseXmmLoadAndClearUpper
-XX:+UseXmmRegToRegMoveAll
-XX:UseAVX=2
-XX:UseSSE=4
"
else
log "cpu not x86_64, disabling architecture specific flags"
fi
if [[ $java_major_version -gt 23 ]]; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseCompactObjectHeaders
"
fi
fi
if isTrue "${USE_MEOWICE_GRAALVM_FLAGS}"; then
if [[ $java_major_version -gt 23 ]]; then
log "Java 24 or higher detected, using modified GraalVM flags"
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseFastJNIAccessors
-XX:+UseInlineCaches
-XX:+SegmentedCodeCache
-Djdk.nio.maxCachedBufferSize=262144
-Djdk.graal.UsePriorityInlining=true
-Djdk.graal.Vectorization=true
-Djdk.graal.OptDuplication=true
-Djdk.graal.DetectInvertedLoopsAsCounted=true
-Djdk.graal.LoopInversion=true
-Djdk.graal.VectorizeHashes=true
-Djdk.graal.EnterprisePartialUnroll=true
-Djdk.graal.VectorizeSIMD=true
-Djdk.graal.StripMineNonCountedLoops=true
-Djdk.graal.SpeculativeGuardMovement=true
-Djdk.graal.TuneInlinerExploration=1
-Djdk.graal.LoopRotation=true
-Djdk.graal.CompilerConfiguration=enterprise
"
else
log "Using MeowIce's flags for Graalvm"
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseFastJNIAccessors
-XX:+UseInlineCaches
-XX:+SegmentedCodeCache
-Djdk.nio.maxCachedBufferSize=262144
-Dgraal.UsePriorityInlining=true
-Dgraal.Vectorization=true
-Dgraal.OptDuplication=true
-Dgraal.DetectInvertedLoopsAsCounted=true
-Dgraal.LoopInversion=true
-Dgraal.VectorizeHashes=true
-Dgraal.EnterprisePartialUnroll=true
-Dgraal.VectorizeSIMD=true
-Dgraal.StripMineNonCountedLoops=true
-Dgraal.SpeculativeGuardMovement=true
-Dgraal.TuneInlinerExploration=1
-Dgraal.LoopRotation=true
-Dgraal.OptWriteMotion=true
-Dgraal.CompilerConfiguration=enterprise
"
fi
fi
if isTrue "${USE_FLARE_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UnlockDiagnosticVMOptions
-XX:+DebugNonSafepoints
"
fi
if isTrue "${USE_SIMD_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
--add-modules=jdk.incubator.vector
"
fi
# shellcheck source=start-finalExec-jvmFlags
. "$(dirname "$0")/start-finalExec-jvmFlags"
# Handle GTNH args
if isType "GTNH"; then
+206
View File
@@ -0,0 +1,206 @@
#!/bin/bash
: "${USE_AIKAR_FLAGS:=false}"
: "${USE_MEOWICE_FLAGS:=false}"
: "${USE_MEOWICE_GRAALVM_FLAGS:=false}"
if isTrue "${USE_MEOWICE_FLAGS}" || isTrue "${USE_MEOWICE_GRAALVM_FLAGS}"; then
java_major_version=$(mc-image-helper java-release)
fi
if isTrue "${USE_MEOWICE_FLAGS}"; then
if [[ $java_major_version -gt 16 ]]; then
log "Java version $java_major_version using MeowIce's flags for Java 17+"
else
log "Your Java version is $java_major_version, MeowIce's flags are for Java 17+ falling back to Aikar's"
USE_MEOWICE_FLAGS=FALSE
USE_AIKAR_FLAGS=TRUE
fi
fi
if isTrue "${USE_AIKAR_FLAGS}" || isTrue "${USE_MEOWICE_FLAGS}"; then
# From https://mcflags.emc.gs/
if isTrue "${USE_MEOWICE_FLAGS}"; then
log "Using MeowIce's flags"
G1NewSizePercent=28
G1MaxNewSizePercent=50
G1HeapRegionSize=16M
G1ReservePercent=15
InitiatingHeapOccupancyPercent=20
G1MixedGCCountTarget=3
G1RSetUpdatingPauseTimePercent=0
elif [[ $MAX_MEMORY ]] && (( $(normalizeMemSize "${MAX_MEMORY}") >= $(normalizeMemSize 12g) )); then
log "Using Aikar's >12GB flags"
G1NewSizePercent=40
G1MaxNewSizePercent=50
G1HeapRegionSize=16M
G1ReservePercent=15
InitiatingHeapOccupancyPercent=20
G1MixedGCCountTarget=4
G1RSetUpdatingPauseTimePercent=5
else
log "Using Aikar's flags"
G1NewSizePercent=30
G1MaxNewSizePercent=40
G1HeapRegionSize=8M
G1ReservePercent=20
InitiatingHeapOccupancyPercent=15
G1MixedGCCountTarget=4
G1RSetUpdatingPauseTimePercent=5
fi
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseG1GC
-XX:+ParallelRefProcEnabled
-XX:MaxGCPauseMillis=200
-XX:+UnlockExperimentalVMOptions
-XX:+DisableExplicitGC
-XX:+AlwaysPreTouch
-XX:G1NewSizePercent=${G1NewSizePercent}
-XX:G1MaxNewSizePercent=${G1MaxNewSizePercent}
-XX:G1HeapRegionSize=${G1HeapRegionSize}
-XX:G1ReservePercent=${G1ReservePercent}
-XX:G1HeapWastePercent=5
-XX:G1MixedGCCountTarget=${G1MixedGCCountTarget}
-XX:InitiatingHeapOccupancyPercent=${InitiatingHeapOccupancyPercent}
-XX:G1MixedGCLiveThresholdPercent=90
-XX:G1RSetUpdatingPauseTimePercent=${G1RSetUpdatingPauseTimePercent}
-XX:SurvivorRatio=32
-XX:+PerfDisableSharedMem
-XX:MaxTenuringThreshold=1
"
if isTrue "${USE_AIKAR_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-Dusing.aikars.flags=https://mcflags.emc.gs
-Daikars.new.flags=true
"
fi
fi
if isTrue "${USE_MEOWICE_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UnlockDiagnosticVMOptions
-XX:+UnlockExperimentalVMOptions
-XX:G1SATBBufferEnqueueingThresholdPercent=30
-XX:G1ConcMarkStepDurationMillis=5
-XX:+UseNUMA
-XX:-DontCompileHugeMethods
-XX:MaxNodeLimit=240000
-XX:NodeLimitFudgeFactor=8000
-XX:ReservedCodeCacheSize=400M
-XX:NonNMethodCodeHeapSize=12M
-XX:ProfiledCodeHeapSize=194M
-XX:NonProfiledCodeHeapSize=194M
-XX:NmethodSweepActivity=1
-XX:+UseFastUnorderedTimeStamps
-XX:+UseCriticalJavaThreadPriority
-XX:AllocatePrefetchStyle=3
-XX:+AlwaysActAsServerClassMachine
-XX:+UseTransparentHugePages
-XX:LargePageSizeInBytes=2M
-XX:+UseLargePages
-XX:+EagerJVMCI
-XX:+UseStringDeduplication
-XX:+UseAES
-XX:+UseAESIntrinsics
-XX:+UseFMA
-XX:+UseLoopPredicate
-XX:+RangeCheckElimination
-XX:+OptimizeStringConcat
-XX:+UseCompressedOops
-XX:+UseThreadPriorities
-XX:+OmitStackTraceInFastThrow
-XX:+RewriteBytecodes
-XX:+RewriteFrequentPairs
-XX:+UseFPUForSpilling
-XX:+UseVectorCmov
-XX:+UseXMMForArrayCopy
-XX:+EliminateLocks
-XX:+DoEscapeAnalysis
-XX:+AlignVector
-XX:+OptimizeFill
-XX:+EnableVectorSupport
-XX:+UseCharacterCompareIntrinsics
-XX:+UseCopySignIntrinsic
-XX:+UseVectorStubs
"
if [[ $(arch) == "x86_64" ]]; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseFastStosb
-XX:+UseNewLongLShift
-XX:+UseXmmI2D
-XX:+UseXmmI2F
-XX:+UseXmmLoadAndClearUpper
-XX:+UseXmmRegToRegMoveAll
-XX:UseAVX=2
-XX:UseSSE=4
"
else
log "cpu not x86_64, disabling architecture specific flags"
fi
if [[ $java_major_version -gt 23 ]]; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseCompactObjectHeaders
"
fi
fi
if isTrue "${USE_MEOWICE_GRAALVM_FLAGS}"; then
if [[ $java_major_version -gt 23 ]]; then
log "Java 24 or higher detected, using modified GraalVM flags"
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseFastJNIAccessors
-XX:+UseInlineCaches
-XX:+SegmentedCodeCache
-Djdk.nio.maxCachedBufferSize=262144
-Djdk.graal.UsePriorityInlining=true
-Djdk.graal.Vectorization=true
-Djdk.graal.OptDuplication=true
-Djdk.graal.DetectInvertedLoopsAsCounted=true
-Djdk.graal.LoopInversion=true
-Djdk.graal.VectorizeHashes=true
-Djdk.graal.EnterprisePartialUnroll=true
-Djdk.graal.VectorizeSIMD=true
-Djdk.graal.StripMineNonCountedLoops=true
-Djdk.graal.SpeculativeGuardMovement=true
-Djdk.graal.TuneInlinerExploration=1
-Djdk.graal.LoopRotation=true
-Djdk.graal.CompilerConfiguration=enterprise
"
else
log "Using MeowIce's flags for Graalvm"
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UseFastJNIAccessors
-XX:+UseInlineCaches
-XX:+SegmentedCodeCache
-Djdk.nio.maxCachedBufferSize=262144
-Dgraal.UsePriorityInlining=true
-Dgraal.Vectorization=true
-Dgraal.OptDuplication=true
-Dgraal.DetectInvertedLoopsAsCounted=true
-Dgraal.LoopInversion=true
-Dgraal.VectorizeHashes=true
-Dgraal.EnterprisePartialUnroll=true
-Dgraal.VectorizeSIMD=true
-Dgraal.StripMineNonCountedLoops=true
-Dgraal.SpeculativeGuardMovement=true
-Dgraal.TuneInlinerExploration=1
-Dgraal.LoopRotation=true
-Dgraal.OptWriteMotion=true
-Dgraal.CompilerConfiguration=enterprise
"
fi
fi
if isTrue "${USE_FLARE_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
-XX:+UnlockDiagnosticVMOptions
-XX:+DebugNonSafepoints
"
fi
if isTrue "${USE_SIMD_FLAGS}"; then
JVM_XX_OPTS="${JVM_XX_OPTS}
--add-modules=jdk.incubator.vector
"
fi
+130
View File
@@ -0,0 +1,130 @@
#!/bin/bash
useGeneratedLogs=${GENERATE_LOG4J2_CONFIG:-${ENABLE_ROLLING_LOGS:-false}}
useFallbackJvmFlag=false
patchLog4jConfig() {
file=${1?}
url=${2?}
if ! get -o "${SERVER_DIR}/${file}" "$url"; then
logError "Failed to download corrected log4j config, fallback to JVM flag"
useFallbackJvmFlag=true
return 1
fi
JVM_OPTS="-Dlog4j.configurationFile=${file} ${JVM_OPTS}"
useGeneratedLogs=false
}
# Temporarily disable debugging output
oldState=$(shopt -po xtrace || true)
shopt -u -o xtrace
# Patch Log4j remote code execution vulnerability
# See https://www.minecraft.net/en-us/article/important-message--security-vulnerability-java-edition
if isFamily NATIVE; then
: # Native server, so there is no log4j to patch
elif versionLessThan 1.7; then
: # No patch required here.
elif isFamily VANILLA && versionLessThan 1.12; then
patchLog4jConfig log4j2_17-111.xml https://launcher.mojang.com/v1/objects/dd2b723346a8dcd48e7f4d245f6bf09e98db9696/log4j2_17-111.xml
elif isFamily VANILLA && versionLessThan 1.17; then
patchLog4jConfig log4j2_112-116.xml https://launcher.mojang.com/v1/objects/02937d122c86ce73319ef9975b58896fc1b491d1/log4j2_112-116.xml
# See https://purpurmc.org/docs/Log4j/
elif isType PURPUR && versionLessThan 1.17; then
patchLog4jConfig purpur_log4j2_1141-1165.xml https://purpurmc.org/docs/xml/purpur_log4j2_1141-1165.xml
elif isType PURPUR && versionLessThan 1.18.1; then
patchLog4jConfig purpur_log4j2_117.xml https://purpurmc.org/docs/xml/purpur_log4j2_117.xml
elif versionLessThan 1.18.1; then
useFallbackJvmFlag=true
fi
eval "$oldState"
if ${useFallbackJvmFlag}; then
JVM_OPTS="-Dlog4j2.formatMsgNoLookups=true ${JVM_OPTS}"
fi
if isFamily NATIVE; then
: # Native server, so no Log4jPatcher agent
elif versionLessThan 1.7; then
: # No patch required here.
elif versionLessThan 1.18.1; then
if isTrue "${SKIP_LOG4J_PATCHER:-false}"; then
log "Skipping Log4jPatcher, make sure you are not affected"
else
JVM_OPTS="-javaagent:/image/Log4jPatcher.jar ${JVM_OPTS}"
fi
fi
# Set up log4j2 configuration with templating support
LOGFILE="${SERVER_DIR}/log4j2.xml"
if isFamily NATIVE; then
: # Native server, so no log4j configuration
elif ${useGeneratedLogs}; then
# Set up log configuration defaults
: "${LOG_LEVEL:=info}"
: "${ROLLING_LOG_MAX_FILES:=1000}"
# Note: Can't use ${VAR:=default} syntax for values containing } as it breaks parsing
if [ -z "${ROLLING_LOG_FILE_PATTERN}" ]; then
ROLLING_LOG_FILE_PATTERN='logs/%d{yyyy-MM-dd}-%i.log.gz'
fi
# Pattern format defaults (compatible with vanilla Minecraft)
# Note: Can't use ${VAR:=default} syntax because } in the value breaks parsing
if [ -z "${LOG_CONSOLE_FORMAT}" ]; then
LOG_CONSOLE_FORMAT='[%d{HH:mm:ss}] [%t/%level]: %msg%n'
fi
if [ -z "${LOG_TERMINAL_FORMAT}" ]; then
LOG_TERMINAL_FORMAT='[%d{HH:mm:ss} %level]: %msg%n'
fi
if [ -z "${LOG_FILE_FORMAT}" ]; then
LOG_FILE_FORMAT='[%d{HH:mm:ss}] [%t/%level]: %msg%n'
fi
export LOG_LEVEL ROLLING_LOG_FILE_PATTERN ROLLING_LOG_MAX_FILES
export LOG_CONSOLE_FORMAT LOG_TERMINAL_FORMAT LOG_FILE_FORMAT
# Always regenerate if file doesn't exist
if [ ! -e "$LOGFILE" ] || isTrue "${REGENERATE_LOG4J2:-true}"; then
log "Generating log4j2.xml from template in ${LOGFILE}"
# Generate log4j2.xml using heredoc for reliable variable substitution
cat > "$LOGFILE" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="SysOut" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_CONSOLE_FORMAT}" />
</Console>
<Queue name="TerminalConsole">
<PatternLayout pattern="${LOG_TERMINAL_FORMAT}" />
</Queue>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="${ROLLING_LOG_FILE_PATTERN}">
<PatternLayout pattern="${LOG_FILE_FORMAT}" />
<Policies>
<TimeBasedTriggeringPolicy />
<OnStartupTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy max="${ROLLING_LOG_MAX_FILES}"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="${LOG_LEVEL}">
<filters>
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
</filters>
<AppenderRef ref="SysOut"/>
<AppenderRef ref="File"/>
<AppenderRef ref="TerminalConsole"/>
</Root>
</Loggers>
</Configuration>
EOF
else
log "log4j2.xml already exists and is up to date, skipping generation"
fi
# Apply the log4j2 configuration
JVM_OPTS="-Dlog4j.configurationFile=log4j2.xml ${JVM_OPTS}"
else
rm -f "${LOGFILE}"
fi
+4
View File
@@ -313,6 +313,10 @@ function handleModrinthProjects() {
loader=${HYBRIDTYPE}
elif isFamily VANILLA; then
loader=datapack
elif isType NEOFORGE; then
loader=neoforge
elif isFamily FORGE; then
loader=forge
else
loader="${TYPE,,}"
fi
+2 -2
View File
@@ -28,8 +28,8 @@ fullMinecraftUpTest(){
}
# go through each folder in fulltests and run fullbuilds
files=$(ls */docker-compose.yml)
for file in $files; do
readarray -t files < <(find . -maxdepth 2 -mindepth 2 \( -name compose.yml -o -name docker-compose.yml \) | sort)
for file in "${files[@]}"; do
echo "Starting Tests on $(dirname "$file")"
if ! fullMinecraftUpTest "$file"; then
@@ -0,0 +1,14 @@
services:
mc:
restart: "no"
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "TRUE"
SETUP_ONLY: "TRUE"
VERSION: ${MINECRAFT_VERSION:-LATEST}
# The image's own directory holds a Java agent among other files
JAVA_AGENTS: /image
# The JDK's debugger is a native JVM agent
JVM_AGENTS: /opt/java/openjdk/lib/libjdwp.so
volumes:
- ./data:/data
+1
View File
@@ -0,0 +1 @@
[[ -f /opt/java/openjdk/lib/libjdwp.so ]] || exit 1
+3
View File
@@ -0,0 +1,3 @@
mc-image-helper assert fileExists agents/java/Log4jPatcher.jar
mc-image-helper assert fileNotExists agents/java/server.properties
mc-image-helper assert fileExists agents/jvm/libjdwp.so
@@ -0,0 +1,11 @@
services:
mc:
image: ${IMAGE_TO_TEST:-itzg/minecraft-server}
environment:
EULA: "true"
SETUP_ONLY: "true"
TYPE: NEOFORGE
VERSION: 1.21.1
MODRINTH_PROJECTS: storagedrawers
volumes:
- ./data:/data
@@ -0,0 +1 @@
mc-image-helper assert fileExists "mods/StorageDrawers-neoforge-*.jar"
+11 -1
View File
@@ -41,6 +41,16 @@ setupOnlyMinecraftTest(){
fi
fi
if [ -f require_inside.sh ]; then
# require_inside.sh scripts run inside the image under test to check for things like a particular
# JVM file or feature. A non-zero exit status indicates the test should be skipped.
if ! docker run --rm --entrypoint bash -v "${PWD}/require_inside.sh":/require_inside:ro "${IMAGE_TO_TEST}" -e /require_inside; then
echo "${folder} SKIP (require_inside)"
cd ..
return 0
fi
fi
# false positive since it's used in delta calculations below
# shellcheck disable=SC2034
start=$(date +%s)
@@ -71,7 +81,7 @@ image=""
# Go through each folder in setuponly and test setups
if (( $# == 0 )); then
readarray -t folders < <(find . -maxdepth 2 -mindepth 2 -name docker-compose.yml -exec dirname "{}" \;)
readarray -t folders < <(find . -maxdepth 2 -mindepth 2 \( -name compose.yml -o -name docker-compose.yml \) -exec dirname "{}" \; | sort -u)
foldersList=("${folders[@]}")
image=" using $IMAGE_TO_TEST"
fi