Merge pull request 'feat: multi-radarr' (#74) from multi-radarr into main
Reviewed-on: #74
This commit is contained in:
commit
77d0962f1c
4 changed files with 433 additions and 282 deletions
|
@ -91,41 +91,77 @@
|
||||||
restartUnits = [ "sonarr.service" ];
|
restartUnits = [ "sonarr.service" ];
|
||||||
};
|
};
|
||||||
# Radarr
|
# Radarr
|
||||||
"arr/radarr/apiKey" = {
|
"arr/radarr/1080p/apiKey" = {
|
||||||
sopsFile = ../secrets.sops.yaml;
|
sopsFile = ../secrets.sops.yaml;
|
||||||
owner = "radarr";
|
owner = "radarr";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
restartUnits = [ "radarr.service" ];
|
restartUnits = [ "radarr-movies1080p.service" ];
|
||||||
};
|
};
|
||||||
"arr/radarr/postgres/dbName" = {
|
"arr/radarr/1080p/postgres/dbName" = {
|
||||||
sopsFile = ../secrets.sops.yaml;
|
sopsFile = ../secrets.sops.yaml;
|
||||||
owner = "radarr";
|
owner = "radarr";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
restartUnits = [ "radarr.service" ];
|
restartUnits = [ "radarr-movies1080p.service" ];
|
||||||
};
|
};
|
||||||
"arr/radarr/postgres/user" = {
|
"arr/radarr/1080p/postgres/user" = {
|
||||||
sopsFile = ../secrets.sops.yaml;
|
sopsFile = ../secrets.sops.yaml;
|
||||||
owner = "radarr";
|
owner = "radarr";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
restartUnits = [ "radarr.service" ];
|
restartUnits = [ "radarr-movies1080p.service" ];
|
||||||
};
|
};
|
||||||
"arr/radarr/postgres/password" = {
|
"arr/radarr/1080p/postgres/password" = {
|
||||||
sopsFile = ../secrets.sops.yaml;
|
sopsFile = ../secrets.sops.yaml;
|
||||||
owner = "radarr";
|
owner = "radarr";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
restartUnits = [ "radarr.service" ];
|
restartUnits = [ "radarr-movies1080p.service" ];
|
||||||
};
|
};
|
||||||
"arr/radarr/postgres/host" = {
|
"arr/radarr/1080p/postgres/host" = {
|
||||||
sopsFile = ../secrets.sops.yaml;
|
sopsFile = ../secrets.sops.yaml;
|
||||||
owner = "radarr";
|
owner = "radarr";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
restartUnits = [ "radarr.service" ];
|
restartUnits = [ "radarr-movies1080p.service" ];
|
||||||
};
|
};
|
||||||
"arr/radarr/extraEnvVars" = {
|
"arr/radarr/1080p/extraEnvVars" = {
|
||||||
sopsFile = ../secrets.sops.yaml;
|
sopsFile = ../secrets.sops.yaml;
|
||||||
owner = "radarr";
|
owner = "radarr";
|
||||||
mode = "400";
|
mode = "400";
|
||||||
restartUnits = [ "radarr.service" ];
|
restartUnits = [ "radarr-movies1080p.service" ];
|
||||||
|
};
|
||||||
|
"arr/radarr/anime/apiKey" = {
|
||||||
|
sopsFile = ../secrets.sops.yaml;
|
||||||
|
owner = "radarr";
|
||||||
|
mode = "400";
|
||||||
|
restartUnits = [ "radarr-anime.service" ];
|
||||||
|
};
|
||||||
|
"arr/radarr/anime/postgres/dbName" = {
|
||||||
|
sopsFile = ../secrets.sops.yaml;
|
||||||
|
owner = "radarr";
|
||||||
|
mode = "400";
|
||||||
|
restartUnits = [ "radarr-anime.service" ];
|
||||||
|
};
|
||||||
|
"arr/radarr/anime/postgres/user" = {
|
||||||
|
sopsFile = ../secrets.sops.yaml;
|
||||||
|
owner = "radarr";
|
||||||
|
mode = "400";
|
||||||
|
restartUnits = [ "radarr-anime.service" ];
|
||||||
|
};
|
||||||
|
"arr/radarr/anime/postgres/password" = {
|
||||||
|
sopsFile = ../secrets.sops.yaml;
|
||||||
|
owner = "radarr";
|
||||||
|
mode = "400";
|
||||||
|
restartUnits = [ "radarr-anime.service" ];
|
||||||
|
};
|
||||||
|
"arr/radarr/anime/postgres/host" = {
|
||||||
|
sopsFile = ../secrets.sops.yaml;
|
||||||
|
owner = "radarr";
|
||||||
|
mode = "400";
|
||||||
|
restartUnits = [ "radarr-anime.service" ];
|
||||||
|
};
|
||||||
|
"arr/radarr/anime/extraEnvVars" = {
|
||||||
|
sopsFile = ../secrets.sops.yaml;
|
||||||
|
owner = "radarr";
|
||||||
|
mode = "400";
|
||||||
|
restartUnits = [ "radarr-anime.service" ];
|
||||||
};
|
};
|
||||||
# Unpackerr
|
# Unpackerr
|
||||||
"arr/unpackerr/extraEnvVars" = {
|
"arr/unpackerr/extraEnvVars" = {
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
inputs,
|
inputs,
|
||||||
pkgs,
|
pkgs,
|
||||||
...
|
...
|
||||||
}: let
|
}:
|
||||||
sanoidConfig = import ./config/sanoid.nix {};
|
let
|
||||||
|
sanoidConfig = import ./config/sanoid.nix { };
|
||||||
disks = import ./config/disks.nix;
|
disks = import ./config/disks.nix;
|
||||||
smartdDevices = map (device: {inherit device;}) disks;
|
smartdDevices = map (device: { inherit device; }) disks;
|
||||||
pushoverNotify = pkgs.writeShellApplication {
|
pushoverNotify = pkgs.writeShellApplication {
|
||||||
name = "pushover-notify";
|
name = "pushover-notify";
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@
|
||||||
jq
|
jq
|
||||||
];
|
];
|
||||||
|
|
||||||
excludeShellChecks = ["SC2154"];
|
excludeShellChecks = [ "SC2154" ];
|
||||||
|
|
||||||
text = ''
|
text = ''
|
||||||
${builtins.readFile ./scripts/pushover-notify.sh}
|
${builtins.readFile ./scripts/pushover-notify.sh}
|
||||||
|
@ -31,28 +32,29 @@
|
||||||
jq
|
jq
|
||||||
];
|
];
|
||||||
|
|
||||||
excludeShellChecks = ["SC2154"];
|
excludeShellChecks = [ "SC2154" ];
|
||||||
|
|
||||||
text = ''
|
text = ''
|
||||||
${builtins.readFile ./scripts/refresh-series.sh}
|
${builtins.readFile ./scripts/refresh-series.sh}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
in {
|
in
|
||||||
|
{
|
||||||
imports = [
|
imports = [
|
||||||
inputs.disko.nixosModules.disko
|
inputs.disko.nixosModules.disko
|
||||||
(import ../../profiles/disko-nixos.nix {
|
(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
|
inputs.nix-minecraft.nixosModules.minecraft-servers
|
||||||
];
|
];
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
initrd = {
|
initrd = {
|
||||||
kernelModules = ["nfs"];
|
kernelModules = [ "nfs" ];
|
||||||
supportedFilesystems = ["nfs"];
|
supportedFilesystems = [ "nfs" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
binfmt.emulatedSystems = ["aarch64-linux"]; # Enabled for arm compilation
|
binfmt.emulatedSystems = [ "aarch64-linux" ]; # Enabled for arm compilation
|
||||||
|
|
||||||
kernelModules = [
|
kernelModules = [
|
||||||
"vfio"
|
"vfio"
|
||||||
|
@ -60,11 +62,11 @@ in {
|
||||||
"vfio_pci"
|
"vfio_pci"
|
||||||
"vfio_virqfd"
|
"vfio_virqfd"
|
||||||
];
|
];
|
||||||
extraModulePackages = [];
|
extraModulePackages = [ ];
|
||||||
kernelParams = ["zfs.zfs_arc_max=107374182400"]; # 100GB
|
kernelParams = [ "zfs.zfs_arc_max=107374182400" ]; # 100GB
|
||||||
};
|
};
|
||||||
|
|
||||||
swapDevices = [];
|
swapDevices = [ ];
|
||||||
|
|
||||||
hardware = {
|
hardware = {
|
||||||
cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
@ -74,7 +76,7 @@ in {
|
||||||
nvidia-container-toolkit.enable = true;
|
nvidia-container-toolkit.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
users.users.root.openssh.authorizedKeys.keys = [];
|
users.users.root.openssh.authorizedKeys.keys = [ ];
|
||||||
# Network settings
|
# Network settings
|
||||||
networking = {
|
networking = {
|
||||||
hostName = "shadowfax";
|
hostName = "shadowfax";
|
||||||
|
@ -167,7 +169,7 @@ in {
|
||||||
# Minio
|
# Minio
|
||||||
minio = {
|
minio = {
|
||||||
enable = true;
|
enable = true;
|
||||||
dataDir = ["/eru/minio"];
|
dataDir = [ "/eru/minio" ];
|
||||||
rootCredentialsFile = config.sops.secrets."minio".path;
|
rootCredentialsFile = config.sops.secrets."minio".path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,7 +196,7 @@ in {
|
||||||
# Soft Serve - SSH git server
|
# Soft Serve - SSH git server
|
||||||
soft-serve = {
|
soft-serve = {
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = import ./config/soft-serve.nix {};
|
settings = import ./config/soft-serve.nix { };
|
||||||
};
|
};
|
||||||
|
|
||||||
sunshine = {
|
sunshine = {
|
||||||
|
@ -214,7 +216,7 @@ in {
|
||||||
# VSCode Compatibility Settings
|
# VSCode Compatibility Settings
|
||||||
vscode-server.enable = true;
|
vscode-server.enable = true;
|
||||||
|
|
||||||
xserver.videoDrivers = ["nvidia"];
|
xserver.videoDrivers = [ "nvidia" ];
|
||||||
greetd = {
|
greetd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
vt = 3;
|
vt = 3;
|
||||||
|
@ -228,7 +230,7 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
# sops
|
# sops
|
||||||
sops = import ./config/sops-secrets.nix {};
|
sops = import ./config/sops-secrets.nix { };
|
||||||
|
|
||||||
# System settings and services.
|
# System settings and services.
|
||||||
mySystem = {
|
mySystem = {
|
||||||
|
@ -267,22 +269,49 @@ in {
|
||||||
# Radarr
|
# Radarr
|
||||||
radarr = {
|
radarr = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.unstable.radarr;
|
instances = {
|
||||||
dataDir = "/nahar/radarr";
|
movies1080p = {
|
||||||
extraEnvVarFile = config.sops.secrets."arr/radarr/extraEnvVars".path;
|
enable = true;
|
||||||
moviesDir = "/moria/media/Movies";
|
package = pkgs.unstable.radarr;
|
||||||
user = "radarr";
|
dataDir = "/nahar/radarr/1080p";
|
||||||
group = "kah";
|
extraEnvVarFile = config.sops.secrets."arr/radarr/1080p/extraEnvVars".path;
|
||||||
port = 7878;
|
moviesDir = "/moria/media/Movies";
|
||||||
openFirewall = true;
|
user = "radarr";
|
||||||
hardening = true;
|
group = "kah";
|
||||||
apiKeyFile = config.sops.secrets."arr/radarr/apiKey".path;
|
port = 7878;
|
||||||
db = {
|
openFirewall = true;
|
||||||
enable = true;
|
hardening = true;
|
||||||
hostFile = config.sops.secrets."arr/radarr/postgres/host".path;
|
apiKeyFile = config.sops.secrets."arr/radarr/1080p/apiKey".path;
|
||||||
port = 5432;
|
db = {
|
||||||
userFile = config.sops.secrets."arr/radarr/postgres/user".path;
|
enable = true;
|
||||||
passwordFile = config.sops.secrets."arr/radarr/postgres/password".path;
|
hostFile = config.sops.secrets."arr/radarr/1080p/postgres/host".path;
|
||||||
|
port = 5432;
|
||||||
|
dbname = "radarr_main";
|
||||||
|
userFile = config.sops.secrets."arr/radarr/1080p/postgres/user".path;
|
||||||
|
passwordFile = config.sops.secrets."arr/radarr/1080p/postgres/password".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
moviesAnime = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.unstable.radarr;
|
||||||
|
dataDir = "/nahar/radarr/anime";
|
||||||
|
extraEnvVarFile = config.sops.secrets."arr/radarr/anime/extraEnvVars".path;
|
||||||
|
moviesDir = "/moria/media/Anime/Movies";
|
||||||
|
user = "radarr";
|
||||||
|
group = "kah";
|
||||||
|
port = 7879;
|
||||||
|
openFirewall = true;
|
||||||
|
hardening = true;
|
||||||
|
apiKeyFile = config.sops.secrets."arr/radarr/anime/apiKey".path;
|
||||||
|
db = {
|
||||||
|
enable = true;
|
||||||
|
hostFile = config.sops.secrets."arr/radarr/anime/postgres/host".path;
|
||||||
|
port = 5432;
|
||||||
|
dbname = "radarr_anime";
|
||||||
|
userFile = config.sops.secrets."arr/radarr/anime/postgres/user".path;
|
||||||
|
passwordFile = config.sops.secrets."arr/radarr/anime/postgres/password".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
# Sonarr
|
# Sonarr
|
||||||
|
@ -354,7 +383,7 @@ in {
|
||||||
# qBittorrent
|
# qBittorrent
|
||||||
qbittorrent = {
|
qbittorrent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.unstable.qbittorrent.override {guiSupport = false;};
|
package = pkgs.unstable.qbittorrent.override { guiSupport = false; };
|
||||||
user = "qbittorrent";
|
user = "qbittorrent";
|
||||||
group = "kah";
|
group = "kah";
|
||||||
dataDir = "/nahar/qbittorrent";
|
dataDir = "/nahar/qbittorrent";
|
||||||
|
@ -378,9 +407,9 @@ in {
|
||||||
system = {
|
system = {
|
||||||
incus = {
|
incus = {
|
||||||
enable = true;
|
enable = true;
|
||||||
preseed = import ./config/incus-preseed.nix {};
|
preseed = import ./config/incus-preseed.nix { };
|
||||||
};
|
};
|
||||||
motd.networkInterfaces = ["bond0"];
|
motd.networkInterfaces = [ "bond0" ];
|
||||||
nfs.enable = true;
|
nfs.enable = true;
|
||||||
zfs.enable = true;
|
zfs.enable = true;
|
||||||
zfs.mountPoolsAtBoot = [
|
zfs.mountPoolsAtBoot = [
|
||||||
|
|
|
@ -28,13 +28,22 @@ arr:
|
||||||
password: ENC[AES256_GCM,data:XOrycMom2utnefraGPoAq7xtP6yfSzTb8g==,iv:WQInK+bJuDNI9uN/GeQ2Fb1Mmlux6+lXwkGS1ZEh+kQ=,tag:DGqLerxomCVfVv15Gt3b8A==,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]
|
extraEnvVars: ENC[AES256_GCM,data:KnZSJ2YbNLawSzrj7syx0cfAFseHbgjGvjpB7yWajXfCIy+CV800z9YU2SVO2kV6b+9OrmyKKFFbM5ac4cWnc5Pcx8TUxfiAuL5RSi6ZTmUrZUA7Zqx5UDTHwXgvhDI=,iv:TX8sFk7uc1TYG/gkuA9plGZlhP25WuczEXd+QKsPi4c=,tag:zhVeZxrTgcv+Y2OP8I+k5g==,type:str]
|
||||||
radarr:
|
radarr:
|
||||||
apiKey: ENC[AES256_GCM,data:Qcfzr12aftnS+b3pDHHnfOya1+vlyVaoNCPLzJ9xv5Pv,iv:9M33sfqZPzeghxmBtYk3LgsfbInC7sPSQGuYFJiydh4=,tag:lSmi6Do64sarG15q6+yuQw==,type:str]
|
1080p:
|
||||||
postgres:
|
apiKey: ENC[AES256_GCM,data:NVIa3nK4/QxZF1/peKei9Qsxn2AjRiBnBdr2N08QiXhi,iv:h/Rb38FCF8auMCTT+Cuj/i8YAeavntwbbJEA9LwDYUY=,tag:OwAQy76GjIrY9/126zExdA==,type:str]
|
||||||
host: ENC[AES256_GCM,data:mYFhyUYIqp8=,iv:Cj03GOR58PWv3HWXRx0/D5tZ2oObejtIVuQcTcHGkuw=,tag:9K2asujaqi4/Qbozb18Ghg==,type:str]
|
postgres:
|
||||||
dbName: ENC[AES256_GCM,data:zC4j0VJJpWWT0XY=,iv:ITupnWLgvI2wAPnkD826S77BMELDqRWZKax51SVkBgA=,tag:L7YXfoxAhi94ssBoE35Aug==,type:str]
|
host: ENC[AES256_GCM,data:bycrytLkcdI=,iv:zfsSP+uoVpvG2HXydCXT+yfMc5GadjG8qo+4ld+rdjk=,tag:cXtYTFg27hS9Idn3UjUn1A==,type:str]
|
||||||
user: ENC[AES256_GCM,data:jaYUWAzQ,iv:ayEutHFPyZ7CN3inTqmgPmintR8qE8HfatvzCx7VXnA=,tag:3Ou0JRzpcihL0AWcC0pC5w==,type:str]
|
dbName: ENC[AES256_GCM,data:pjvSoLQ/TUdd6Y0=,iv:TsThUHuF9Mm1fuGYcEh/GanaDGuoSJxPt7LVRJHSFAo=,tag:tMIdTPSaNE4hOh97lck6DQ==,type:str]
|
||||||
password: ENC[AES256_GCM,data:XcS9H5L+ikA2KflepKrBHVlBjKwB0Vu8mw==,iv:lSpoEiCqOpP3p1T7bBH8F9YiSf2kwQQC+FQPuaKojnE=,tag:ScV/E6JeomQlfp35NIrh1g==,type:str]
|
user: ENC[AES256_GCM,data:0QFQsAfq,iv:+qtq/BhC26fdW9rXlbZFf6fQCOV+UsP1Y9cNMUtn5+w=,tag:WBg4ruYa7t+8d8iHjjPJ1g==,type:str]
|
||||||
extraEnvVars: ENC[AES256_GCM,data:hQlXQD4Zb3HnXfOZsX5PpxxyIzpYjqFletRiGRUWpICCEIcbsEK6WN8VtCaH+lpVqcVOpLUSSX1jILEwn4H483JyPk9EI04tIGBgq+svUOg7PZhc7zLllczMKN+BcdY=,iv:OyeAYXln8Dm1WvrrySkYXk+XC7kcwHFUSamIBdCTHRY=,tag:OGsR6IfBJF5Ki6VG15iyUw==,type:str]
|
password: ENC[AES256_GCM,data:TvGQsShraVE70JoHkk4PWkoeElu+dn882w==,iv:oQ15XrRCLUZ6XWSifB9hGF+wYActgDE9NEqly+LTTFA=,tag:kUbn5dKq9jU4Xl1+mRI2Zw==,type:str]
|
||||||
|
extraEnvVars: ENC[AES256_GCM,data:4E1NFQZOrH7sBGnJus7+VZLTWnzif1Asr+mCeaXorsfO8nJpA14HjQ9diAqPuabTlUsl4vMznFmKjdAFCvuRz9p7xfq96qmJKN3oTKuVaz6SlQbXKcfCeldn2E2EA2k=,iv:CVaiTGR0WpcCNvDpD202P4dHqEjX9xqJEVz0usEeANY=,tag:FRz7t5wV2TePakxmyBkb1Q==,type:str]
|
||||||
|
anime:
|
||||||
|
apiKey: ENC[AES256_GCM,data:7Z59sJCKBmayd1J71+C72IdoeNlU71jcJS885bUwc+g8,iv:0Uav84UAanmZvvZfJJNoDmvyKY068L8+ONnVGWmldSI=,tag:WYQvccwlm/Y8S2ynPkEPjA==,type:str]
|
||||||
|
postgres:
|
||||||
|
host: ENC[AES256_GCM,data:EL6Qzm8r/XQ=,iv:Gz099lg7zDRrIf7i2kOb+MSXGwHazTtcnBbCmciVCHE=,tag:l2Lqd7dDeRZYzflhK9/Kdg==,type:str]
|
||||||
|
dbName: ENC[AES256_GCM,data:9MJ6UcVlLPN+hI4=,iv:AwCdIJ1KwThbUVGM759m0GVWh3yf3anBHdsfdIjVWP4=,tag:7kUUSTNpt/rOtYHkDRlKxA==,type:str]
|
||||||
|
user: ENC[AES256_GCM,data:QE+Lr0L0ad3oufG4,iv:WCTkwhN9FjibXlyPqY7oDjSByXn6Exma/VDsE3ju/FE=,tag:orFBsxd/ETSaiFC1KNsO0A==,type:str]
|
||||||
|
password: ENC[AES256_GCM,data:3rYBq3cosu962m/FZIc/WZogr+BZxQ==,iv:dK/IDKYz3NKeAE7PV/f+qRtSu3veg20B6+6gZmaD/eg=,tag:9k0+zrcWC6i6YjwJkMYkzA==,type:str]
|
||||||
|
extraEnvVars: ENC[AES256_GCM,data:HAGHXI14CFx/CXbpHGn1MQQeRmMO9zzsnHEJrgTfho96XPtoKJQj+b3h7VNVkkHAifjuMzbKb0BM8qrtAIjssWuQUrWChxgHBg3OWodsJkstYplB0RYIun5RorzHaNY=,iv:3nW9806ciMdblFphEi9zK8kkIB8r01eF/167vYq177w=,tag:7aPJ63Wl+SGzWCBXuitgmA==,type:str]
|
||||||
unpackerr:
|
unpackerr:
|
||||||
extraEnvVars: ENC[AES256_GCM,data:UT6HLaEKGEHggZx8Ict23OOLlRppErCnIDA16CleMFe33/IHyyp8El8aBNCq5A/1+NIGN5aZat2El562QAcZBVITa9ffmmtXqnDsheaRo+nDSPR5mGqh39uoKWIy2eSO5nv3rD0jN08MFYjxZNti/k0p0JIDMYN5shnVLiwO7krLs3Z6m+sZntg6euCWnHJMM2p3v38bffUzbZWrD1hEKaOUofOhTL0rDUiiysCawMZvJx6zXgfyO6DeUdwlYIxlg0mZ8SkmDRoFDPYrI40tIA+oSScJhJkDgoNPPJVEuGu6vVMPgqkAWUSucVGeiYVati2PsBJHn9wori2GWRTY0n7mjQKe8cz3nPIKQFWYLRWDZ9UBBvh05bYLa54+C4mGczFFPZra/DDoR2i9gzCXxjhRmt2Qs+g0RqefJTq5W2qQKRLj9PKFr02GuOY=,iv:pmOkkfFd4eGRCburRz6rgqqAFQJhPgjuUKn23ipLg3E=,tag:heZtewMOnnMxE5qSVEiI0Q==,type:str]
|
extraEnvVars: ENC[AES256_GCM,data:UT6HLaEKGEHggZx8Ict23OOLlRppErCnIDA16CleMFe33/IHyyp8El8aBNCq5A/1+NIGN5aZat2El562QAcZBVITa9ffmmtXqnDsheaRo+nDSPR5mGqh39uoKWIy2eSO5nv3rD0jN08MFYjxZNti/k0p0JIDMYN5shnVLiwO7krLs3Z6m+sZntg6euCWnHJMM2p3v38bffUzbZWrD1hEKaOUofOhTL0rDUiiysCawMZvJx6zXgfyO6DeUdwlYIxlg0mZ8SkmDRoFDPYrI40tIA+oSScJhJkDgoNPPJVEuGu6vVMPgqkAWUSucVGeiYVati2PsBJHn9wori2GWRTY0n7mjQKe8cz3nPIKQFWYLRWDZ9UBBvh05bYLa54+C4mGczFFPZra/DDoR2i9gzCXxjhRmt2Qs+g0RqefJTq5W2qQKRLj9PKFr02GuOY=,iv:pmOkkfFd4eGRCburRz6rgqqAFQJhPgjuUKn23ipLg3E=,tag:heZtewMOnnMxE5qSVEiI0Q==,type:str]
|
||||||
sops:
|
sops:
|
||||||
|
@ -115,8 +124,8 @@ sops:
|
||||||
aVlOSHhFb2I5UnYwVytyQzlWTXBDYUUKdQKilmfJ1F7UYKtQV9zV95FcRIK17p4M
|
aVlOSHhFb2I5UnYwVytyQzlWTXBDYUUKdQKilmfJ1F7UYKtQV9zV95FcRIK17p4M
|
||||||
vGvu/pGJ32tH8xI7cNs9I5Hmg9c5wOam21W1FDk+VlJ/ClXqQzS0MA==
|
vGvu/pGJ32tH8xI7cNs9I5Hmg9c5wOam21W1FDk+VlJ/ClXqQzS0MA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-02-04T04:28:14Z"
|
lastmodified: "2025-02-10T04:49:46Z"
|
||||||
mac: ENC[AES256_GCM,data:7y38SzT51EOTx83lEJugW5XmsgGa00yemYIE5IRLasqwiSGSWHTt3iZy/2FLNXbFIqiz+O1K3xajstOF4ijvpYmP6Tu3rCh/4gxChqcokP6kxsI6b4nKp6ZkC/eZpoevFQmYHYqJU4b9iOQT9QZqdzwCIxOVRNZDAAc8u1SeBsg=,iv:7ni7qo6Xojs5MlOZBMLnnEKnDqdNDp9Ms/D9JMoRnm0=,tag:1/wqZh0igzhFyqdBxemntA==,type:str]
|
mac: ENC[AES256_GCM,data:wT82lve5wNbxXUgcw3EZkOrsLFOmtriJtSNtpcfcH2KYkFEZTyzYCO10EBMrm1FjJxJFmhtde9f+CkSkT5ypjP6Ou4TGn9nP0jOlCyLxYyQkv7Lr31aEF8d2Q0NDjSHePW4YUiY88YrOX8shWYFVtNoZSonyCv8G6lwGVIsZzi4=,iv:MkHiwV5qRBE3LfTt0WHV56LWAeTEcRlux4xIf90R3AU=,tag:qUgCaPLa+W/pZ8uM1Gw7Xw==,type:str]
|
||||||
pgp: []
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.9.4
|
version: 3.9.4
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
utils,
|
utils,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
with lib; let
|
with lib;
|
||||||
|
let
|
||||||
cfg = config.mySystem.services.radarr;
|
cfg = config.mySystem.services.radarr;
|
||||||
dbOptions = {
|
dbOptions = {
|
||||||
options = {
|
options = {
|
||||||
|
@ -50,253 +51,329 @@ with lib; let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
|
||||||
|
# Function to create instance-specific configuration
|
||||||
|
mkRadarrInstance = name: instanceCfg: {
|
||||||
|
|
||||||
|
systemd.services."radarr-${name}" = {
|
||||||
|
description = "Radarr (${name})";
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = mkIf instanceCfg.openFirewall {
|
||||||
|
allowedTCPPorts = [ instanceCfg.port ];
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.${instanceCfg.group} = { };
|
||||||
|
users.users = mkIf (instanceCfg.user == "radarr") {
|
||||||
|
radarr = {
|
||||||
|
inherit (instanceCfg) group;
|
||||||
|
isSystemUser = true;
|
||||||
|
home = instanceCfg.dataDir;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
options.mySystem.services.radarr = {
|
options.mySystem.services.radarr = {
|
||||||
enable = mkEnableOption "Radarr";
|
enable = mkEnableOption "Radarr (global)";
|
||||||
|
|
||||||
package = mkPackageOption pkgs "Radarr" {};
|
instances = mkOption {
|
||||||
|
type = types.attrsOf (
|
||||||
|
types.submodule (
|
||||||
|
{ name, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
enable = mkEnableOption "Radarr (instance)";
|
||||||
|
|
||||||
user = mkOption {
|
package = mkPackageOption pkgs "Radarr" { };
|
||||||
type = types.str;
|
|
||||||
default = "radarr";
|
|
||||||
description = "User account under which radarr runs.";
|
|
||||||
};
|
|
||||||
|
|
||||||
group = mkOption {
|
user = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "radarr";
|
default = "radarr";
|
||||||
description = "Group under which radarr runs.";
|
description = "User account under which radarr runs.";
|
||||||
};
|
};
|
||||||
|
|
||||||
dataDir = mkOption {
|
group = mkOption {
|
||||||
type = types.path;
|
type = types.str;
|
||||||
default = "/var/lib/radarr";
|
default = "radarr";
|
||||||
description = "Storage directory for radarr data";
|
description = "Group under which radarr runs.";
|
||||||
};
|
};
|
||||||
|
|
||||||
moviesDir = mkOption {
|
dataDir = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
default = "/mnt/media/movies";
|
default = "/var/lib/radarr/${name}";
|
||||||
description = "Directory where movies are stored";
|
description = "Storage directory for radarr data";
|
||||||
};
|
};
|
||||||
|
|
||||||
port = mkOption {
|
moviesDir = mkOption {
|
||||||
type = types.port;
|
type = types.path;
|
||||||
default = 7878;
|
default = "/mnt/media/movies";
|
||||||
description = "Port for radarr web interface";
|
description = "Directory where movies are stored";
|
||||||
};
|
};
|
||||||
|
|
||||||
openFirewall = mkOption {
|
port = mkOption {
|
||||||
type = types.bool;
|
type = types.port;
|
||||||
default = false;
|
default = 7878;
|
||||||
description = "Open firewall ports for radarr";
|
description = "Port for radarr web interface";
|
||||||
};
|
};
|
||||||
|
|
||||||
hardening = mkOption {
|
openFirewall = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = false;
|
||||||
description = "Enable security hardening features";
|
description = "Open firewall ports for radarr";
|
||||||
};
|
};
|
||||||
|
|
||||||
apiKey = mkOption {
|
hardening = mkOption {
|
||||||
type = types.str;
|
type = types.bool;
|
||||||
default = "";
|
default = true;
|
||||||
example = "abc123";
|
description = "Enable security hardening features";
|
||||||
description = "Direct API key for radarr (mutually exclusive with apiKeyFile)";
|
};
|
||||||
};
|
|
||||||
|
|
||||||
apiKeyFile = mkOption {
|
apiKey = mkOption {
|
||||||
type = types.path;
|
type = types.str;
|
||||||
default = "/run/secrets/radarr_api_key";
|
default = "";
|
||||||
description = "API key for radarr from a file (mutually exclusive with apiKey)";
|
example = "abc123";
|
||||||
};
|
description = "Direct API key for radarr (mutually exclusive with apiKeyFile)";
|
||||||
|
};
|
||||||
|
|
||||||
db = mkOption {
|
apiKeyFile = mkOption {
|
||||||
type = types.submodule dbOptions;
|
type = types.path;
|
||||||
example = {
|
default = "/run/secrets/radarr_api_key";
|
||||||
enable = true;
|
description = "API key for radarr from a file (mutually exclusive with apiKey)";
|
||||||
host = "10.5.0.5"; # or use hostFile
|
};
|
||||||
port = "5432";
|
|
||||||
user = "radarr"; # or userFile
|
|
||||||
passwordFile = "/run/secrets/radarr_db_password";
|
|
||||||
dbname = "radarr_main";
|
|
||||||
};
|
|
||||||
description = "Database settings for radarr.";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraEnvVars = mkOption {
|
db = mkOption {
|
||||||
type = types.attrs;
|
type = types.submodule dbOptions;
|
||||||
default = {};
|
example = {
|
||||||
example = {
|
enable = true;
|
||||||
MY_VAR = "my value";
|
host = "10.5.0.5"; # or use hostFile
|
||||||
};
|
port = "5432";
|
||||||
description = "Extra environment variables for radarr.";
|
user = "radarr"; # or userFile
|
||||||
};
|
passwordFile = "/run/secrets/radarr_db_password";
|
||||||
|
dbname = "radarr_main";
|
||||||
|
};
|
||||||
|
description = "Database settings for radarr.";
|
||||||
|
};
|
||||||
|
|
||||||
extraEnvVarFile = mkOption {
|
extraEnvVars = mkOption {
|
||||||
type = lib.types.nullOr lib.types.path;
|
type = types.attrs;
|
||||||
default = null;
|
default = { };
|
||||||
example = "/run/secrets/radarr_extra_env";
|
example = {
|
||||||
description = "Extra environment file for Radarr.";
|
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.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
default = { };
|
||||||
|
description = "Radarr instance configurations.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
assertions = [
|
# Add assertions for all instances
|
||||||
{
|
assertions = flatten (
|
||||||
assertion = !(cfg.db.host != "" && cfg.db.hostFile != "");
|
mapAttrsToList (
|
||||||
message = "Specify either a direct database host via db.host or a file via db.hostFile (leave direct host empty).";
|
name: instanceCfg:
|
||||||
}
|
if instanceCfg.enable then
|
||||||
{
|
[
|
||||||
assertion = !(cfg.db.user != "radarr" && cfg.db.userFile != "");
|
{
|
||||||
message = "Specify either a direct database user via db.user or a file via db.userFile.";
|
assertion = !(instanceCfg.db.host != "" && instanceCfg.db.hostFile != "");
|
||||||
}
|
message = "Specify either a direct database host via db.host or a file via db.hostFile (leave direct host empty).";
|
||||||
{
|
|
||||||
assertion = !(cfg.apiKey != "" && cfg.apiKeyFile != "");
|
|
||||||
message = "Specify either a direct API key via apiKey or a file via apiKeyFile (leave direct API key empty).";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
|
||||||
"d ${cfg.dataDir} 0775 ${cfg.user} ${cfg.group}"
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.services.radarr = {
|
|
||||||
description = "Radarr";
|
|
||||||
after = [
|
|
||||||
"network.target"
|
|
||||||
"nss-lookup.target"
|
|
||||||
];
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
environment = lib.mkMerge [
|
|
||||||
{
|
|
||||||
RADARR__APP__INSTANCENAME = "Radarr";
|
|
||||||
RADARR__APP__THEME = "dark";
|
|
||||||
RADARR__AUTH__METHOD = "External";
|
|
||||||
RADARR__AUTH__REQUIRED = "DisabledForLocalAddresses";
|
|
||||||
RADARR__LOG__DBENABLED = "False";
|
|
||||||
RADARR__LOG__LEVEL = "info";
|
|
||||||
RADARR__SERVER__PORT = toString cfg.port;
|
|
||||||
RADARR__UPDATE__BRANCH = "develop";
|
|
||||||
}
|
|
||||||
(lib.mkIf cfg.db.enable {
|
|
||||||
RADARR__POSTGRES__PORT = toString cfg.db.port;
|
|
||||||
RADARR__POSTGRES__MAINDB = cfg.db.dbname;
|
|
||||||
})
|
|
||||||
cfg.extraEnvVars
|
|
||||||
];
|
|
||||||
|
|
||||||
serviceConfig = lib.mkMerge [
|
|
||||||
{
|
|
||||||
Type = "simple";
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
ExecStart = utils.escapeSystemdExecArgs [
|
|
||||||
(lib.getExe cfg.package)
|
|
||||||
"-nobrowser"
|
|
||||||
"-data=${cfg.dataDir}"
|
|
||||||
"-port=${toString cfg.port}"
|
|
||||||
];
|
|
||||||
WorkingDirectory = cfg.dataDir;
|
|
||||||
RuntimeDirectory = "radarr";
|
|
||||||
LogsDirectory = "radarr";
|
|
||||||
RuntimeDirectoryMode = "0750";
|
|
||||||
Restart = "on-failure";
|
|
||||||
RestartSec = 5;
|
|
||||||
}
|
|
||||||
(lib.mkIf cfg.hardening {
|
|
||||||
CapabilityBoundingSet = [""];
|
|
||||||
DeviceAllow = [""];
|
|
||||||
DevicePolicy = "closed";
|
|
||||||
LockPersonality = true;
|
|
||||||
# Needs access to .Net CLR memory space.
|
|
||||||
MemoryDenyWriteExecute = false;
|
|
||||||
NoNewPrivileges = true;
|
|
||||||
PrivateDevices = true;
|
|
||||||
PrivateTmp = true;
|
|
||||||
ProtectControlGroups = true;
|
|
||||||
ProtectHome = "read-only";
|
|
||||||
ProtectKernelModules = true;
|
|
||||||
ProtectKernelTunables = true;
|
|
||||||
ProtectSystem = "strict";
|
|
||||||
ReadWritePaths = [
|
|
||||||
cfg.dataDir
|
|
||||||
cfg.moviesDir
|
|
||||||
"/var/log/radarr"
|
|
||||||
"/eru/media"
|
|
||||||
];
|
|
||||||
RestrictAddressFamilies = [
|
|
||||||
"AF_INET"
|
|
||||||
"AF_INET6"
|
|
||||||
"AF_NETLINK"
|
|
||||||
];
|
|
||||||
RestrictNamespaces = [
|
|
||||||
"uts"
|
|
||||||
"ipc"
|
|
||||||
"pid"
|
|
||||||
"user"
|
|
||||||
"cgroup"
|
|
||||||
"net"
|
|
||||||
];
|
|
||||||
RestrictSUIDSGID = true;
|
|
||||||
SystemCallArchitectures = "native";
|
|
||||||
SystemCallFilter = [
|
|
||||||
"@system-service"
|
|
||||||
#"~@privileged"
|
|
||||||
# .Net CLR requirement
|
|
||||||
#"~@resources"
|
|
||||||
];
|
|
||||||
})
|
|
||||||
(lib.mkIf cfg.db.enable {
|
|
||||||
ExecStartPre = "+${pkgs.writeShellScript "radarr-pre-script" ''
|
|
||||||
mkdir -p /run/radarr
|
|
||||||
rm -f /run/radarr/secrets.env
|
|
||||||
|
|
||||||
# Helper function to safely write variables
|
|
||||||
write_var() {
|
|
||||||
local var_name="$1"
|
|
||||||
local value="$2"
|
|
||||||
if [ -n "$value" ]; then
|
|
||||||
printf "%s=%s\n" "$var_name" "$value" >> /run/radarr/secrets.env
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
assertion = !(instanceCfg.db.user != "radarr" && instanceCfg.db.userFile != "");
|
||||||
|
message = "Specify either a direct database user via db.user or a file via db.userFile.";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assertion = !(instanceCfg.apiKey != "" && instanceCfg.apiKeyFile != "");
|
||||||
|
message = "Specify either a direct API key via apiKey or a file via apiKeyFile (leave direct API key empty).";
|
||||||
|
}
|
||||||
|
]
|
||||||
|
else
|
||||||
|
[ ]
|
||||||
|
) cfg.instances
|
||||||
|
);
|
||||||
|
|
||||||
# API Key (direct value or file)
|
# Create systemd tmpfiles rules for each enabled instance
|
||||||
if [ -n "${cfg.apiKey}" ]; then
|
systemd.tmpfiles.rules = flatten (
|
||||||
write_var "RADARR__AUTH__APIKEY" "${cfg.apiKey}"
|
mapAttrsToList (
|
||||||
else
|
name: instanceCfg:
|
||||||
write_var "RADARR__AUTH__APIKEY" "$(cat ${cfg.apiKeyFile})"
|
if instanceCfg.enable then
|
||||||
fi
|
[
|
||||||
|
"d ${instanceCfg.dataDir} 0775 ${instanceCfg.user} ${instanceCfg.group}"
|
||||||
|
]
|
||||||
|
else
|
||||||
|
[ ]
|
||||||
|
) cfg.instances
|
||||||
|
);
|
||||||
|
|
||||||
# Database Configuration
|
# Create services for each enabled instance
|
||||||
write_var "RADARR__POSTGRES__HOST" "$([ -n "${cfg.db.host}" ] && echo "${cfg.db.host}" || cat "${cfg.db.hostFile}")"
|
systemd.services = mapAttrs' (
|
||||||
write_var "RADARR__POSTGRES__USER" "$([ -n "${cfg.db.user}" ] && echo "${cfg.db.user}" || cat "${cfg.db.userFile}")"
|
name: instanceCfg:
|
||||||
write_var "RADARR__POSTGRES__PASSWORD" "$(cat ${cfg.db.passwordFile})"
|
nameValuePair "radarr-${name}" (
|
||||||
|
mkIf instanceCfg.enable {
|
||||||
|
description = "Radarr (${name})";
|
||||||
|
after = [
|
||||||
|
"network.target"
|
||||||
|
"nss-lookup.target"
|
||||||
|
];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
environment = lib.mkMerge [
|
||||||
|
{
|
||||||
|
RADARR__APP__INSTANCENAME = name;
|
||||||
|
RADARR__APP__THEME = "dark";
|
||||||
|
RADARR__AUTH__METHOD = "External";
|
||||||
|
RADARR__AUTH__REQUIRED = "DisabledForLocalAddresses";
|
||||||
|
RADARR__LOG__DBENABLED = "False";
|
||||||
|
RADARR__LOG__LEVEL = "info";
|
||||||
|
RADARR__SERVER__PORT = toString instanceCfg.port;
|
||||||
|
RADARR__UPDATE__BRANCH = "develop";
|
||||||
|
}
|
||||||
|
(lib.mkIf instanceCfg.db.enable {
|
||||||
|
RADARR__POSTGRES__PORT = toString instanceCfg.db.port;
|
||||||
|
RADARR__POSTGRES__MAINDB = instanceCfg.db.dbname;
|
||||||
|
})
|
||||||
|
instanceCfg.extraEnvVars
|
||||||
|
];
|
||||||
|
|
||||||
# Final permissions
|
serviceConfig = lib.mkMerge [
|
||||||
chmod 600 /run/radarr/secrets.env
|
{
|
||||||
chown ${cfg.user}:${cfg.group} /run/radarr/secrets.env
|
Type = "simple";
|
||||||
''}";
|
User = instanceCfg.user;
|
||||||
|
Group = instanceCfg.group;
|
||||||
|
ExecStart = utils.escapeSystemdExecArgs [
|
||||||
|
(lib.getExe instanceCfg.package)
|
||||||
|
"-nobrowser"
|
||||||
|
"-data=${instanceCfg.dataDir}"
|
||||||
|
"-port=${toString instanceCfg.port}"
|
||||||
|
];
|
||||||
|
WorkingDirectory = instanceCfg.dataDir;
|
||||||
|
RuntimeDirectory = "radarr-${name}";
|
||||||
|
LogsDirectory = "radarr-${name}";
|
||||||
|
RuntimeDirectoryMode = "0750";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 5;
|
||||||
|
}
|
||||||
|
(lib.mkIf instanceCfg.hardening {
|
||||||
|
CapabilityBoundingSet = [ "" ];
|
||||||
|
DeviceAllow = [ "" ];
|
||||||
|
DevicePolicy = "closed";
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = false;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectHome = "read-only";
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ReadWritePaths = [
|
||||||
|
instanceCfg.dataDir
|
||||||
|
instanceCfg.moviesDir
|
||||||
|
"/var/log/radarr-${name}"
|
||||||
|
"/eru/media"
|
||||||
|
];
|
||||||
|
RestrictAddressFamilies = [
|
||||||
|
"AF_INET"
|
||||||
|
"AF_INET6"
|
||||||
|
"AF_NETLINK"
|
||||||
|
];
|
||||||
|
RestrictNamespaces = [
|
||||||
|
"uts"
|
||||||
|
"ipc"
|
||||||
|
"pid"
|
||||||
|
"user"
|
||||||
|
"cgroup"
|
||||||
|
"net"
|
||||||
|
];
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
];
|
||||||
|
})
|
||||||
|
(lib.mkIf instanceCfg.db.enable {
|
||||||
|
ExecStartPre = "+${pkgs.writeShellScript "radarr-${name}-pre-script" ''
|
||||||
|
mkdir -p /run/radarr-${name}
|
||||||
|
rm -f /run/radarr-${name}/secrets.env
|
||||||
|
|
||||||
EnvironmentFile = (
|
# Helper function to safely write variables
|
||||||
["-/run/radarr/secrets.env"]
|
write_var() {
|
||||||
++ lib.optional (cfg.extraEnvVarFile != null && cfg.extraEnvVarFile != "") cfg.extraEnvVarFile
|
local var_name="$1"
|
||||||
);
|
local value="$2"
|
||||||
})
|
if [ -n "$value" ]; then
|
||||||
];
|
printf "%s=%s\n" "$var_name" "$value" >> /run/radarr-${name}/secrets.env
|
||||||
};
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
networking.firewall = mkIf cfg.openFirewall {
|
# API Key (direct value or file)
|
||||||
allowedTCPPorts = [cfg.port];
|
if [ -n "${instanceCfg.apiKey}" ]; then
|
||||||
};
|
write_var "RADARR__AUTH__APIKEY" "${instanceCfg.apiKey}"
|
||||||
|
else
|
||||||
|
write_var "RADARR__AUTH__APIKEY" "$(cat ${instanceCfg.apiKeyFile})"
|
||||||
|
fi
|
||||||
|
|
||||||
users.groups.${cfg.group} = {};
|
# Database Configuration
|
||||||
users.users = mkIf (cfg.user == "radarr") {
|
write_var "RADARR__POSTGRES__HOST" "$([ -n "${instanceCfg.db.host}" ] && echo "${instanceCfg.db.host}" || cat "${instanceCfg.db.hostFile}")"
|
||||||
radarr = {
|
write_var "RADARR__POSTGRES__USER" "$([ -n "${instanceCfg.db.userFile}" ] && cat "${instanceCfg.db.userFile}" || echo "${instanceCfg.db.user}")"
|
||||||
inherit (cfg) group;
|
write_var "RADARR__POSTGRES__PASSWORD" "$(cat ${instanceCfg.db.passwordFile})"
|
||||||
isSystemUser = true;
|
|
||||||
home = cfg.dataDir;
|
# Final permissions
|
||||||
};
|
chmod 600 /run/radarr-${name}/secrets.env
|
||||||
};
|
chown ${instanceCfg.user}:${instanceCfg.group} /run/radarr-${name}/secrets.env
|
||||||
|
''}";
|
||||||
|
|
||||||
|
EnvironmentFile = (
|
||||||
|
[ "-/run/radarr-${name}/secrets.env" ]
|
||||||
|
++ lib.optional (
|
||||||
|
instanceCfg.extraEnvVarFile != null && instanceCfg.extraEnvVarFile != ""
|
||||||
|
) instanceCfg.extraEnvVarFile
|
||||||
|
);
|
||||||
|
})
|
||||||
|
];
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) cfg.instances;
|
||||||
|
|
||||||
|
# Firewall configurations
|
||||||
|
networking.firewall = mkMerge (
|
||||||
|
mapAttrsToList (
|
||||||
|
name: instanceCfg:
|
||||||
|
mkIf (instanceCfg.enable && instanceCfg.openFirewall) {
|
||||||
|
allowedTCPPorts = [ instanceCfg.port ];
|
||||||
|
}
|
||||||
|
) cfg.instances
|
||||||
|
);
|
||||||
|
|
||||||
|
# Users and groups
|
||||||
|
users = mkMerge (
|
||||||
|
mapAttrsToList (
|
||||||
|
name: instanceCfg:
|
||||||
|
mkIf instanceCfg.enable {
|
||||||
|
groups.${instanceCfg.group} = { };
|
||||||
|
users = mkIf (instanceCfg.user == "radarr") {
|
||||||
|
radarr = {
|
||||||
|
inherit (instanceCfg) group;
|
||||||
|
isSystemUser = true;
|
||||||
|
# home = instanceCfg.dataDir;
|
||||||
|
home = "/nahar/radarr";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) cfg.instances
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue