From fee475957c15102bf5e4817eccd00c3a92a24291 Mon Sep 17 00:00:00 2001 From: Joseph Hanson Date: Tue, 4 Feb 2025 11:18:05 -0600 Subject: [PATCH] added unpackerr and pushover scripts --- nixos/configuration.nix | 0 nixos/hosts/shadowfax/config/sops-secrets.nix | 21 ++++- nixos/hosts/shadowfax/default.nix | 90 ++++++++++++++----- .../shadowfax/scripts/pushover-notify.sh | 89 ++++++++++++++++++ .../hosts/shadowfax/scripts/refresh-series.sh | 19 ++++ nixos/hosts/shadowfax/secrets.sops.yaml | 10 ++- nixos/modules/nixos/services/default.nix | 1 + .../nixos/services/prowlarr/default.nix | 40 +++++++-- .../modules/nixos/services/radarr/default.nix | 22 ++++- .../modules/nixos/services/sonarr/default.nix | 22 ++++- .../nixos/services/unpackerr/default.nix | 75 ++++++++++++++++ 11 files changed, 353 insertions(+), 36 deletions(-) create mode 100644 nixos/configuration.nix create mode 100644 nixos/hosts/shadowfax/scripts/pushover-notify.sh create mode 100644 nixos/hosts/shadowfax/scripts/refresh-series.sh create mode 100644 nixos/modules/nixos/services/unpackerr/default.nix diff --git a/nixos/configuration.nix b/nixos/configuration.nix new file mode 100644 index 0000000..e69de29 diff --git a/nixos/hosts/shadowfax/config/sops-secrets.nix b/nixos/hosts/shadowfax/config/sops-secrets.nix index fc8f445..fecadb9 100644 --- a/nixos/hosts/shadowfax/config/sops-secrets.nix +++ b/nixos/hosts/shadowfax/config/sops-secrets.nix @@ -84,7 +84,13 @@ mode = "400"; restartUnits = [ "sonarr.service" ]; }; - # # Radarr + "arr/sonarr/extraEnvVars" = { + sopsFile = ../secrets.sops.yaml; + owner = "sonarr"; + mode = "400"; + restartUnits = [ "sonarr.service" ]; + }; + # Radarr "arr/radarr/apiKey" = { sopsFile = ../secrets.sops.yaml; owner = "radarr"; @@ -115,5 +121,18 @@ mode = "400"; restartUnits = [ "radarr.service" ]; }; + "arr/radarr/extraEnvVars" = { + sopsFile = ../secrets.sops.yaml; + owner = "radarr"; + mode = "400"; + restartUnits = [ "radarr.service" ]; + }; + # Unpackerr + "arr/unpackerr/extraEnvVars" = { + sopsFile = ../secrets.sops.yaml; + owner = "unpackerr"; + mode = "400"; + restartUnits = [ "unpackerr.service" ]; + }; }; } diff --git a/nixos/hosts/shadowfax/default.nix b/nixos/hosts/shadowfax/default.nix index 355b6c0..6d1242b 100644 --- a/nixos/hosts/shadowfax/default.nix +++ b/nixos/hosts/shadowfax/default.nix @@ -4,28 +4,55 @@ inputs, pkgs, ... -}: -let - sanoidConfig = import ./config/sanoid.nix { }; +}: let + sanoidConfig = import ./config/sanoid.nix {}; disks = import ./config/disks.nix; - smartdDevices = map (device: { inherit device; }) disks; -in -{ + smartdDevices = map (device: {inherit device;}) disks; + pushoverNotify = pkgs.writeShellApplication { + name = "pushover-notify"; + + runtimeInputs = with pkgs; [ + curl + jo + jq + ]; + + excludeShellChecks = ["SC2154"]; + + text = '' + ${builtins.readFile ./scripts/pushover-notify.sh} + ''; + }; + refreshSeries = pkgs.writeShellApplication { + name = "refresh-series"; + + runtimeInputs = with pkgs; [ + curl + jq + ]; + + excludeShellChecks = ["SC2154"]; + + text = '' + ${builtins.readFile ./scripts/refresh-series.sh} + ''; + }; +in { imports = [ inputs.disko.nixosModules.disko (import ../../profiles/disko-nixos.nix { - disks = [ "/dev/sda|/dev/disk/by-id/nvme-Samsung_SSD_970_EVO_Plus_500GB_S58SNM0W406409E" ]; + disks = ["/dev/sda|/dev/disk/by-id/nvme-Samsung_SSD_970_EVO_Plus_500GB_S58SNM0W406409E"]; }) inputs.nix-minecraft.nixosModules.minecraft-servers ]; boot = { initrd = { - kernelModules = [ "nfs" ]; - supportedFilesystems = [ "nfs" ]; + kernelModules = ["nfs"]; + supportedFilesystems = ["nfs"]; }; - binfmt.emulatedSystems = [ "aarch64-linux" ]; # Enabled for arm compilation + binfmt.emulatedSystems = ["aarch64-linux"]; # Enabled for arm compilation kernelModules = [ "vfio" @@ -33,11 +60,11 @@ in "vfio_pci" "vfio_virqfd" ]; - extraModulePackages = [ ]; - kernelParams = [ "zfs.zfs_arc_max=107374182400" ]; # 100GB + extraModulePackages = []; + kernelParams = ["zfs.zfs_arc_max=107374182400"]; # 100GB }; - swapDevices = [ ]; + swapDevices = []; hardware = { cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; @@ -47,7 +74,7 @@ in nvidia-container-toolkit.enable = true; }; - users.users.root.openssh.authorizedKeys.keys = [ ]; + users.users.root.openssh.authorizedKeys.keys = []; # Network settings networking = { hostName = "shadowfax"; @@ -72,6 +99,7 @@ in }; }; + # System packages environment.systemPackages = with pkgs; [ libva-utils # to view graphics capabilities greetd.tuigreet @@ -87,7 +115,11 @@ in wlogout # fun fastfetch + # Scripts + pushoverNotify + refreshSeries ]; + programs = { # 1Password cli _1password.enable = true; @@ -135,7 +167,7 @@ in # Minio minio = { enable = true; - dataDir = [ "/eru/minio" ]; + dataDir = ["/eru/minio"]; rootCredentialsFile = config.sops.secrets."minio".path; }; @@ -162,7 +194,7 @@ in # Soft Serve - SSH git server soft-serve = { enable = true; - settings = import ./config/soft-serve.nix { }; + settings = import ./config/soft-serve.nix {}; }; sunshine = { @@ -182,7 +214,7 @@ in # VSCode Compatibility Settings vscode-server.enable = true; - xserver.videoDrivers = [ "nvidia" ]; + xserver.videoDrivers = ["nvidia"]; greetd = { enable = true; vt = 3; @@ -196,7 +228,7 @@ in }; # sops - sops = import ./config/sops-secrets.nix { }; + sops = import ./config/sops-secrets.nix {}; # System settings and services. mySystem = { @@ -237,6 +269,7 @@ in enable = true; package = pkgs.unstable.radarr; dataDir = "/nahar/radarr"; + extraEnvVarFile = config.sops.secrets."arr/radarr/extraEnvVars".path; moviesDir = "/moria/media/Movies"; user = "radarr"; group = "kah"; @@ -257,12 +290,13 @@ in enable = true; package = pkgs.unstable.sonarr; dataDir = "/nahar/sonarr"; + extraEnvVarFile = config.sops.secrets."arr/sonarr/extraEnvVars".path; tvDir = "/moria/media/TV"; user = "sonarr"; group = "kah"; port = 8989; openFirewall = true; - hardening = true; + hardening = false; apiKeyFile = config.sops.secrets."arr/sonarr/apiKey".path; db = { enable = true; @@ -278,12 +312,22 @@ in package = pkgs.unstable.sabnzbd; configFile = "/nahar/sabnzbd/sabnzbd.ini"; port = 8457; + user = "sabnzbd"; + group = "kah"; # Security hardening. dataDir = "/nahar/sabnzbd"; downloadsDir = "/eru/media/sabnzbd"; hardening = true; openFirewall = true; }; + unpackerr = { + enable = true; + package = pkgs.unstable.unpackerr; + configFile = "/tmp/unpackerr/config.yaml"; + extraEnvVarsFile = config.sops.secrets."arr/unpackerr/extraEnvVars".path; + user = "unpackerr"; + group = "kah"; + }; # Sanoid sanoid = { enable = true; @@ -310,7 +354,9 @@ in # qBittorrent qbittorrent = { enable = true; - package = pkgs.unstable.qbittorrent.override { guiSupport = false; }; + package = pkgs.unstable.qbittorrent.override {guiSupport = false;}; + user = "qbittorrent"; + group = "kah"; dataDir = "/nahar/qbittorrent"; downloadsDir = "/eru/media/qb/downloads"; webuiPort = 8456; @@ -331,9 +377,9 @@ in system = { incus = { enable = true; - preseed = import ./config/incus-preseed.nix { }; + preseed = import ./config/incus-preseed.nix {}; }; - motd.networkInterfaces = [ "bond0" ]; + motd.networkInterfaces = ["bond0"]; nfs.enable = true; zfs.enable = true; zfs.mountPoolsAtBoot = [ diff --git a/nixos/hosts/shadowfax/scripts/pushover-notify.sh b/nixos/hosts/shadowfax/scripts/pushover-notify.sh new file mode 100644 index 0000000..c2d87d1 --- /dev/null +++ b/nixos/hosts/shadowfax/scripts/pushover-notify.sh @@ -0,0 +1,89 @@ +# shellcheck disable=SC2154,2148 + +# User defined variables for pushover +PUSHOVER_USER_KEY="${PUSHOVER_USER_KEY:-required}" +PUSHOVER_TOKEN="${PUSHOVER_TOKEN:-required}" +PUSHOVER_PRIORITY="${PUSHOVER_PRIORITY:-"-2"}" +PUSHOVER_TITLE="${sonarr_eventtype} - Title unset" +PUSHOVER_MESSAGE="${sonarr_eventtype} - Message unset" +PUSHOVER_URL="${sonarr_eventtype} - url unset" +PUSHOVER_URL_TITLE="${sonarr_eventtype} - url title unset" + +if [[ "${sonarr_eventtype:-}" == "Test" ]]; then + PUSHOVER_PRIORITY="1" + printf -v PUSHOVER_TITLE \ + "Test Notification" + printf -v PUSHOVER_MESSAGE \ + "Howdy this is a test notification from %s" \ + "${sonarr_instancename:-Sonarr}" + printf -v PUSHOVER_URL \ + "%s" \ + "${sonarr_applicationurl:-localhost}" + printf -v PUSHOVER_URL_TITLE \ + "Open %s" \ + "${sonarr_instancename:-Sonarr}" +fi + +if [[ "${sonarr_eventtype:-}" == "Download" ]]; then + printf -v PUSHOVER_TITLE \ + "Episode %s" \ + "$([[ "${sonarr_isupgrade}" == "True" ]] && echo "Upgraded" || echo "Downloaded")" + printf -v PUSHOVER_MESSAGE \ + "%s (S%02dE%02d)\n%s\n\nQuality: %s\nClient: %s" \ + "${sonarr_series_title}" \ + "${sonarr_episodefile_seasonnumber}" \ + "${sonarr_episodefile_episodenumbers}" \ + "${sonarr_episodefile_episodetitles}" \ + "${sonarr_episodefile_quality:-Unknown}" \ + "${sonarr_download_client:-Unknown}" + printf -v PUSHOVER_URL \ + "%s/series/%s" \ + "${sonarr_applicationurl:-localhost}" \ + "${sonarr_series_titleslug}" + printf -v PUSHOVER_URL_TITLE \ + "View series in %s" \ + "${sonarr_instancename:-Sonarr}" +fi + +if [[ "${sonarr_eventtype:-}" == "ManualInteractionRequired" ]]; then + PUSHOVER_PRIORITY="1" + printf -v PUSHOVER_TITLE \ + "Episode import requires intervention" + printf -v PUSHOVER_MESSAGE \ + "%s\nClient: %s" \ + "${sonarr_series_title}" \ + "${sonarr_download_client:-Unknown}" + printf -v PUSHOVER_URL \ + "%s/activity/queue" \ + "${sonarr_applicationurl:-localhost}" + printf -v PUSHOVER_URL_TITLE \ + "View queue in %s" \ + "${sonarr_instancename:-Sonarr}" +fi + +json_data=$( + jo \ + token="${PUSHOVER_TOKEN}" \ + user="${PUSHOVER_USER_KEY}" \ + title="${PUSHOVER_TITLE}" \ + message="${PUSHOVER_MESSAGE}" \ + url="${PUSHOVER_URL}" \ + url_title="${PUSHOVER_URL_TITLE}" \ + priority="${PUSHOVER_PRIORITY}" \ + html="1" +) + +status_code=$( + curl \ + --silent \ + --write-out "%{http_code}" \ + --output /dev/null \ + --request POST \ + --header "Content-Type: application/json" \ + --data-binary "${json_data}" \ + "https://api.pushover.net/1/messages.json" +) + +printf "pushover notification returned with HTTP status code %s and payload: %s\n" \ + "${status_code}" \ + "$(echo "${json_data}" | jq --compact-output)" >&2 diff --git a/nixos/hosts/shadowfax/scripts/refresh-series.sh b/nixos/hosts/shadowfax/scripts/refresh-series.sh new file mode 100644 index 0000000..2074ac6 --- /dev/null +++ b/nixos/hosts/shadowfax/scripts/refresh-series.sh @@ -0,0 +1,19 @@ +# shellcheck disable=SC2154,2148 + +CURL_CMD=(curl -fsSL --header "X-Api-Key: ${SONARR__AUTH__APIKEY:-}") +SONARR_API_URL="http://localhost:${SONARR__SERVER__PORT:-}/api/v3" + +if [[ "${sonarr_eventtype:-}" == "Grab" ]]; then + tba=$("${CURL_CMD[@]}" "${SONARR_API_URL}/episode?seriesId=${sonarr_series_id:-}" | jq --raw-output ' + [.[] | select((.title == "TBA") or (.title == "TBD"))] | length + ') + + if ((tba > 0)); then + echo "INFO: Refreshing series ${sonarr_series_id:-} due to TBA/TBD episodes found" + "${CURL_CMD[@]}" \ + --request POST \ + --header "Content-Type: application/json" \ + --data-binary '{"name": "RefreshSeries", "seriesId": '"${sonarr_series_id:-}"'}' \ + "${SONARR_API_URL}/command" &>/dev/null + fi +fi diff --git a/nixos/hosts/shadowfax/secrets.sops.yaml b/nixos/hosts/shadowfax/secrets.sops.yaml index 92fd47a..e9f7c12 100644 --- a/nixos/hosts/shadowfax/secrets.sops.yaml +++ b/nixos/hosts/shadowfax/secrets.sops.yaml @@ -9,6 +9,8 @@ minio: ENC[AES256_GCM,data:IJTwUJOC84a5n798fTDlwRzVc8p5zRiccjdoNTPCNlls0RAyGllij postgres: host: ENC[AES256_GCM,data:fd0SCRhtJWA=,iv:KNSZ2iaCum+0AlDlgrH5VAVj7D1RRJSSFGEw0eYi5+4=,tag:Gs5HHPN9SeDm+CIzD7GPXQ==,type:str] port: ENC[AES256_GCM,data:Z0fHNA==,iv:otbEsYxhJ6/YR+A5oRx3Dwrqk6T6BL9OGka5yu1H+HA=,tag:T+KW8DaRJ8NN7k1mIMn6QA==,type:int] +pushover: + userKey: ENC[AES256_GCM,data:RYn9OCGaEgu/41kMolmqjYtr8FRmyEOvNStk+7Uz1A==,iv:L4pJJxGPhrmGSJdRDIP/OONibHvIP8KUdXwED29kTJ8=,tag:6TxYaUA6QA1NroBXhQHRlQ==,type:str] arr: prowlarr: apiKey: ENC[AES256_GCM,data:qxm2yp8ReuMgQ0155mKBAWickKusOaa/FeoIopj9l1Z3,iv:pAeDxK6CGap4fKU5xQ5hZR9It6/1uo27dKZBi5Bl3rc=,tag:HZl914AfFU4D5J7cDS3I1g==,type:str] @@ -24,6 +26,7 @@ arr: dbName: ENC[AES256_GCM,data:Um9YpALoU7qQfTo=,iv:q0IVjaxyaG8MWAxp43kZjHIBm6dWv37maykSfhAxe1M=,tag:NLqIikfWculCeuoRqPHc8Q==,type:str] user: ENC[AES256_GCM,data:Vd68IvZs,iv:DYT3PudE94JZZTZHzV8QgRYADtThZhxTjFJByLcZP1c=,tag:pX1ZNC+M9Jm+PlQ22BZMRw==,type:str] password: ENC[AES256_GCM,data:XOrycMom2utnefraGPoAq7xtP6yfSzTb8g==,iv:WQInK+bJuDNI9uN/GeQ2Fb1Mmlux6+lXwkGS1ZEh+kQ=,tag:DGqLerxomCVfVv15Gt3b8A==,type:str] + extraEnvVars: ENC[AES256_GCM,data:KnZSJ2YbNLawSzrj7syx0cfAFseHbgjGvjpB7yWajXfCIy+CV800z9YU2SVO2kV6b+9OrmyKKFFbM5ac4cWnc5Pcx8TUxfiAuL5RSi6ZTmUrZUA7Zqx5UDTHwXgvhDI=,iv:TX8sFk7uc1TYG/gkuA9plGZlhP25WuczEXd+QKsPi4c=,tag:zhVeZxrTgcv+Y2OP8I+k5g==,type:str] radarr: apiKey: ENC[AES256_GCM,data:Qcfzr12aftnS+b3pDHHnfOya1+vlyVaoNCPLzJ9xv5Pv,iv:9M33sfqZPzeghxmBtYk3LgsfbInC7sPSQGuYFJiydh4=,tag:lSmi6Do64sarG15q6+yuQw==,type:str] postgres: @@ -31,6 +34,9 @@ arr: dbName: ENC[AES256_GCM,data:zC4j0VJJpWWT0XY=,iv:ITupnWLgvI2wAPnkD826S77BMELDqRWZKax51SVkBgA=,tag:L7YXfoxAhi94ssBoE35Aug==,type:str] user: ENC[AES256_GCM,data:jaYUWAzQ,iv:ayEutHFPyZ7CN3inTqmgPmintR8qE8HfatvzCx7VXnA=,tag:3Ou0JRzpcihL0AWcC0pC5w==,type:str] password: ENC[AES256_GCM,data:XcS9H5L+ikA2KflepKrBHVlBjKwB0Vu8mw==,iv:lSpoEiCqOpP3p1T7bBH8F9YiSf2kwQQC+FQPuaKojnE=,tag:ScV/E6JeomQlfp35NIrh1g==,type:str] + extraEnvVars: ENC[AES256_GCM,data:hQlXQD4Zb3HnXfOZsX5PpxxyIzpYjqFletRiGRUWpICCEIcbsEK6WN8VtCaH+lpVqcVOpLUSSX1jILEwn4H483JyPk9EI04tIGBgq+svUOg7PZhc7zLllczMKN+BcdY=,iv:OyeAYXln8Dm1WvrrySkYXk+XC7kcwHFUSamIBdCTHRY=,tag:OGsR6IfBJF5Ki6VG15iyUw==,type:str] + unpackerr: + extraEnvVars: ENC[AES256_GCM,data:UT6HLaEKGEHggZx8Ict23OOLlRppErCnIDA16CleMFe33/IHyyp8El8aBNCq5A/1+NIGN5aZat2El562QAcZBVITa9ffmmtXqnDsheaRo+nDSPR5mGqh39uoKWIy2eSO5nv3rD0jN08MFYjxZNti/k0p0JIDMYN5shnVLiwO7krLs3Z6m+sZntg6euCWnHJMM2p3v38bffUzbZWrD1hEKaOUofOhTL0rDUiiysCawMZvJx6zXgfyO6DeUdwlYIxlg0mZ8SkmDRoFDPYrI40tIA+oSScJhJkDgoNPPJVEuGu6vVMPgqkAWUSucVGeiYVati2PsBJHn9wori2GWRTY0n7mjQKe8cz3nPIKQFWYLRWDZ9UBBvh05bYLa54+C4mGczFFPZra/DDoR2i9gzCXxjhRmt2Qs+g0RqefJTq5W2qQKRLj9PKFr02GuOY=,iv:pmOkkfFd4eGRCburRz6rgqqAFQJhPgjuUKn23ipLg3E=,tag:heZtewMOnnMxE5qSVEiI0Q==,type:str] sops: kms: [] gcp_kms: [] @@ -109,8 +115,8 @@ sops: aVlOSHhFb2I5UnYwVytyQzlWTXBDYUUKdQKilmfJ1F7UYKtQV9zV95FcRIK17p4M vGvu/pGJ32tH8xI7cNs9I5Hmg9c5wOam21W1FDk+VlJ/ClXqQzS0MA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-02-03T20:15:40Z" - mac: ENC[AES256_GCM,data:V7XiBqYsWk3kEoGeM6aOfZk6DaSwZAPc2kCt25n0y5eDKeLaxp6P/gwiquNjnvKmftRAbK0IK7TXxrg4+oEaJzLccAHqc5ch+4oJpWJIC6XlcksYc4JH8K1pzzPKHCW70w0sVghUmaNE/cNaglNgj+0JG9gseC1PKx9vyxFzfAM=,iv:McVZQTSvLugOd/2OMLIDfVuNDdHETF92TCkw7+o0sQg=,tag:peILXXpBChxEa1yRXVgsJw==,type:str] + lastmodified: "2025-02-04T04:28:14Z" + mac: ENC[AES256_GCM,data:7y38SzT51EOTx83lEJugW5XmsgGa00yemYIE5IRLasqwiSGSWHTt3iZy/2FLNXbFIqiz+O1K3xajstOF4ijvpYmP6Tu3rCh/4gxChqcokP6kxsI6b4nKp6ZkC/eZpoevFQmYHYqJU4b9iOQT9QZqdzwCIxOVRNZDAAc8u1SeBsg=,iv:7ni7qo6Xojs5MlOZBMLnnEKnDqdNDp9Ms/D9JMoRnm0=,tag:1/wqZh0igzhFyqdBxemntA==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.4 diff --git a/nixos/modules/nixos/services/default.nix b/nixos/modules/nixos/services/default.nix index 7bed208..cad1fa4 100644 --- a/nixos/modules/nixos/services/default.nix +++ b/nixos/modules/nixos/services/default.nix @@ -18,6 +18,7 @@ ./sanoid ./sonarr ./syncthing + ./unpackerr ./zfs-nightly-snap ]; } diff --git a/nixos/modules/nixos/services/prowlarr/default.nix b/nixos/modules/nixos/services/prowlarr/default.nix index 6e72a73..cd164cf 100644 --- a/nixos/modules/nixos/services/prowlarr/default.nix +++ b/nixos/modules/nixos/services/prowlarr/default.nix @@ -5,7 +5,8 @@ utils, ... }: -with lib; let +with lib; +let cfg = config.mySystem.services.prowlarr; dbOptions = { options = { @@ -50,11 +51,12 @@ with lib; let }; }; }; -in { +in +{ options.mySystem.services.prowlarr = { enable = mkEnableOption "Prowlarr"; - package = mkPackageOption pkgs "prowlarr" {}; + package = mkPackageOption pkgs "prowlarr" { }; user = mkOption { type = types.str; @@ -105,6 +107,22 @@ in { description = "API key for Prowlarr from a file (mutually exclusive with apiKey)"; }; + extraEnvVars = mkOption { + type = types.attrs; + default = { }; + example = { + MY_VAR = "my value"; + }; + description = "Extra environment variables for Prowlarr."; + }; + + extraEnvVarFile = mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/secrets/prowlarr_extra_env"; + description = "Extra environment file for Prowlarr."; + }; + db = mkOption { type = types.submodule dbOptions; example = { @@ -141,7 +159,7 @@ in { "network.target" "nss-lookup.target" ]; - wantedBy = ["multi-user.target"]; + wantedBy = [ "multi-user.target" ]; environment = lib.mkMerge [ { PROWLARR__APP__INSTANCENAME = "Prowlarr"; @@ -157,6 +175,7 @@ in { PROWLARR__POSTGRES__PORT = toString cfg.db.port; PROWLARR__POSTGRES__MAINDB = cfg.db.dbname; }) + cfg.extraEnvVars ]; serviceConfig = lib.mkMerge [ @@ -178,8 +197,8 @@ in { RestartSec = 5; } (lib.mkIf cfg.hardening { - CapabilityBoundingSet = [""]; - DeviceAllow = [""]; + CapabilityBoundingSet = [ "" ]; + DeviceAllow = [ "" ]; DevicePolicy = "closed"; LockPersonality = true; # Needs access to .Net CLR memory space. @@ -249,16 +268,19 @@ in { chown ${cfg.user}:${cfg.group} /run/prowlarr/secrets.env ''}"; - EnvironmentFile = ["-/run/prowlarr/secrets.env"]; + EnvironmentFile = ( + [ "-/run/prowlarr/secrets.env" ] + ++ lib.optional (cfg.extraEnvVarFile != null && cfg.extraEnvVarFile != "") cfg.extraEnvVarFile + ); }) ]; }; networking.firewall = mkIf cfg.openFirewall { - allowedTCPPorts = [cfg.port]; + allowedTCPPorts = [ cfg.port ]; }; - users.groups.${cfg.group} = {}; + users.groups.${cfg.group} = { }; users.users = mkIf (cfg.user == "prowlarr") { prowlarr = { inherit (cfg) group; diff --git a/nixos/modules/nixos/services/radarr/default.nix b/nixos/modules/nixos/services/radarr/default.nix index bc714d5..9497df4 100644 --- a/nixos/modules/nixos/services/radarr/default.nix +++ b/nixos/modules/nixos/services/radarr/default.nix @@ -125,6 +125,22 @@ in }; description = "Database settings for radarr."; }; + + extraEnvVars = mkOption { + type = types.attrs; + default = { }; + example = { + MY_VAR = "my value"; + }; + description = "Extra environment variables for radarr."; + }; + + extraEnvVarFile = mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/secrets/radarr_extra_env"; + description = "Extra environment file for Radarr."; + }; }; config = mkIf cfg.enable { @@ -169,6 +185,7 @@ in RADARR__POSTGRES__PORT = toString cfg.db.port; RADARR__POSTGRES__MAINDB = cfg.db.dbname; }) + cfg.extraEnvVars ]; serviceConfig = lib.mkMerge [ @@ -262,7 +279,10 @@ in chown ${cfg.user}:${cfg.group} /run/radarr/secrets.env ''}"; - EnvironmentFile = [ "-/run/radarr/secrets.env" ]; + EnvironmentFile = ( + [ "-/run/radarr/secrets.env" ] + ++ lib.optional (cfg.extraEnvVarFile != null && cfg.extraEnvVarFile != "") cfg.extraEnvVarFile + ); }) ]; }; diff --git a/nixos/modules/nixos/services/sonarr/default.nix b/nixos/modules/nixos/services/sonarr/default.nix index d5cfd80..a523ce9 100644 --- a/nixos/modules/nixos/services/sonarr/default.nix +++ b/nixos/modules/nixos/services/sonarr/default.nix @@ -113,6 +113,22 @@ in description = "API key for sonarr from a file (mutually exclusive with apiKey)"; }; + extraEnvVars = mkOption { + type = types.attrs; + default = { }; + example = { + MY_VAR = "my value"; + }; + description = "Extra environment variables for sonarr."; + }; + + extraEnvVarFile = mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + example = "/run/secrets/sonarr_extra_env"; + description = "Extra environment file for Sonarr."; + }; + db = mkOption { type = types.submodule dbOptions; example = { @@ -169,6 +185,7 @@ in SONARR__POSTGRES__PORT = toString cfg.db.port; SONARR__POSTGRES__MAINDB = cfg.db.dbname; }) + cfg.extraEnvVars ]; serviceConfig = lib.mkMerge [ @@ -263,7 +280,10 @@ in chown ${cfg.user}:${cfg.group} /run/sonarr/secrets.env ''}"; - EnvironmentFile = [ "-/run/sonarr/secrets.env" ]; + EnvironmentFile = ( + [ "-/run/sonarr/secrets.env" ] + ++ lib.optional (cfg.extraEnvVarFile != null && cfg.extraEnvVarFile != "") cfg.extraEnvVarFile + ); }) ]; }; diff --git a/nixos/modules/nixos/services/unpackerr/default.nix b/nixos/modules/nixos/services/unpackerr/default.nix new file mode 100644 index 0000000..144b978 --- /dev/null +++ b/nixos/modules/nixos/services/unpackerr/default.nix @@ -0,0 +1,75 @@ +{ + lib, + config, + pkgs, + ... +}: + +with lib; + +let + cfg = config.mySystem.services.unpackerr; +in +{ + options.mySystem.services.unpackerr = { + enable = mkEnableOption "Unpackerr"; + + package = mkPackageOption pkgs "unpackerr" { }; + + user = mkOption { + type = types.str; + default = "unpackerr"; + description = "User account under which Unpackerr runs."; + }; + + group = mkOption { + type = types.str; + default = "unpackerr"; + description = "Group under which Unpackerr runs."; + }; + + configFile = mkOption { + type = types.path; + default = "/var/lib/unpackerr/config.yaml"; + description = "Configuration file used by Unpackerr."; + }; + + extraEnvVarsFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/secrets/unpackerr_extra_env"; + description = "Extra environment file for Unpackerr."; + }; + }; + + config = mkIf cfg.enable { + users.groups.${cfg.group} = { }; + users.users = mkIf (cfg.user == "unpackerr") { + unpackerr = { + inherit (cfg) group; + isSystemUser = true; + }; + }; + + systemd.services.unpackerr = { + description = "Unpackerr service"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + ExecStart = lib.mkForce ( + lib.concatStringsSep " " [ + "${cfg.package}/bin/unpackerr" + "--config" + "${cfg.configFile}" + ] + ); + + EnvironmentFile = lib.optional ( + cfg.extraEnvVarsFile != null && cfg.extraEnvVarsFile != "" + ) cfg.extraEnvVarsFile; + }; + }; + }; +}