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:
12 files changed
+223
-105
No files matched your search
@@ -87,9 +87,14 @@ type Config struct {
|
||||
// CPULimit / MemLimit cap the backup container.
|
||||
CPULimit string
|
||||
MemLimit string
|
||||
// RunAsUser / RunAsGroup / FSGroup are the Pod's runtime identity. FSGroup MUST
|
||||
// match the operator StatefulSet's runtime group so the read-only world mount is
|
||||
// readable by this Pod's uid.
|
||||
// RunAsUser / RunAsGroup / FSGroup are the Pod's runtime identity. They default
|
||||
// to ROOT (0:0) for the same reason the operator's forwarding-init container
|
||||
// runs as root: the world volume is written by the game image's own UID (root
|
||||
// for every Paper image we ship), and Paper saves files a non-root uid can
|
||||
// never read — level.dat is written mode 0600 (tar walk: permission denied,
|
||||
// verified live). DAC_OVERRIDE on the container covers images whose UID is
|
||||
// neither root nor ours. Set 0/0/0 explicitly for root; FSGroup is omitted
|
||||
// when zero.
|
||||
RunAsUser int64
|
||||
RunAsGroup int64
|
||||
FSGroup int64
|
||||
@@ -111,7 +116,6 @@ const (
|
||||
defaultDeadline = 30 * time.Minute
|
||||
defaultCPULimit = "1"
|
||||
defaultMemLimit = "1Gi"
|
||||
defaultRunAsID = int64(1000)
|
||||
defaultTTL = 10 * time.Minute
|
||||
)
|
||||
|
||||
@@ -145,15 +149,6 @@ func (c Config) withDefaults() Config {
|
||||
if c.MemLimit == "" {
|
||||
c.MemLimit = defaultMemLimit
|
||||
}
|
||||
if c.RunAsUser == 0 {
|
||||
c.RunAsUser = defaultRunAsID
|
||||
}
|
||||
if c.RunAsGroup == 0 {
|
||||
c.RunAsGroup = defaultRunAsID
|
||||
}
|
||||
if c.FSGroup == 0 {
|
||||
c.FSGroup = defaultRunAsID
|
||||
}
|
||||
if c.TTLAfterFinished <= 0 {
|
||||
c.TTLAfterFinished = defaultTTL
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user