mirror of
https://github.com/Ayymoss/Plutainer
synced 2026-08-24 14:32:06 -04:00
1 commit
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4ce33c637e
|
V2 layout (#4)
* v2: unify PLUTAINER_* env vars, restructure volume layout, harden entries
Volume layout (breaking — v1 volumes refused on start, see migrate-v1-to-v2.sh):
app/configs/ user-facing real *.cfg files (flat); SOT
app/logs/ stable symlinks (unchanged)
app/runtime/gamefiles/, app/runtime/plutonium/
app/.plutainer-version=2
Each entry script fans out symlinks from app/configs/*.cfg into the engine's
expected config dir, so games read configs through symlinks back to the
user-facing dir. RCON writeconfig writes back transparently.
Env vars unified: PLUTAINER_GAME/CONFIG_FILE/PORT/SERVER_NAME/MOD/AUTO_UPDATE/
HEALTHCHECK/SKIP_SEED/EXTRA_ARGS. Old PLUTO_/IW4X_/ALTER_ prefixes still work
via shim_env_vars in game-config.sh, emit [DEPRECATED] warning. PLUTO_SERVER_KEY,
PLUTO_MAX_CLIENTS, IW4X_NET_LOG_IP keep original names (single-family vars).
Other fixes folded in:
- Symlink existence guards via new link_files helper (eliminates dangling
symlinks when host gamefiles are missing — same class as the prior t7x '*'
bug).
- set -euo pipefail in all entry scripts.
- wget -N for t7x.exe (skip redownload when unchanged).
- HEALTHCHECK start-period: 1m -> 5m for slow first-run downloads.
- migrate-v1-to-v2.sh handles the volume restructure (supports --dry-run).
- .gitattributes pins shell/python/Dockerfile to LF.
* Fix shim_env_vars + detect_game_type under set -u
Indirect expansion ${!var} and bare ${VAR} both error out under set -u when
the referenced variable is unset. Add :- default so the strict mode in entry
scripts works when canonical PLUTAINER_* vars (or any old-prefix ones) are
absent.
* CI: build :v2 tag from v2-layout branch, keep separate from :latest
Workflow now triggers on pushes to main and v2-layout. Tag rules:
- :latest only when is_default_branch (= main).
- :v2 only when github.ref == refs/heads/v2-layout.
These conditions are mutually exclusive, so v2 builds never touch :latest
and main builds never touch :v2. Both branches still get a :sha-<short> tag.
Doc references updated from :main to :v2.
* v2: drop env-var shim; add raw-configs mode, auto-lift, hold/throttle, mod fan-out
Breaking (only on :v2 — :latest unaffected):
* shim_env_vars removed. PLUTO_*/IW4X_*/ALTER_* prefix env vars no longer
recognised. PLUTAINER_* is the only accepted form (plus the three unique
vars PLUTO_SERVER_KEY, PLUTO_MAX_CLIENTS, IW4X_NET_LOG_IP).
New:
* PLUTAINER_USE_RAW_CONFIGS=true opts out of the configs/ symlink system;
engine path becomes the SOT directly. Default off.
* ensure_config_present: auto-lifts CONFIG_FILE from engine path to configs/
if found as a real file there; refuses startup with case-insensitive
find-iname hint if absent everywhere.
* resolve_mod_config_dir + link_configs variadic: when PLUTAINER_MOD is set,
cfg symlinks fan out into BOTH the base engine config dir AND the
mod-scoped dir (plutonium fs_game / iw4x mod path). Alterware skipped
(Workshop ID, not a path).
* link_configs refuses to overwrite a real file at engine path; warns
instead. Prevents the silent-replace failure mode.
* hold_indefinitely: on startup validation failure, exec sleep infinity so
the container stays Up and docker doesn't loop restart it. User fixes
the config and runs docker restart.
* launch_game: 30s sleep after wine exits before container exits, so
restart policies (no min-delay knob in compose) throttle to ~1 restart
per 30s on real crashes.
* Improved extract_rcon_password: handles single-quoted and unquoted
forms; on failure emits a structured WARN telling the user the accepted
forms and not to set rcon_password via PLUTAINER_EXTRA_ARGS. Doesn't
block startup.
Docs updated (README + CLAUDE.md): removed deprecated-prefix table,
documented PLUTAINER_USE_RAW_CONFIGS, auto-lift, refuse behavior, restart
throttle, and the rcon parser accepted forms.
* Split auto-lift from ensure_config_present so seed can't pre-empt user file
Original order: seed_configs (cp -n) before ensure_config_present meant a
user's real cfg at engine path got bypassed because seed had already
filled configs/ with a default basename, satisfying the SOT check.
Now auto_lift_user_config runs before seed: if user has a real
(non-symlink) cfg at engine path, mv -f it to configs/ unconditionally.
Then seed gap-fills (cp -n preserves the user file). Then link_configs
fans out. Then ensure_config_present only does the presence-or-refuse
check.
Three callers updated: alterentry, plutoentry, iw4xentry.
* log-watcher: strip stray dirs at stable paths; reap orphan temp symlinks
A sidecar that bind-mounts an individual log file (e.g. games_zm.log) before
the file exists causes Docker to auto-create an empty root-owned directory at
that host path. place_symlink's mv -Tf then fails every poll and litters
logs/ with .XXX temp symlinks.
Fix both reactively in place_symlink and on startup heal. Try rmdir first
(empty dir, plutainer owns parent), fall back to rm -rf; if both fail (non-
empty root-owned dir), log a clear error pointing at the sidecar config.
* extract_rcon_password: accept bare 'rcon_password' (no set/seta prefix)
T6/T7 community cfgs commonly write `rcon_password "value"` without the
`set` keyword. Engine accepts both forms; parser only accepted the prefixed
form, so healthcheck and rcon-cli silently failed on stock t6zm seeds.
Make the `set[a]?` prefix optional and adjust the unquoted fallback to pick
the right awk column whether or not the prefix is present.
* Arm64 v2 (#3)
* Add ARM64 image variant with native Wine 11 via Hangover
New Dockerfile.arm64 targets aarch64 (Pi 5+, Ampere, Apple silicon under
Linux). Multi-stage build:
1. rust-builder -> native aarch64 plutonium-updater (upstream ships
no aarch64-linux release).
2. cpp-builder -> native aarch64 iw4x-launcher via build2 0.18.1
compiled from source.
3. runtime -> Debian 13 trixie + Hangover 11.4 (.deb bundle:
Wine 11 + FEX 2603 + box64 as Wine CPU plug-ins).
x86_64 Windows PE binaries (Plutonium/IW4x/T7x server exes) run under
Wine 11 thunked WoW64 with libarm64ecfex.dll as the CPU backend. No
user-space x86 emulator is required because the helper CLIs are native
aarch64.
scripts/ unchanged - the entrypoints call /home/plutainer/.plutainer/
{plutonium-updater,iw4x-launcher} by fixed path, and we drop a native
aarch64 ELF at exactly that path. The amd64 Dockerfile and its
workflow are untouched.
CI: .github/workflows/docker-publish-arm64.yml builds via QEMU on
ubuntu-latest and pushes ghcr.io/<repo>:arm64. Comment in the file
notes the ubuntu-24.04-arm runner swap for a 3-5x speedup.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add curl to arm64 cpp-builder stage so build2 installer runs
The build2-install-*.sh script unconditionally `check_cmd curl`s before
fetching the toolchain source tarball; the stage shipped only wget, so
the installer exited 1 on first ARM64 build. Add curl to the apt list
and use it for the script download too for consistency.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Switch arm64 CI to native ubuntu-24.04-arm runner
Plutainer is a public repo, so ARM-hosted runners are free. The
Multi-Stage Dockerfile compiles build2 from source and runs full
cargo/build2 builds; QEMU-emulated on ubuntu-latest that runs 60-90 min
and exposes flaky edge cases. Native aarch64 should land at 20-30 min
and removes QEMU as a failure surface.
setup-qemu-action removed (not needed on native arm runner).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Adapt arm64 image to v2-layout: add migrate-v1-to-v2.sh, retag
Two narrow tweaks on top of the v2 scripts:
* Dockerfile.arm64: include migrate-v1-to-v2.sh in the chmod list so the
v2 entrypoint can find it executable (was missing because the original
arm64 commit predated v2).
* CI workflow: trigger on `arm64-v2` and `v2-layout` too, and emit a
clean `:arm64-v2` tag for those branches instead of the v1-style
`arm64-{{branch}}` pattern which would produce `arm64-arm64-v2`.
scripts/ themselves come unchanged from upstream v2-layout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* v2: combined v1-deployment refusal + MIGRATION.md + workflow for :latest promotion
Pre-promotion to :latest, the v2 image needs to refuse v1 deployments
cleanly. Previously the volume check printed its own refusal block but the
env-var side was silent — a user pulling :latest (post-promotion) onto
their v1 compose would have hit "PLUTAINER_CONFIG_FILE not set" with no
hint that the rename was the cause.
Changes:
- detect_legacy_env_vars: scans PLUTO_*/IW4X_*/ALTER_* names, populates
LEGACY_ENVS_FOUND. Returns non-zero if any are set.
- check_volume_version: still validates marker / inits fresh / detects v1,
but no longer prints the v1 block inline. Sets V1_VOLUME_DETECTED=true
on v1 detection and returns. Marker-mismatch errors still print.
- print_v1_migration_block: combined refusal block, adapts to what was
detected (env, volume, or both). Shows both paths side by side —
pin :v1-final or migrate via the bundled tool + env rename.
- entrypoint.sh: runs both detectors before deciding to hold, so a single
block surfaces every reason for refusal.
- MIGRATION.md: full env mapping table, step-by-step migration, rollback.
- README.md: top banner rewritten for the post-promotion tag layout.
:latest = v2, :v1-final = frozen v1.
- docker-publish.yml + docker-publish-arm64.yml: :v2 / :arm64-v2 enable
predicates now also fire on main, so the post-merge build publishes
both the canonical (:latest / :arm64) and the alias tags.
---------
Co-authored-by: nellydocs <71311423+nellydocs@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|