Commit Graph
7 Commits
Author SHA1 Message Date
jklein bfa72181eb minecraft-server: move to the java25 line (4.1.0+up2026.8.2.java25)
Minecraft 26.2 requires Java 25, so the chart's default minecraft.version can
only be raised on a java25 image. appVersion becomes 2026.8.2-java25 - the same
dated upstream release the java21 line ships, so the only variables that change
are the JVM and the Minecraft version.

The chart version stays at 4.1.0: the Java lines are siblings of one chart
generation, not successors, and are told apart by the +up suffix.

The Java boundaries in the values.yaml / NOTES.txt comments are read off
Mojang's version manifest (javaVersion.majorVersion per release), not
estimated: 1.21.11 is the last release asking for Java 21, every release from
26.1 on asks for Java 25.
2026-09-01 17:30:22 +02:00
jklein 5c5160a920 minecraft-server: NOTES.txt and the exponential-quantity fix (4.1.0+up2026.8.2.java21)
Teil von #157 and Teil von #43, in one change because both are additive and
neither moves a rendered object.

#157 - multiplyQuantity turned large numbers into exponential notation. The
null-safe fallback helpers pass values through fromYaml, which parses every
number as float64, and Go's "%v" switches float64 to exponential notation from
about 1e6 upwards. A bare byte count like 1048576 became "1.048576e+06".

The chart has two affected positions, and they fail differently:

  - the entry of multiplyQuantity aborts the render loudly, because the
    exponent is caught by the suffix check
    (unsupported resource quantity suffix "e+06").
  - the output of a non-integer product never reaches that check and renders
    silently: a fractional limitFactor together with a bare number produced
    "1.4999985e+06" in the manifest, rejected only later by the API server.

Note that this chart's schema types limitFactor as "number" with
exclusiveMinimum 0, not as an integer, so the silent path is reachable here
through ordinary values.

Both positions now go through a new minecraft-server.formatNumber helper, the
canonical correction already applied to template-chart, voucher-vault, zipline,
outline and minecraft-router.

#43 - NOTES.txt for this chart. It prints what an operator would otherwise have
to read out of the templates, conditional on the values actually set:

  - access, which is not a URL: ClusterIP means the server is reachable only
    once its Service name is entered in the minecraft-router release's static
    mappings, since that router does no auto-discovery; NodePort prints the
    node port and warns when it falls outside 30000-32767.
  - the Java line, derived from appVersion rather than written into the file,
    so it holds for all three published lines, together with the fact that
    nothing checks minecraft.version against it.
  - what a green rollout does not prove. The probes do run a real server-list
    ping, so Ready means the server answers - but a ping is answered before any
    login, so every login-side refusal is invisible to all three probes. The
    whitelist is the practical case: enabled without players locks everyone out
    while the rollout stays green.
  - which fields the 1Password item must carry, listed only for the features
    actually enabled, plus the documented gap that a changed item content does
    not roll the pod.
  - the world PVC that helm uninstall deletes, the two memory numbers and how
    they decouple, RCON not being published by the Service, the declared but
    unserved metrics port, and the enabled modpack source.

No real domain anywhere; the router example uses mc.example.com.

Verified: helm lint --strict clean on all three Java lines; rendering the CI
values and the chart defaults is byte-identical to origin/main, so no
Kubernetes object changes and the minor bump is the right one.
2026-08-29 00:43:22 +02:00
jklein fc8f57e176 minecraft-server: null-safe hardening, probes and resources
The last open gap of #99. minecraft-server was the one chart of 21 where an
erased security context removed the hardening in silence: it never got the
defaultedDict helper, the StatefulSet rendered .Values.securityContext.pod
straight through toYaml, and the schema typed securityContext.pod as a strict
"object" without required. Measured against ci/minecraft-server/test-values.yaml
on 3.0.1:

  --set securityContext.pod=null --set securityContext.container=null
  -> helm exit 0, no schema error, "securityContext: null" for BOTH the pod and
     the container - no runAsNonRoot, no readOnlyRootFilesystem, no dropped
     capabilities, in a chart with a PVC.

