minecraft-server: an overridable image tag and a Java-line guard (5.0.0+up2026.8.2.java25)
Only the newest Java line is maintained from now on. Publishing the chart once per line out of one directory is what made the lines drift apart (#158): a change reached whichever line happened to lie in the directory. java8 and java17 stay published as frozen artifacts at 4.0.0, java21 at 4.1.0, and none of them gets another chart change. Running an older JVM is now a decision at rollout time instead of a chart version: image.tagOverride replaces the tag that otherwise comes from appVersion. It is not called image.tag because it decouples the running image from the chart version, and it is deliberately outside Renovate's reach - renovate.json5 keeps tracking appVersion only. The pairing of tag and minecraft.version is now checked at render time and fails with both values named, the line each one belongs to, and where the tag came from. Until now nothing checked it: a mismatch installed silently and only the container failed afterwards. The boundaries are Mojang's, swept over all 102 releases of the piston-meta manifest (javaVersion.majorVersion): up to 1.16.5 Java 8, 1.17-1.17.1 Java 16, 1.18-1.20.4 Java 17, 1.20.5-1.21.11 Java 21, 26.1 and later Java 25. The 1.17 line was the one gap the chart's own notes did not cover. Two cases pass unchecked on purpose, documented in values.yaml and NOTES.txt: a tag without a recognizable java<N> part, and a minecraft.version that is not a plain numeric x[.y[.z]]. A guard that rejects what it does not understand gets worked around instead of respected. Major, because an installation that already runs a mismatched pair stops rendering. It does not run today either - it now fails earlier and visibly.
This commit is contained in:
7 files changed
+262
-31
No files matched your search
@@ -9,7 +9,9 @@
|
||||
{{- if and (kindIs "float64" $startup.periodSeconds) (kindIs "float64" $startup.failureThreshold) -}}
|
||||
{{- $budget = printf "%.0f seconds" (mulf $startup.periodSeconds $startup.failureThreshold) -}}
|
||||
{{- end -}}
|
||||
{{- $line := regexFind "java[0-9]+" (printf "%v" .Chart.AppVersion) -}}
|
||||
{{- $tag := include "minecraft-server.imageTag" . -}}
|
||||
{{- $line := include "minecraft-server.javaLine" . -}}
|
||||
{{- $tagOverridden := ne (include "minecraft-server.imageTagSource" .) ".Chart.AppVersion" -}}
|
||||
{{- $svc := printf "%s-%s-service" .Release.Name .Chart.Name -}}
|
||||
{{- $sfs := printf "%s-%s-sfs" .Release.Name .Chart.Name -}}
|
||||
{{- $pod := printf "%s-%s-sfs-0" .Release.Name .Chart.Name -}}
|
||||
@@ -26,7 +28,7 @@
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- $memPinned := not (kindIs "invalid" (index $givenReq "memory")) -}}
|
||||
minecraft-server {{ .Chart.AppVersion }} — release {{ .Release.Name }} in namespace {{ .Release.Namespace }}.
|
||||
minecraft-server {{ $tag }} — release {{ .Release.Name }} in namespace {{ .Release.Namespace }}.
|
||||
|
||||
ACCESS — A MINECRAFT SERVER, NOT A WEB SERVICE
|
||||
This release has no Ingress, no certificate and no URL. Clients speak the
|
||||
@@ -76,25 +78,53 @@ ACCESS — A MINECRAFT SERVER, NOT A WEB SERVICE
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} port-forward svc/{{ $svc }} {{ .Values.server.service.port }}:{{ .Values.server.service.port }}
|
||||
|
||||
THIS CHART IS PUBLISHED ONCE PER JAVA LINE — THIS IS {{ $line | default "an unrecognized line" | upper }}
|
||||
The JVM is fixed by the image tag, which comes from the chart's appVersion
|
||||
({{ .Chart.AppVersion }}), not from a value. This build runs
|
||||
minecraft.version {{ .Values.minecraft.version }}.
|
||||
THE JAVA LINE OF THIS RELEASE IS {{ $line | default "NOT RECOGNIZABLE FROM ITS TAG" | upper }}
|
||||
The JVM is fixed by the image tag, not by a value of the game. This release
|
||||
runs
|
||||
|
||||
Java 8 runs Minecraft up to 1.16.5, 1.18-1.20.4 need Java 17, 1.20.5-1.21.11
|
||||
need Java 21 and 26.1 and later need Java 25 (read off Mojang's version
|
||||
manifest, javaVersion.majorVersion per release). Nothing in this chart checks
|
||||
that minecraft.version fits the line: a mismatch renders and installs without
|
||||
a word, and only the container fails afterwards — CrashLoopBackOff once the
|
||||
startup budget{{ if $budget }} ({{ $budget }}){{ end }} is spent, with the reason in the log and
|
||||
itzg/minecraft-server:{{ $tag }}
|
||||
|
||||
with minecraft.version {{ .Values.minecraft.version }}.
|
||||
{{- if $tagOverridden }}
|
||||
|
||||
That tag comes from image.tagOverride, NOT from the chart's appVersion
|
||||
({{ .Chart.AppVersion }}). So the chart version no longer says what this release runs:
|
||||
"helm list" reports {{ .Chart.Version }} while the pod is on the tag
|
||||
above. That is the price of the override, and the reason it is not called
|
||||
image.tag.
|
||||
{{- else }}
|
||||
|
||||
That tag comes from the chart's appVersion; image.tagOverride is empty, so
|
||||
the chart version tells the whole truth about the image.
|
||||
{{- end }}
|
||||
|
||||
Since chart 5.0.0 THAT PAIRING IS CHECKED: if the line of the tag above does
|
||||
not fit minecraft.version, the render fails and names both values. Two cases
|
||||
are let through on purpose — a tag without a recognizable "java<N>" part, and
|
||||
a minecraft.version that is not a plain numeric x[.y[.z]] (a snapshot, a
|
||||
pre-release, "LATEST"). In those two the old failure mode still applies: the
|
||||
release installs, and only the container fails afterwards — CrashLoopBackOff
|
||||
once the startup budget{{ if $budget }} ({{ $budget }}){{ end }} is spent, with the reason in the log and
|
||||
nowhere else:
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} logs {{ $pod }}
|
||||
|
||||
So moving the server across a line boundary is a change of CHART VERSION, not
|
||||
a change of minecraft.version: pick the published chart of the target line and
|
||||
set minecraft.version to match it. Changing only minecraft.version leaves the
|
||||
old JVM in place.
|
||||
The boundaries are Mojang's (javaVersion.majorVersion in the piston-meta
|
||||
version manifest, per release):
|
||||
|
||||
up to 1.16.5 Java 8
|
||||
1.17 - 1.17.1 Java 16
|
||||
1.18 - 1.20.4 Java 17
|
||||
1.20.5 - 1.21.11 Java 21
|
||||
26.1 and later Java 25
|
||||
|
||||
ONLY THE NEWEST LINE IS MAINTAINED. This chart directory carries one line and
|
||||
gets chart changes only for that one; java8 and java17 stay frozen at chart
|
||||
4.0.0, java21 at 4.1.0. So moving the server across a line boundary is no
|
||||
longer a change of chart version: set image.tagOverride to a tag of the target
|
||||
line AND minecraft.version to a release of it, in the same upgrade. Changing
|
||||
only one of the two now fails the render instead of leaving a broken pod
|
||||
behind.
|
||||
{{- if eq $replicas "0" }}
|
||||
|
||||
SCALED TO ZERO
|
||||
|
||||
@@ -183,6 +183,133 @@ last one silently won. Fail loudly instead.
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
The tag of the itzg/minecraft-server image this release actually runs.
|
||||
|
||||
Default: .Chart.AppVersion, exactly as before chart 5.0.0. image.tagOverride
|
||||
replaces it when set - that is the one way to run a Java line other than the
|
||||
one this chart version publishes, now that only the newest line is maintained
|
||||
(see Chart.yaml). The value is deliberately NOT called image.tag: it is an
|
||||
emergency exit, not a knob to turn in passing, and it is not managed by
|
||||
Renovate (renovate.json5 tracks appVersion only).
|
||||
*/}}
|
||||
{{- define "minecraft-server.imageTag" -}}
|
||||
{{- $override := "" -}}
|
||||
{{- if kindIs "map" .Values.image -}}
|
||||
{{- if not (kindIs "invalid" .Values.image.tagOverride) -}}
|
||||
{{- $override = printf "%v" .Values.image.tagOverride | trim -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if $override -}}{{ $override }}{{- else -}}{{ .Chart.AppVersion }}{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Where the effective tag came from - used in the guard's message so the reader
|
||||
knows which of the two values to change.
|
||||
*/}}
|
||||
{{- define "minecraft-server.imageTagSource" -}}
|
||||
{{- $override := "" -}}
|
||||
{{- if kindIs "map" .Values.image -}}
|
||||
{{- if not (kindIs "invalid" .Values.image.tagOverride) -}}
|
||||
{{- $override = printf "%v" .Values.image.tagOverride | trim -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if $override -}}image.tagOverride{{- else -}}.Chart.AppVersion{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
The Java line the effective image tag carries ("java25", "java17", ...), or the
|
||||
empty string when the tag does not name one.
|
||||
|
||||
regexFind rather than a suffix comparison, so flavoured tags keep working:
|
||||
"2026.8.2-java25", "java21-alpine" and "latest-java17-jdk" all resolve.
|
||||
*/}}
|
||||
{{- define "minecraft-server.javaLine" -}}
|
||||
{{- regexFind "java[0-9]+" (include "minecraft-server.imageTag" .) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
The Java line minecraft.version requires, or the empty string when the value is
|
||||
not a version this chart can compare.
|
||||
|
||||
The boundaries are Mojang's, not this chart's: they are javaVersion.majorVersion
|
||||
from the piston-meta version manifest, swept over all 102 releases on 2026-09-02.
|
||||
The transitions are exactly four, and monotonic in release order:
|
||||
|
||||
1.0 - 1.16.5 java 8 (1.6.1-1.6.4 predate the field and carry none)
|
||||
1.17 - 1.17.1 java 16
|
||||
1.18 - 1.20.4 java 17
|
||||
1.20.5 - 1.21.11 java 21
|
||||
26.1 and later java 25
|
||||
|
||||
DELIBERATE GAP: a minecraft.version that is not a plain numeric "x", "x.y" or
|
||||
"x.y.z" - a snapshot ("26w13a"), a pre-release ("1.21.11-pre1"), "LATEST" -
|
||||
yields the empty string and is let through unchecked. The chart cannot compare
|
||||
it, and a guard that rejects everything it does not understand gets worked
|
||||
around instead of respected. The mismatch then still surfaces the old way:
|
||||
CrashLoopBackOff once the startup budget is spent, with the reason in the log.
|
||||
*/}}
|
||||
{{- define "minecraft-server.requiredJavaLine" -}}
|
||||
{{- $v := printf "%v" .Values.minecraft.version | trim -}}
|
||||
{{- if regexMatch "^[0-9]+(\\.[0-9]+){0,2}$" $v -}}
|
||||
{{- $n := len (splitList "." $v) -}}
|
||||
{{- $sv := $v -}}
|
||||
{{- if eq $n 1 -}}{{- $sv = printf "%s.0.0" $v -}}{{- else if eq $n 2 -}}{{- $sv = printf "%s.0" $v -}}{{- end -}}
|
||||
{{- if semverCompare "< 1.17.0" $sv -}}java8
|
||||
{{- else if semverCompare "< 1.18.0" $sv -}}java16
|
||||
{{- else if semverCompare "< 1.20.5" $sv -}}java17
|
||||
{{- else if semverCompare "< 26.1.0" $sv -}}java21
|
||||
{{- else -}}java25
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Guard: minecraft.version must fit the Java line of the effective image tag.
|
||||
|
||||
Until chart 5.0.0 nothing checked this - a mismatch rendered and installed
|
||||
without a word, and only the container failed afterwards. It now fails at render
|
||||
time, which is a behaviour change for an installation that already runs a
|
||||
mismatched pair (it does not run: it fails earlier and visibly instead).
|
||||
|
||||
The check runs ALWAYS, not only when image.tagOverride is set: Helm merges user
|
||||
values into the chart defaults indistinguishably, so a template cannot tell a
|
||||
deliberately set minecraft.version from the chart's own default.
|
||||
|
||||
DELIBERATE GAP, the second one: an image tag without a recognizable java<N> part
|
||||
is let through - see minecraft-server.javaLine. Same reasoning as for an
|
||||
uncomparable minecraft.version.
|
||||
*/}}
|
||||
{{- define "minecraft-server.validateJavaLine" -}}
|
||||
{{- $tag := include "minecraft-server.imageTag" . -}}
|
||||
{{- $line := include "minecraft-server.javaLine" . -}}
|
||||
{{- $required := include "minecraft-server.requiredJavaLine" . -}}
|
||||
{{- if and $line $required -}}
|
||||
{{- if ne $line $required -}}
|
||||
{{- $source := include "minecraft-server.imageTagSource" . -}}
|
||||
{{- $swapped := regexReplaceAll "java[0-9]+" $tag $required -}}
|
||||
{{- fail (printf (join "\n" (list
|
||||
"minecraft-server: the image tag and minecraft.version belong to different Java lines."
|
||||
""
|
||||
" image tag %-22s is the %s line (from %s)"
|
||||
" minecraft.version %-22s needs the %s line"
|
||||
""
|
||||
"Java 8 runs Minecraft up to 1.16.5, 1.17-1.17.1 need Java 16, 1.18-1.20.4 need"
|
||||
"Java 17, 1.20.5-1.21.11 need Java 21, and 26.1 and later need Java 25 (Mojang's"
|
||||
"version manifest, javaVersion.majorVersion per release)."
|
||||
""
|
||||
"Change one of the two:"
|
||||
" - set minecraft.version to a release of the %s line, or"
|
||||
" - set image.tagOverride to an itzg/minecraft-server tag of the %s line"
|
||||
" (this tag with its line swapped would be \"%s\" - check that upstream"
|
||||
" published it before using it)."))
|
||||
(printf "%q" $tag) $line $source
|
||||
(printf "%q" (printf "%v" .Values.minecraft.version)) $required
|
||||
$line $required $swapped) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Merge a user-supplied values sub-tree onto a dict of chart defaults so that a
|
||||
null / empty override falls back to the defaults instead of erasing them.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{{- include "minecraft-server.validateModpackSources" . }}
|
||||
{{- include "minecraft-server.validateJavaLine" . }}
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
@@ -58,7 +59,11 @@ spec:
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Release.Name }}-{{ .Chart.Name }}-sfs
|
||||
image: "itzg/minecraft-server:{{ .Chart.AppVersion }}"
|
||||
{{- /* Tag from .Chart.AppVersion unless image.tagOverride replaces
|
||||
it; validateJavaLine above rejects a tag whose Java line does
|
||||
not fit minecraft.version. Template comment on purpose - a
|
||||
YAML comment here would change the rendered manifest. */}}
|
||||
image: "itzg/minecraft-server:{{ include "minecraft-server.imageTag" . }}"
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
{{- include "minecraft-server.containerSecurityContext" .Values.securityContext | nindent 12 }}
|
||||
|
||||
Reference in new issue
Block a user