c48f95fe06
appbackup/userdata.go: EnsureUserdataDir (MkdirAll + explicit setgid Chmod 2775 +
chown gid 1000), UserdataSkeleton, EnsureUserdataSkeleton; linux chown/StatGID +
non-linux stubs. stackEnv injects USERDATA_PATH=<HDD_PATH>/userdata. Skeleton
pre-created on register + FileBrowser sync; deploy belt (composeExecCustomEnv on
'up') pre-creates every ${USERDATA_PATH} bind source. FileBrowser mounts userdata
(was appdata) — uid 1000 can now write into 2775 setgid. #8: migrate merge walk +
copyFile preserve source setgid+group so the convention survives MigrateAll.
Non-hollow tests incl. Linux setgid assertions + migration-preserve companion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 lines
1.4 KiB
Go
44 lines
1.4 KiB
Go
//go:build linux
|
|
|
|
package appbackup
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// TestEnsureDirOwned_Setgid is the load-bearing assertion: EnsureDirOwned produces a dir with the
|
|
// SETGID bit + group-rwx (mode 02775) and the requested group. Uses the test's own gid so the chown
|
|
// succeeds without root. Companion: a plain MkdirAll(0755) does NOT get setgid — proving the explicit
|
|
// Chmod is what sets it (the spike's collision fix). This test FAILS on a pre-fix MkdirAll-only impl.
|
|
func TestEnsureDirOwned_Setgid(t *testing.T) {
|
|
gid := os.Getgid()
|
|
dir := filepath.Join(t.TempDir(), "userdata", "media", "movies")
|
|
if err := EnsureDirOwned(dir, gid); err != nil {
|
|
t.Fatalf("EnsureDirOwned: %v", err)
|
|
}
|
|
fi, err := os.Stat(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if fi.Mode()&os.ModeSetgid == 0 {
|
|
t.Errorf("dir is missing the setgid bit: mode=%v", fi.Mode())
|
|
}
|
|
if perm := fi.Mode().Perm(); perm != 0o775 {
|
|
t.Errorf("dir perm = %o, want 0775", perm)
|
|
}
|
|
if g, ok := StatGID(fi); !ok || g != gid {
|
|
t.Errorf("dir gid = %d (ok=%v), want %d", g, ok, gid)
|
|
}
|
|
|
|
// Companion: the pre-fix behaviour (MkdirAll only, no explicit setgid Chmod) → NO setgid.
|
|
plain := filepath.Join(t.TempDir(), "plain")
|
|
if err := os.MkdirAll(plain, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if pfi, _ := os.Stat(plain); pfi.Mode()&os.ModeSetgid != 0 {
|
|
t.Errorf("plain MkdirAll unexpectedly has setgid — the explicit Chmod is not load-bearing")
|
|
}
|
|
}
|