docs: README userdata convention + REPORT for v0.66.x (userdata layout)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-14 22:31:30 +02:00
parent 3b7d08979c
commit d0718e8d0e
2 changed files with 103 additions and 59 deletions
+25
View File
@@ -698,6 +698,31 @@ not just those with HDD data. Non-HDD apps can configure destination, method, an
> restores `Schedulable`. A deployed app whose drive is decommissioned/disconnected/absent shows the
> **"Hiányzó tárhely"** warning badge on the dashboard/stacks/app card.
>
> - **(v0.66.0) Userdata layout + shared-storage ownership convention** (`internal/appbackup/userdata.go`).
> Each drive's felhom-data namespace gains a customer-facing **`userdata/`** tree (sibling of
> `appdata/`/`backups/`) — the ONLY thing FileBrowser mounts. Skeleton:
> `media/{movies,tv,music,audiobooks,books,comics,photos}`, `downloads`, `import/{paperless,calibre}`,
> `roms`, `documents`. **Convention:** every userdata dir is group-owned by `SharedContentGID` (1000),
> mode **2775** (setgid + group-rwx) — `EnsureUserdataDir` = MkdirAll → explicit `Chmod(ModeSetgid|0775)`
> (MkdirAll's mode is umask-masked AND drops setgid) → chown group 1000. Setgid makes new files inherit
> group 1000 so FileBrowser (uid 1000) + the content apps collaborate without permission collisions.
> - **`USERDATA_PATH`** = `<HDD_PATH>/userdata` is injected into the compose env (the shared
> `withUserdataPath`, used by BOTH `stackEnv` and `composeExecWithEnv` — the initial deploy builds env
> from values, not app.yaml). Catalog media mounts use `${USERDATA_PATH}/...`.
> - **Pre-create**: the full skeleton is created with the convention on `registerStoragePath` +
> `syncFileBrowserMounts` (system + additional drives); a **deploy belt** in `composeExecCustomEnv`
> (on `up`) pre-creates every `${USERDATA_PATH}/...` bind source the app declares, so Docker never
> auto-creates a userdata dir as guest-root (covers apps not in the skeleton).
> - **FileBrowser** mounts `<drive>/userdata` (was `appdata`) and runs as uid 1000 → it can create
> folders + upload into the 2775 setgid tree (fixes the old permission-denied); app internals
> (`appdata/`) are no longer browsable.
> - **Run-identity**: PUID/PGID-1000 apps (radarr/sonarr/calibre with `UMASK=002`) write **group-
> writable**, so FileBrowser can fully manage their output. Root-only apps (jellyfin :ro; komga +
> audiobookshelf RW after the `user:1000` fallback) write **group-readable** via setgid (FileBrowser
> browses/reads, the app manages its own files).
> - **Migration-safe**: `migrate.go`'s merge walk preserves the source dir's setgid + group (and
> `copyFile` the full file mode + group), so the convention survives a whole-drive `MigrateAll`.
>
> The privileged controller-side disk subsections **below are historical** (the `internal/storage/*` scan/
> format code was removed in 8C — execution is the agent's now).