Merge branch 'beta' into dev

This commit is contained in:
rasmus-kirk
2025-06-01 16:53:26 +02:00
3 changed files with 137 additions and 98 deletions
+4 -96
View File
@@ -7,99 +7,6 @@
with lib; let with lib; let
cfg = config.nixarr; cfg = config.nixarr;
globals = config.util-nixarr.globals; globals = config.util-nixarr.globals;
list-unlinked = pkgs.writeShellApplication {
name = "list-unlinked";
runtimeInputs = with pkgs; [util-linux];
text = ''
if [ "$#" -ne 1 ]; then
echo "Illegal number of parameters. Must be one file path"
fi
find "$1" -type f -links 1 -exec du -h {} + | sort -h
'';
};
fix-permissions = pkgs.writeShellApplication {
name = "fix-permissions";
runtimeInputs = with pkgs; [util-linux];
text =
''
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit
fi
find "${cfg.mediaDir}" \( -type d -exec chmod 0775 {} + -true \) -o \( -exec chmod 0664 {} + \)
''
+ strings.optionalString cfg.jellyfin.enable ''
chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${cfg.mediaDir}/library"
chown -R ${globals.jellyfin.user}:root "${cfg.jellyfin.stateDir}"
find "${cfg.jellyfin.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.plex.enable ''
chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${cfg.mediaDir}/library"
chown -R ${globals.plex.user}:root "${cfg.plex.stateDir}"
find "${cfg.plex.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.audiobookshelf.enable ''
chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${cfg.mediaDir}/library"
chown -R ${globals.audiobookshelf.user}:root "${cfg.audiobookshelf.stateDir}"
find "${cfg.audiobookshelf.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.transmission.enable ''
chown -R ${globals.transmission.user}:${globals.transmission.group} "${cfg.mediaDir}/torrents"
chown -R ${globals.transmission.user}:${globals.transmission.group} "${cfg.transmission.stateDir}"
find "${cfg.transmission.stateDir}" \( -type d -exec chmod 0750 {} + -true \) -o \( -exec chmod 0640 {} + \)
''
+ strings.optionalString cfg.sabnzbd.enable ''
chown -R ${globals.sabnzbd.user}:${globals.sabnzbd.group} "${cfg.mediaDir}/usenet"
chown -R ${globals.sabnzbd.user}:root "${cfg.sabnzbd.stateDir}"
find "${cfg.sabnzbd.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.transmission.privateTrackers.cross-seed.enable ''
chown -R ${globals.cross-seed.user}:root "${cfg.transmission.privateTrackers.cross-seed.stateDir}"
find "${cfg.transmission.privateTrackers.cross-seed.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.prowlarr.enable ''
chown -R ${globals.prowlarr.user}:root "${cfg.prowlarr.stateDir}"
find "${cfg.prowlarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.sonarr.enable ''
chown -R ${globals.sonarr.user}:root "${cfg.sonarr.stateDir}"
find "${cfg.sonarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.radarr.enable ''
chown -R ${globals.radarr.user}:root "${cfg.radarr.stateDir}"
find "${cfg.radarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.lidarr.enable ''
chown -R ${globals.lidarr.user}:root "${cfg.lidarr.stateDir}"
find "${cfg.lidarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.bazarr.enable ''
chown -R ${globals.bazarr.user}:root "${cfg.bazarr.stateDir}"
find "${cfg.bazarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.readarr.enable ''
chown -R ${globals.readarr.user}:root "${cfg.readarr.stateDir}"
find "${cfg.readarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.readarr-audiobook.enable ''
chown -R ${globals.readarr.user}:root "${cfg.readarr-audiobook.stateDir}"
find "${cfg.readarr-audiobook.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.jellyseerr.enable ''
chown -R ${globals.jellyseerr.user}:root "${cfg.jellyseerr.stateDir}"
find "${cfg.jellyseerr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.autobrr.enable ''
chown -R ${globals.autobrr.user}:root "${cfg.autobrr.stateDir}"
find "${cfg.autobrr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''
+ strings.optionalString cfg.recyclarr.enable ''
chown -R ${globals.recyclarr.user}:root "${cfg.recyclarr.stateDir}"
find "${cfg.recyclarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
'';
};
in { in {
imports = [ imports = [
./audiobookshelf ./audiobookshelf
@@ -109,6 +16,7 @@ in {
./jellyfin ./jellyfin
./jellyseerr ./jellyseerr
./lidarr ./lidarr
./nixarr-command
./openssh ./openssh
./plex ./plex
./prowlarr ./prowlarr
@@ -140,6 +48,8 @@ in {
- **Optional Automatic Port Forwarding:** This module has a UPNP support that - **Optional Automatic Port Forwarding:** This module has a UPNP support that
lets services request ports from your router automatically, if you enable it. lets services request ports from your router automatically, if you enable it.
Also comes with the `nixarr` command that helps you manage your library.
It is possible, _but not recommended_, to run the "*Arrs" behind a VPN, It is possible, _but not recommended_, to run the "*Arrs" behind a VPN,
because it can cause rate limiting issues. Generally, you should use because it can cause rate limiting issues. Generally, you should use
VPN on transmission and maybe jellyfin, depending on your setup. VPN on transmission and maybe jellyfin, depending on your setup.
@@ -304,13 +214,11 @@ in {
users.groups.media.members = cfg.mediaUsers; users.groups.media.members = cfg.mediaUsers;
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d '${cfg.mediaDir}' 0775 root media - -" "d '${cfg.mediaDir}' 0775 ${globals.libraryOwner.user} ${globals.libraryOwner.group} - -"
]; ];
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
jdupes jdupes
list-unlinked
fix-permissions
]; ];
vpnNamespaces.wg = mkIf cfg.vpn.enable { vpnNamespaces.wg = mkIf cfg.vpn.enable {
+131
View File
@@ -0,0 +1,131 @@
{
inputs,
config,
pkgs,
lib,
...
}:
with lib; let
nixarr = config.nixarr;
globals = config.util-nixarr.globals;
nixarr-command = pkgs.writeShellApplication {
name = "nixarr";
runtimeInputs = with pkgs; [util-linux];
text = ''
command="''${1:-}"
# Check if a parameter is provided
if [ -z "$command" ]; then
echo "Usage: nixarr <command>"
echo ""
echo "Commands:"
echo " fix-permissions Sets correct permissions for any directory managed by Nixarr."
echo " list-unlinked Lists unlinked directories and files, in the given directory."
echo " Use on the media directory to diagnose harddrive space issues."
exit 1
fi
fix-permissions() {
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit
fi
find "${nixarr.mediaDir}" \( -type d -exec chmod 0775 {} + -true \) -o \( -exec chmod 0664 {} + \)
${strings.optionalString nixarr.jellyfin.enable ''
chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${nixarr.mediaDir}/library"
chown -R ${globals.jellyfin.user}:root "${nixarr.jellyfin.stateDir}"
find "${nixarr.jellyfin.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.plex.enable ''
chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${nixarr.mediaDir}/library"
chown -R ${globals.plex.user}:root "${nixarr.plex.stateDir}"
find "${nixarr.plex.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.audiobookshelf.enable ''
chown -R ${globals.libraryOwner.user}:${globals.libraryOwner.group} "${nixarr.mediaDir}/library"
chown -R ${globals.audiobookshelf.user}:root "${nixarr.audiobookshelf.stateDir}"
find "${nixarr.audiobookshelf.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.transmission.enable ''
chown -R ${globals.transmission.user}:${globals.transmission.group} "${nixarr.mediaDir}/torrents"
chown -R ${globals.transmission.user}:${globals.cross-seed.group} "${nixarr.transmission.stateDir}"
find "${nixarr.transmission.stateDir}" \( -type d -exec chmod 0750 {} + -true \) -o \( -exec chmod 0640 {} + \)
''}
${strings.optionalString nixarr.sabnzbd.enable ''
chown -R ${globals.sabnzbd.user}:${globals.sabnzbd.group} "${nixarr.mediaDir}/usenet"
chown -R ${globals.sabnzbd.user}:root "${nixarr.sabnzbd.stateDir}"
find "${nixarr.sabnzbd.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.transmission.privateTrackers.cross-seed.enable ''
chown -R ${globals.cross-seed.user}:root "${nixarr.transmission.privateTrackers.cross-seed.stateDir}"
find "${nixarr.transmission.privateTrackers.cross-seed.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.prowlarr.enable ''
chown -R ${globals.prowlarr.user}:root "${nixarr.prowlarr.stateDir}"
find "${nixarr.prowlarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.sonarr.enable ''
chown -R ${globals.sonarr.user}:root "${nixarr.sonarr.stateDir}"
find "${nixarr.sonarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.radarr.enable ''
chown -R ${globals.radarr.user}:root "${nixarr.radarr.stateDir}"
find "${nixarr.radarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.lidarr.enable ''
chown -R ${globals.lidarr.user}:root "${nixarr.lidarr.stateDir}"
find "${nixarr.lidarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.bazarr.enable ''
chown -R ${globals.bazarr.user}:root "${nixarr.bazarr.stateDir}"
find "${nixarr.bazarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.readarr.enable ''
chown -R ${globals.readarr.user}:root "${nixarr.readarr.stateDir}"
find "${nixarr.readarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.readarr-audiobook.enable ''
chown -R ${globals.readarr.user}:root "${nixarr.readarr-audiobook.stateDir}"
find "${nixarr.readarr-audiobook.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.jellyseerr.enable ''
chown -R ${globals.jellyseerr.user}:root "${nixarr.jellyseerr.stateDir}"
find "${nixarr.jellyseerr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.autobrr.enable ''
chown -R ${globals.autobrr.user}:root "${nixarr.autobrr.stateDir}"
find "${nixarr.autobrr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
${strings.optionalString nixarr.recyclarr.enable ''
chown -R ${globals.recyclarr.user}:root "${nixarr.recyclarr.stateDir}"
find "${nixarr.recyclarr.stateDir}" \( -type d -exec chmod 0700 {} + -true \) -o \( -exec chmod 0600 {} + \)
''}
}
list-unlinked() {
if [ "$#" -ne 1 ]; then
echo "Illegal number of parameters. Must be one file path"
fi
find "$1" -type f -links 1 -exec du -h {} + | sort -h
}
# Handle the command
case "$1" in
fix-permissions)
fix-permissions
;;
list-unlinked)
if [ "$#" -ne 1 ]; then
echo "Illegal number of parameters. Must be one file path"
fi
find "$1" -type f -links 1 -exec du -h {} + | sort -h
;;
esac
'';
};
in {
config.environment.systemPackages = [ nixarr-command ];
}