v0.66.0: userdata layout + shared-storage ownership convention
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>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
//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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user