Bitter place for it: the README lists this chart as the pilot for #68. It got
its schema early and was therefore never caught by the later null-safety wave.

Both halves are added, because they cover different cases. For a key WITH a
chart default Helm's coalescing deletes the null before validation ever sees
it, and only the defaultedDict fallback catches that; for a key WITHOUT one
(server.resources.limits) the null survives into validation, where the strict
"object" aborted the render. Now widened to ["object","null"].

The fallback table reproduces THIS chart's defaults, deviations included:
uid/gid pinned to 1000 (the image's minecraft user - starting as it directly
takes the entrypoint's non-root branch, which skips the recursive chown of
/data and the write to /etc/nsswitch.conf that a read-only root filesystem
would reject), fsGroupChangePolicy OnRootMismatch (a recursive chown of a 32Gi
world on every start costs minutes), the explicit empty capabilities.add list,
and all three probes as exec probes running the image's mc-health script - this
image has no HTTP endpoint, so a probe default rebuilt as httpGet would leave
the workload with no working probe at all. The startup budget stays 15s x 80.

server.resources goes through the same helper while keeping its memory request
deliberately unset, so it is still derived from the JVM heap.

Also, the same class one level down: init.sh chowned the migrated serverpack to
a hardcoded 1000:1000 while the uid it has to match was overridable. Both reads
now go through the same helper, so they cannot disagree. With the chart defaults
the rendered script is unchanged, so checksum/config does not move and no
existing pod rolls.

minecraft.resources.storage and .memory stay deliberately not null-safe: an
erased value yields an invalid PVC or an unparseable quantity, which is the loud
class #99 excludes.

Evidence, all against ci/minecraft-server/test-values.yaml unless noted:

  - the reported call now renders the defaults, byte-identical to the
    unmodified rendering. Fallback, not rejection.
  - rendering with securityContext, all three probes and server.resources set
    to null is byte-identical to rendering the chart defaults - which is what
    keeps the table and values.yaml in sync instead of leaving it to discipline.
  - no regression: rendering before and after the change is byte-identical, on
    the CI values, on the chart defaults, and with curseforgeServerpack enabled
    (the init-container path the CI values do not exercise). Confirmed
    structurally too, not only by raw diff.
  - partial nulling, 14 keys swept one at a time. On 3.0.1 twelve of them
    changed the rendering silently, including capabilities (the container kept
    every default capability instead of dropping ALL) and requests (cpu and
    ephemeral-storage disappeared entirely). On 4.0.0 all fourteen render
    identical to the defaults.
  - explicit false and 0 still win over the defaults; a scalar in a mapping slot
    is still rejected, now naming the values path.

Major bump: erasing one of these blocks used to change the rendered workload
and now does not, which is a runtime behaviour change. appVersion is untouched.

Refs #99
2026-08-24 16:53:25 +02:00
jklein 58ea3b62d4 Restart the server when its config changes (3.0.0+up2026.8.2.java8)
The StatefulSet now carries two annotations over its two configuration
sources, so a change to either produces a new pod template and a controlled
restart:

  checksum/config      the rendered ConfigMap (init.sh) - complete, Helm sees
                       the whole content
  checksum/secret-ref  the rendered OnePasswordItem - the op:// item path only,
                       because the Secret's content is materialized by the
                       operator and is unknown to Helm at render time

Two separate annotations rather than one combined hash: they carry different
guarantees, and a single number would blur "covers everything" and "covers the
path but not the content" into one value that nobody can interpret in a
kubectl describe.

The operator's own operator.1password.io/auto-restart is deliberately NOT set:
it restarts Deployments only. Verified in the operator source (main, 9c3b1b9):
restartWorkloadsWithUpdatedSecrets lists nothing but appsv1.DeploymentList and
getPodTemplate has a single case for *appsv1.Deployment. On this StatefulSet
the annotation would be inert while suggesting the opposite, so the remaining
gap - a rotated value inside the vault item - is documented in values.yaml
instead.

First of the three stage-3-style publishes, so the java8 line goes first and
main ends up on java21. Only the published Java line differs between them:
appVersion 2026.8.2-java8 and the matching minecraft.version default 1.12.2.

