fix(workloads): world executors run as root so game-image worlds are readable

A live backup drill on test-one failed: 'tar walk: open
/world/world/level.dat: permission denied'. The world volume belongs to
the game image's own UID (root for every Paper image we ship), and Paper
saves level.dat mode 0600 — a fixed uid-1000 executor can neither read
it (backup/reaper archive) nor overwrite it (restore). The same identity
silently broke on-demand backups, restores, and the reaper for every
server that had saved once.

Run the backup Job, restore Job, file Job, and the reaper pod as root
with DAC_OVERRIDE on top of drop-ALL — the same owner-matching precedent
as the operator's forwarding-init container; DAC_OVERRIDE extends it to
game images whose UID is neither root nor ours. FSGroup is omitted when
zero so a root executor never chgrps the world volume. Shape tests
updated for the new identity.
This commit is contained in:
Lemon-miaow committed 2026-09-23 06:20:07 +08:00
1 parent f21aef3cfa
commit 2010961d32
12 files changed
+223 -105

No files matched your search

+11 -5
View File
@@ -557,11 +557,17 @@ the flag at k3s's storage root (`/var/lib/rancher/k3s/storage`) is therefore the
supported way to enable retention on a stock install. Two deployment facts the
resolver cannot fix:
- **Permissions.** The reaper pod runs as uid 1000, while k3s creates its
storage root `0700 root:root`. Without traverse (`setfacl -m u:1000:x`, or
`chmod o+x`; the installer applies this when `FELIS_WORLDS_HOST_PATH` is set)
every walk fails `permission denied` / `lstat …: permission denied` and the
world is **preserved**, never reaped — a silent no-op with ERROR logs.
- **Permissions.** The reaper Pod runs as **root** and carries `DAC_OVERRIDE`:
worlds are written by the game image's own UID (root for every Paper image we
ship), and Paper saves `level.dat` mode-0600, so any fixed non-root identity
(the previous uid-1000 convention, and the ACL setup that went with it) could
neither walk the tree nor read the files — every archive failed
`open …/level.dat: permission denied` and the same defect failed on-demand
backups/restores. Root is the same identity the game container itself runs as
(see the operator's forwarding-init note); `DAC_OVERRIDE` extends the archive
to game images with a different UID. If a world is still **preserved** while a
reap was expected, it is now a different cause: check the run's ERROR logs for
the resolver's `lstat` messages before suspecting permissions.
- **Node placement.** Multi-node clusters: the world's directory exists only on
the node holding its volume, and the CronJob sets no `nodeSelector`, so add
one (single-node starters are pinned implicitly).