After the rack move one of the RAID0 disks failed to enumerate, and jupiter boot-looped into an emergency shell nobody could use — root is locked, so sulogin offers a prompt with no answer, and there is no ssh from there: Timed out waiting for device /dev/disk/by-uuid/dadbff6f-... Dependency failed for /mnt/data. Dependency failed for /var/lib/private/prowlarr. Dependency failed for Local File Systems. local-fs.target: Job local-fs.target/start failed with result 'dependency' Reached target Emergency Mode. `nofail` on /mnt/data did not help, because the prowlarr and seerr bind mounts layered on top of it had none: without it a mount is RequiredBy local-fs.target, so those two failed the target on the array's behalf. Give them `nofail` too and let them fail alone. `systemd.enableEmergencyMode = false` then keeps a bad array from costing a reachable box at all — far more useful on a headless host than a console prompt. Booting further is only safe if nothing quietly relocates onto the 29G eMMC, so pin the array-backed services to the mount. systemd derives RequiresMountsFor from a unit's own paths, which for these is somewhere under /var/lib (eMMC) — nothing pointed immich at mediaLocation or sabnzbd at its configFile, so with the array gone they would have started and written to the OS disk, into directories that go invisible the moment /mnt/data mounts over them. jellyfin, sonarr, radarr and gitea already had a real dependency and are untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
52 lines
2.2 KiB
Nix
52 lines
2.2 KiB
Nix
{ ... }:
|
|
|
|
# SABnzbd — usenet downloader. Reuses the config migrated from the old
|
|
# ZimaOS docker stack (servers/API key/history already set up) by pointing
|
|
# straight at the real ini instead of generating a fresh NixOS-managed one.
|
|
# Runs as the module's default dedicated `sabnzbd` system user — after first
|
|
# deploy, chown the migrated config dir to it (see README/CLAUDE notes):
|
|
# chown -R sabnzbd:sabnzbd /mnt/data/AppData/sabnzbd/config
|
|
{
|
|
services.sabnzbd = {
|
|
enable = true;
|
|
configFile = "/mnt/data/AppData/sabnzbd/config/sabnzbd.ini";
|
|
allowConfigWrite = true; # real pre-existing state — let sabnzbd keep saving it
|
|
};
|
|
|
|
# Write access to the shared downloads dir (owned darman:users on disk).
|
|
users.users.sabnzbd.extraGroups = [ "users" ];
|
|
|
|
# configFile and the downloads dir both live on the array, but systemd only
|
|
# derives RequiresMountsFor from /var/lib/sabnzbd (eMMC) — so with the array
|
|
# absent sabnzbd would start and download onto the 29G OS disk.
|
|
systemd.services.sabnzbd.unitConfig.RequiresMountsFor = [ "/mnt/data" ];
|
|
systemd.services.fix-downloads-perms.unitConfig.RequiresMountsFor = [ "/mnt/data" ];
|
|
|
|
# SABnzbd hardcodes completed job folders to 0700 on every job, ignoring
|
|
# the ini's `umask` (that only covers files during unpack, not the job
|
|
# dir itself). setgid on Downloads keeps the group as "users" but perm
|
|
# bits still come back zeroed, locking out cinephage/mediamanager — sweep
|
|
# it clean instead of fighting SABnzbd.
|
|
systemd.services.fix-downloads-perms = {
|
|
description = "Fix group perms SABnzbd resets on completed downloads";
|
|
serviceConfig.Type = "oneshot";
|
|
script = ''
|
|
find /mnt/data/HighSeas/Downloads \
|
|
! -group users -exec chgrp users {} + 2>/dev/null || true
|
|
find /mnt/data/HighSeas/Downloads -type d ! -perm -g+rwx \
|
|
-exec chmod g+rwx {} + 2>/dev/null || true
|
|
find /mnt/data/HighSeas/Downloads -type f ! -perm -g+rw \
|
|
-exec chmod g+rw {} + 2>/dev/null || true
|
|
'';
|
|
};
|
|
|
|
systemd.timers.fix-downloads-perms = {
|
|
description = "Periodically fix group perms under HighSeas/Downloads";
|
|
wantedBy = [ "timers.target" ];
|
|
timerConfig = {
|
|
OnBootSec = "1m";
|
|
OnUnitActiveSec = "2m";
|
|
};
|
|
};
|
|
}
|