Major bump: runtime behaviour changes. A configuration change now costs a full
server restart - 124 s measured for ftb-skies on Longhorn.

Refs #82.
2026-08-23 19:04:03 +02:00
jklein 4874e5db1f Pin minecraft-server to dated image tags and fix the whitelist switch (2.0.0+up2026.8.2.java8)
Stage 3 of the Fleet migration. Two changes, both breaking, hence the major
bump from 1.0.0 to 2.0.0.

Dated image tags: appVersion moves from the rolling line tag "java8" to the
immutable upstream release tag "2026.8.2-java8". The rolling tags are rebuilt
continuously, so a pod restart could pull a different image than the previous
start without that being recorded anywhere. 2026.8.2 is the newest upstream
release (published 2026-08-23) and exists for all three Java lines.

Whitelist semantics: the chart now wires ENABLE_WHITELIST (and ENFORCE_WHITELIST)
in both positions, so minecraft.whitelist.enabled: false actually switches the
whitelist off. Previously the chart only emitted whitelist variables while
enabled was true and had no way to express "off" - and because server.properties
lives on the PVC, a release that had once written white-list=true kept it
forever. players stays guarded by enabled, since a non-empty WHITELIST enables
the whitelist in the image regardless of ENABLE_WHITELIST.

The default flips from enabled: true to enabled: false. Under the corrected
semantics the old default (enabled with an empty player list) would mean a
server nobody can join; false matches both the image and vanilla Minecraft.
2026-08-23 18:06:23 +02:00
jklein 227bcebeb6 Bring minecraft-server up to the chart style guidelines (1.0.0+upjava8)
Stage 2 of the Fleet migration for minecraft-server. Major bump: runtime
behaviour changes (probes, hardening) and the values interface breaks
(resource renames, strict schema).

Two real bugs first:
- The container declared port 35565 while the Service targeted 25565. It
  only worked because targetPort was numeric. Both are now server.port
  (25565) and the Service targets the named port.
- The download-serverpack init container was guarded by the map
  .Values.curseforgeServerpack instead of .enabled, so it rendered for
  every release and silently no-opped on an empty wget URL.

Conventions:
- Resources renamed to <release>-<chart>-<kind>, templates to
  <app>.<kind>.yaml. The PVC deliberately keeps its historical name -
  renaming it would provision a new, empty volume and orphan the worlds.
- Probes (liveness/readiness/startup) via the image's own mc-health, so
  Ready means the server answers a server-list ping. Startup budget 20 min.
- Hardened, values-configurable security contexts: non-root uid 1000,
  read-only root filesystem with an emptyDir at /tmp, all caps dropped.
- Resources from values with the limitFactor helper; an unset memory
  request is derived from the JVM heap so the two cannot drift apart.
- Additive env block rendered through tpl, pinned init image, storage
  class as a value, RCON wiring only when actually enabled.
- curseforge/ftb/curseforgeServerpack are now mutually exclusive.
- minecraft.version is pinned to the Java line instead of LATEST.
- The mc-router auto-discovery annotation is gone; the service type it
  implicitly switched is now the explicit value server.service.type.

Schema pilot (#68): values.schema.json with additionalProperties false on
every chart-owned level, rejecting all three known dead keys.
2026-08-23 16:40:44 +02:00
jklein a68192e5fb Import minecraft-server chart for Fleet migration stage 1 (java8 line)
Imports the chart from cluster-config functionally unchanged, wires it into
the publish/validate/install-test pipelines and publishes it as the first of
three Java lines (0.4.0+upjava8).

The only deviation from the source chart is the chart-global scaleDown flag
plus a server.replicas value, following the satisfactory pattern: two of the
three servers stand at 0 replicas in the cluster, which the chart could not
express, and Fleet would otherwise start them on reconcile. The default
(scaleDown: false) still renders replicas: 1, so the rendering of the running
server is unchanged - verified byte-identical against the three real values
files for all three Java lines.

Known deficiencies (hardening, probes, naming scheme, hardcoded values,
missing icon, the misleading mc-router auto-discovery annotations) are left
untouched on purpose and are scheduled for stage 2.
2026-08-23 15:57:17 +02:00