Repository navigation
operator: stage OCI template upgrades before rolling all referencing game servers #731
Description
A Module update replaces a shared GameTemplate, and the operator reconciles each referencing GameServer against the new pod template. A catalog update can therefore become a fleet rollout without per-server maintenance approval or a staged adoption policy.
Priority: Medium; production-readiness enhancement. Evidence: static inspection of upstream 04e41075cafc4c1a99bcb3723b0a8745ee810957 (2026-10-16). The failure scenarios below have not been reproduced in a running cluster.
Evidence and limits
- operator/internal/controller/module_controller.go:101 resolves an empty Module version to the catalog's latest version.
- operator/internal/controller/module_controller.go:296 verifies template ownership, then replaces the existing template spec.
- operator/internal/controller/gameserver_controller.go:489 maps template changes to referencing servers.
- operator/internal/controller/gameserver_controller.go:1510 rewrites the StatefulSet pod template.
- operator/internal/controller/gameserver_controller.go:551 assigns the primary PVC spec only on creation and retains its GameServer ownership.
The concern is disruption and application/save compatibility, not an assertion that a normal template upgrade deletes PVCs. Configured signature checks, digest handling, minimum-operator checks, ownership validation, and retained extra/mod PVCs are useful safeguards.
Recommended fix
- Separate installing a verified template revision from adopting it on running servers. Give each server an explicit effective revision/digest and a pending-update condition.
- Add an opt-in rollout policy with maintenance windows, bounded concurrency, canaries, and pause/resume controls. Preserve a documented policy for existing installations rather than changing their behavior silently.
- Route rollout through the same lifecycle exclusion used by backups/restores/wipes and through the game's graceful stop contract. Do not replace a quiesced process during a protected copy.
- Pin production Module versions until staged adoption exists. Treat version pinning as an immediate operational control, not a complete rollback mechanism.
- Record the image/template revision and relevant configuration with backups. Explain that save-format changes may require restoring data along with an older image.
- Document PVC retention for updates separately from GameServer deletion; deletion can garbage-collect GameServer-owned claims.
Acceptance criteria
- Installing a revision can leave current games running until explicitly admitted by rollout policy.
- A canary failure stops further adoption; concurrency limits hold across operator restart/leader changes.
- Active backups/restores prevent rollout and admission resumes after cleanup.
- Upgrade tests verify retained PVC identity and contents, and a representative game's save compatibility.
- Rollback guidance distinguishes reverting the runtime from restoring application data.
- Shared-template changes do not bypass per-server maintenance policy.
Activity
ValgulNecron commentedon Oct 20, 2026
Thanks, confirmed on master: the module controller overwrites the GameTemplate spec unconditionally (
operator/internal/controller/module_controller.go:296-305), and every GameServer referencing it is re-enqueued and re-renders its StatefulSet from it (gameserver_controller.go:489-496,:1510), so a module update rolls the whole fleet at once. PVCs are not rewritten, as you noted.Go ahead with a PR that keeps today's behavior as the default and adds an opt-in staged policy:
Until this lands, please document pinning
Module.spec.versionas the way to avoid fleet-wide rollouts.Baylem commentedon Oct 25, 2026
Implemented in #769. Automatic remains the default; per-GameServer OnRequest retains an immutable effective template until an administrator requests the exact installed digest. Status reports desired, effective and observed running revisions, with TemplateUpdatePending explaining pending adoption. Requests may be issued individually or by an administrator's batch process.
Adoption acquires #760's shared ownership from #718, waits for backup/restore/wipe cleanup, stops with the previous template, drains the old workload, then adopts the pinned revision. docs/template-rollouts.md documents Module.spec.version pinning for installations without this feature, plus digest pinning and rollback limits. Regression sources and the real-cluster rollout scenario cover deferred adoption and data retention.