nixos/services/server-permissions.nix

52 lines
1.9 KiB
Nix
Raw Normal View History

# Media writes are allowed only after the pool and all its branches mount.
# Keep these directory rules out of global tmpfiles: nofail mounts may be
# absent when global tmpfiles runs, and creating paths then fills the root disk.
{ config, pkgs, lib, utils, ... }:
let
pool = "/mnt/storage";
branches = config.fileSystems.${pool}.depends or [ ];
mounts = map (p: "${utils.escapeSystemdPath p}.mount") ([ pool ] ++ branches);
consumers = [
"jellyfin" "sonarr" "radarr" "bazarr" "qbittorrent-nox" "sabnzbd"
"docker-shelfarr" "arr-interconnect" "bazarr-sync" "bazarr-sync-full"
];
directories = pkgs.writeText "media-directories.conf" ''
d /mnt/storage/torrents/downloads 2775 qbittorrent media -
d /mnt/storage/torrents/shows 2775 sonarr media -
d /mnt/storage/torrents/movies 2775 radarr media -
d /mnt/storage/torrents/audiobooks 2775 fred media -
d /mnt/storage/usenet/downloads 2775 sabnzbd media -
d /mnt/storage/usenet/incomplete 2775 sabnzbd media -
'';
in
2026-02-20 21:42:34 +00:00
{
config = lib.mkIf (config.networking.hostName == "FredOS-Mediaserver") {
systemd.services = {
media-storage-ready = {
description = "Prepare media directories on the mounted pool";
requires = mounts;
bindsTo = mounts;
after = mounts;
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
set -euo pipefail
${lib.concatMapStringsSep "\n" (p: ''
${pkgs.util-linux}/bin/mountpoint -q ${lib.escapeShellArg p} || {
echo "Required media mount missing: ${p}" >&2
exit 1
}
'') ([ pool ] ++ branches)}
${pkgs.systemd}/bin/systemd-tmpfiles --create ${directories}
'';
};
} // lib.genAttrs consumers (_: {
requires = [ "media-storage-ready.service" ];
after = [ "media-storage-ready.service" ];
bindsTo = [ "media-storage-ready.service" ];
});
2026-02-20 21:42:34 +00:00
};
}