reconfig - no mkfunction
This commit is contained in:
parent
934af3c9b8
commit
5161eba75c
1 changed files with 194 additions and 143 deletions
|
@ -54,147 +54,10 @@ let
|
|||
|
||||
# Function to create instance-specific configuration
|
||||
mkRadarrInstance = name: instanceCfg: {
|
||||
assertions = [
|
||||
{
|
||||
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 = !(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).";
|
||||
}
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${instanceCfg.dataDir} 0775 ${instanceCfg.user} ${instanceCfg.group}"
|
||||
];
|
||||
|
||||
systemd.services."radarr-${name}" = {
|
||||
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
|
||||
];
|
||||
|
||||
serviceConfig = lib.mkMerge [
|
||||
{
|
||||
Name = "radarr-${name}";
|
||||
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
|
||||
|
||||
# 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-${name}/secrets.env
|
||||
fi
|
||||
}
|
||||
|
||||
# API Key (direct value or file)
|
||||
if [ -n "${instanceCfg.apiKey}" ]; then
|
||||
write_var "RADARR__AUTH__APIKEY" "${instanceCfg.apiKey}"
|
||||
else
|
||||
write_var "RADARR__AUTH__APIKEY" "$(cat ${instanceCfg.apiKeyFile})"
|
||||
fi
|
||||
|
||||
# Database Configuration
|
||||
write_var "RADARR__POSTGRES__HOST" "$([ -n "${instanceCfg.db.host}" ] && echo "${instanceCfg.db.host}" || cat "${instanceCfg.db.hostFile}")"
|
||||
write_var "RADARR__POSTGRES__USER" "$([ -n "${instanceCfg.db.user}" ] && echo "${instanceCfg.db.user}" || cat "${instanceCfg.db.userFile}")"
|
||||
write_var "RADARR__POSTGRES__PASSWORD" "$(cat ${instanceCfg.db.passwordFile})"
|
||||
|
||||
# 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
|
||||
);
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
networking.firewall = mkIf instanceCfg.openFirewall {
|
||||
|
@ -317,12 +180,200 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable (mkMerge [
|
||||
# Create services for each enabled instance
|
||||
(mkMerge (
|
||||
config = mkIf cfg.enable {
|
||||
# Add assertions for all instances
|
||||
assertions = flatten (
|
||||
mapAttrsToList (
|
||||
name: instanceCfg: mkIf instanceCfg.enable (mkRadarrInstance name instanceCfg)
|
||||
) cfg.instances
|
||||
))
|
||||
]);
|
||||
name: instanceCfg:
|
||||
if instanceCfg.enable then
|
||||
[
|
||||
{
|
||||
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 = !(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
|
||||
);
|
||||
|
||||
# Create systemd tmpfiles rules for each enabled instance
|
||||
systemd.tmpfiles.rules = flatten (
|
||||
mapAttrsToList (
|
||||
name: instanceCfg:
|
||||
if instanceCfg.enable then
|
||||
[
|
||||
"d ${instanceCfg.dataDir} 0775 ${instanceCfg.user} ${instanceCfg.group}"
|
||||
]
|
||||
else
|
||||
[ ]
|
||||
) cfg.instances
|
||||
);
|
||||
|
||||
# Create services for each enabled instance
|
||||
systemd.services = mapAttrs' (
|
||||
name: instanceCfg:
|
||||
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
|
||||
];
|
||||
|
||||
serviceConfig = lib.mkMerge [
|
||||
{
|
||||
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
|
||||
|
||||
# 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-${name}/secrets.env
|
||||
fi
|
||||
}
|
||||
|
||||
# API Key (direct value or file)
|
||||
if [ -n "${instanceCfg.apiKey}" ]; then
|
||||
write_var "RADARR__AUTH__APIKEY" "${instanceCfg.apiKey}"
|
||||
else
|
||||
write_var "RADARR__AUTH__APIKEY" "$(cat ${instanceCfg.apiKeyFile})"
|
||||
fi
|
||||
|
||||
# Database Configuration
|
||||
write_var "RADARR__POSTGRES__HOST" "$([ -n "${instanceCfg.db.host}" ] && echo "${instanceCfg.db.host}" || cat "${instanceCfg.db.hostFile}")"
|
||||
write_var "RADARR__POSTGRES__USER" "$([ -n "${instanceCfg.db.user}" ] && echo "${instanceCfg.db.user}" || cat "${instanceCfg.db.userFile}")"
|
||||
write_var "RADARR__POSTGRES__PASSWORD" "$(cat ${instanceCfg.db.passwordFile})"
|
||||
|
||||
# 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