Fix: chown directories created during caching to PUID/PGID (#178)#180
Merged
Brandon-Haney merged 1 commit intoJun 5, 2026
Merged
Conversation
The container runs as root so it can move files of any ownership, but raw os.makedirs() then left new array/cache folders owned by root:root (0755). On Unraid this blocked Sonarr/Radarr from importing into newly created library folders (StudioNirin#178). Add a shared create_dir_with_ownership() helper in core/system_utils.py that chowns every newly created directory level to PUID/PGID (or the source file's owner when those are unset), the same way file copies are already handled. Route the move/copy destination directory creation in the caching, eviction, upgrade, restore, symlink, and audit paths through it. FileUtils.create_directory_with_permissions now delegates to the helper so there is a single implementation.
StudioNirin
approved these changes
Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Unraid, PlexCache-D creates new top-level library folders (e.g.
/mnt/user/data/media/tv-shows/) asroot:rootwithdrwxr-xr-x(0755) instead ofnobody:usersdrwxrwxrwx. Because 0755 doesn't grant write access to non-root users, this blocks Sonarr/Radarr from creating new subdirectories inside those folders — imports fail withAccess to the path '...' is denied.Fixes #178.
Root cause
The container runs as root (so it can move files of any ownership) and compensates by
chown-ing what it creates to PUID/PGID. File copies already do this viacopy_file_with_permissions(), but several move/copy destination directory creations used a rawos.makedirs(), which — running as root — leaves new directories owned byroot:rootwith a umask-derived mode. On a multi-disk array, a/mnt/user0/write can land the folder chain on a disk where the library root doesn't exist yet, recreating it (and its parents) as root.Fix
create_dir_with_ownership()helper incore/system_utils.pythat creates a directory tree andchowns every newly created level to PUID/PGID (or the source file's owner when PUID/PGID are unset), best-effort and Linux-only — matching how file copies are already handled.FileUtils.create_directory_with_permissions()now delegates to the helper, so there is a single implementation shared with callers that have noFileUtilsinstance (the web service layer).Testing
TestCreateDirWithOwnership(4 tests): nested-tree creation, no-op when the path already exists, PUID/PGID applied to every newly created level (pre-existing ancestors left untouched), and fallback to the source file's owner when PUID is invalid/unset.Manual verification (Unraid, container with
PUID=99/PGID=100).plexcachedbackup) — anything that makes PlexCache create a new array folder.nobody:usersdrwxrwxrwx, notroot:rootdrwxr-xr-x.Note: only newly created directories are governed by this change; folders already created as
root:rootby prior runs are not retroactively fixed (use "Docker Safe New Permissions" once to clean those up).