Merge branch 'dev'
This commit is contained in:
Generated
+15
-15
@@ -8,11 +8,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1705332421,
|
"lastModified": 1708939976,
|
||||||
"narHash": "sha256-USpGLPme1IuqG78JNqSaRabilwkCyHmVWY0M9vYyqEA=",
|
"narHash": "sha256-O5+nFozxz2Vubpdl1YZtPrilcIXPcRAjqNdNE8oCRoA=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "devshell",
|
"repo": "devshell",
|
||||||
"rev": "83cb93d6d063ad290beee669f4badf9914cc16ec",
|
"rev": "5ddecd67edbd568ebe0a55905273e56cc82aabe3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -28,11 +28,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1706830856,
|
"lastModified": 1709336216,
|
||||||
"narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=",
|
"narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=",
|
||||||
"owner": "hercules-ci",
|
"owner": "hercules-ci",
|
||||||
"repo": "flake-parts",
|
"repo": "flake-parts",
|
||||||
"rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f",
|
"rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -76,11 +76,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1708501555,
|
"lastModified": 1709386671,
|
||||||
"narHash": "sha256-zJaF0RkdIPbh8LTmnpW/E7tZYpqIE+MePzlWwUNob4c=",
|
"narHash": "sha256-VPqfBnIJ+cfa78pd4Y5Cr6sOWVW8GYHRVucxJGmRf8Q=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "b50a77c03d640716296021ad58950b1bb0345799",
|
"rev": "fa9a51752f1b5de583ad5213eb621be071806663",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -122,11 +122,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1708335038,
|
"lastModified": 1709546977,
|
||||||
"narHash": "sha256-ETLZNFBVCabo7lJrpjD6cAbnE11eDOjaQnznmg/6hAE=",
|
"narHash": "sha256-R0bi8zAWt1s1q7lSvwiFI8+kEL29rm4WtYTqPgjlEBs=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"rev": "e504621290a1fd896631ddbc5e9c16f4366c9f65",
|
"rev": "e7a277c5d12bf570efa2427d9cfdb760b9a0512f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -142,11 +142,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1709159289,
|
"lastModified": 1709597689,
|
||||||
"narHash": "sha256-66eFi/SgygAMOLLLkH5oqwBiI4iE5Bj/kBJmmMhX8fg=",
|
"narHash": "sha256-6pSgM6s2Rm2zAA/dYKAOK7wLNkzox5hBKOC5E5TJoO8=",
|
||||||
"owner": "Maroka-chan",
|
"owner": "Maroka-chan",
|
||||||
"repo": "VPN-Confinement",
|
"repo": "VPN-Confinement",
|
||||||
"rev": "93804a1050d3699418f0f9472e9c5eca1aa8153d",
|
"rev": "2f5fffe81305e731593b1923acdf1c7653f1b17c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.util-nixarr.services.bazarr;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
util-nixarr.services.bazarr = {
|
||||||
|
enable = mkEnableOption ("bazarr, a subtitle manager for Sonarr and Radarr");
|
||||||
|
|
||||||
|
openFirewall = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Open ports in the firewall for the bazarr web interface.";
|
||||||
|
};
|
||||||
|
|
||||||
|
listenPort = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 6767;
|
||||||
|
description = "Port on which the bazarr web interface should listen";
|
||||||
|
};
|
||||||
|
|
||||||
|
dataDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "/var/lib/bazarr";
|
||||||
|
description = "State directory for bazarr";
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "bazarr";
|
||||||
|
description = "User account under which bazarr runs.";
|
||||||
|
};
|
||||||
|
|
||||||
|
group = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "bazarr";
|
||||||
|
description = "Group under which bazarr runs.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d '${cfg.dataDir}' 0700 bazarr root - -"
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.bazarr = {
|
||||||
|
description = "bazarr";
|
||||||
|
after = [ "network.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
User = cfg.user;
|
||||||
|
Group = cfg.group;
|
||||||
|
SyslogIdentifier = "bazarr";
|
||||||
|
ExecStart = pkgs.writeShellScript "start-bazarr" ''
|
||||||
|
${pkgs.bazarr}/bin/bazarr \
|
||||||
|
--config '${cfg.dataDir}' \
|
||||||
|
--port ${toString cfg.listenPort} \
|
||||||
|
--no-update True
|
||||||
|
'';
|
||||||
|
Restart = "on-failure";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = mkIf cfg.openFirewall {
|
||||||
|
allowedTCPPorts = [ cfg.listenPort ];
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users = mkIf (cfg.user == "bazarr") {
|
||||||
|
bazarr = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = cfg.group;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups = mkIf (cfg.group == "bazarr") {
|
||||||
|
bazarr = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
with lib; let
|
||||||
|
cfg = config.nixarr.bazarr;
|
||||||
|
nixarr = config.nixarr;
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./bazarr-module
|
||||||
|
];
|
||||||
|
|
||||||
|
options.nixarr.bazarr = {
|
||||||
|
enable = mkEnableOption "the bazarr service.";
|
||||||
|
|
||||||
|
stateDir = mkOption {
|
||||||
|
type = types.path;
|
||||||
|
default = "${nixarr.stateDir}/bazarr";
|
||||||
|
defaultText = literalExpression ''"''${nixarr.stateDir}/bazarr"'';
|
||||||
|
example = "/home/user/.local/share/nixarr/bazarr";
|
||||||
|
description = "The state directory for bazarr";
|
||||||
|
};
|
||||||
|
|
||||||
|
vpn.enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
**Required options:** [`nixarr.vpn.enable`](#nixarr.vpn.enable)
|
||||||
|
|
||||||
|
Route Bazarr traffic through the VPN.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = cfg.vpn.enable -> nixarr.vpn.enable;
|
||||||
|
message = ''
|
||||||
|
The nixarr.bazarr.vpn.enable option requires the
|
||||||
|
nixarr.vpn.enable option to be set, but it was not.
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
util-nixarr.services.bazarr = {
|
||||||
|
enable = cfg.enable;
|
||||||
|
user = "bazarr";
|
||||||
|
group = "media";
|
||||||
|
dataDir = cfg.stateDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable and specify VPN namespace to confine service in.
|
||||||
|
systemd.services.bazarr.vpnconfinement = mkIf cfg.vpn.enable {
|
||||||
|
enable = true;
|
||||||
|
vpnnamespace = "wg";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Port mappings
|
||||||
|
# TODO: openports
|
||||||
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
|
portMappings = [{ from = config.bazarr.listenPort; to = config.bazarr.listenPort; }];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = mkIf cfg.vpn.enable {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
|
||||||
|
virtualHosts."127.0.0.1:${builtins.toString config.bazarr.listenPort}" = {
|
||||||
|
listen = [
|
||||||
|
{
|
||||||
|
addr = "0.0.0.0";
|
||||||
|
port = config.bazarr.listenPort;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
locations."/" = {
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
proxyWebsockets = true;
|
||||||
|
proxyPass = "http://192.168.15.1:${builtins.toString config.bazarr.listenPort}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
+120
-48
@@ -6,9 +6,66 @@
|
|||||||
}:
|
}:
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.nixarr.ddns;
|
cfg = config.nixarr.ddns;
|
||||||
|
ddns-njalla = pkgs.writeShellApplication {
|
||||||
|
name = "ddns-njalla";
|
||||||
|
|
||||||
|
runtimeInputs = with pkgs; [ curl jq ];
|
||||||
|
|
||||||
|
# Thanks chatgpt...
|
||||||
|
text = ''
|
||||||
|
# Path to the JSON file
|
||||||
|
json_file="$1"
|
||||||
|
|
||||||
|
# Convert the JSON object into a series of tab-separated key-value pairs using jq
|
||||||
|
# - `to_entries[]`: Convert the object into an array of key-value pairs.
|
||||||
|
# - `[.key, .value]`: For each pair, create an array containing the key and the value.
|
||||||
|
# - `@tsv`: Convert the array to a tab-separated string.
|
||||||
|
# The output will be a series of lines, each containing a key and a value separated by a tab.
|
||||||
|
jq_command='to_entries[] | [.key, .value] | @tsv'
|
||||||
|
|
||||||
|
# Read the converted output line by line
|
||||||
|
# - `IFS=$'\t'`: Use the tab character as the field separator.
|
||||||
|
# - `read -r key val`: For each line, split it into `key` and `val` based on the tab separator.
|
||||||
|
while IFS=$'\t' read -r key val; do
|
||||||
|
# For each key-value pair, execute the curl command
|
||||||
|
# Replace `''${key}` and `''${val}` in the URL with the actual key and value.
|
||||||
|
curl -s "https://njal.la/update/?h=''${key}&k=''${val}&auto"
|
||||||
|
done < <(jq -r "$jq_command" "$json_file")
|
||||||
|
'';
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
options.nixarr.ddns = {
|
options.nixarr.ddns = {
|
||||||
njalla = {
|
njalla = {
|
||||||
|
vpn = {
|
||||||
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
example = true;
|
||||||
|
description = ''
|
||||||
|
**Required options:**
|
||||||
|
|
||||||
|
- [`nixarr.ddns.njalla.keysFile`](#nixarr.ddns.njalla.keysfile)
|
||||||
|
- [`nixarr.vpn.enable`](#nixarr.vpn.enable)
|
||||||
|
|
||||||
|
Whether or not to enable DDNS over VPN for a
|
||||||
|
[Njalla](https://njal.la/) domain. Setting this will point to
|
||||||
|
the public ip of your VPN. Useful if you're running services
|
||||||
|
over VPN and want a domain that points to the corresponding ip.
|
||||||
|
|
||||||
|
**Note:** You can enable both this and the regular njalla DDNS
|
||||||
|
service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
keysFile = mkOption {
|
||||||
|
type = with types; nullOr path;
|
||||||
|
default = null;
|
||||||
|
example = "/data/.secret/njalla/keys-file.json";
|
||||||
|
description = ''
|
||||||
|
See [`nixarr.ddns.njalla.keysFile`](#nixarr.ddns.njalla.keysfile)
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
@@ -60,60 +117,75 @@ in {
|
|||||||
nixarr.ddns.njalla.keysFile option to be set, but it was not.
|
nixarr.ddns.njalla.keysFile option to be set, but it was not.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
assertion = cfg.njalla.vpn.enable -> (
|
||||||
|
cfg.njalla.vpn.keysFile != null &&
|
||||||
|
config.nixarr.vpn.enable
|
||||||
|
);
|
||||||
|
message = ''
|
||||||
|
The nixarr.ddns.njalla.enable option requires the
|
||||||
|
nixarr.vpn.enable option to be set, but it was not.
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
systemd.timers = mkIf cfg.njalla.enable {
|
systemd.timers = mkMerge [
|
||||||
ddnsNjalla = {
|
(mkIf cfg.njalla.enable {
|
||||||
description = "Timer for setting the Njalla DDNS records";
|
ddnsNjalla = {
|
||||||
|
description = "Timer for setting the Njalla DDNS records";
|
||||||
|
|
||||||
timerConfig = {
|
timerConfig = {
|
||||||
OnBootSec = "30"; # Run 30 seconds after system boot
|
OnBootSec = "30"; # Run 30 seconds after system boot
|
||||||
OnCalendar = "hourly";
|
OnCalendar = "hourly";
|
||||||
Persistent = true; # Run service immediately if last window was missed
|
Persistent = true; # Run service immediately if last window was missed
|
||||||
RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min
|
RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min
|
||||||
|
};
|
||||||
|
|
||||||
|
wantedBy = ["multi-user.target"];
|
||||||
};
|
};
|
||||||
|
})
|
||||||
|
(mkIf cfg.njalla.vpn.enable {
|
||||||
|
ddnsNjallaVpn = {
|
||||||
|
description = "Timer for setting the Njalla DDNS records over VPN";
|
||||||
|
|
||||||
wantedBy = ["multi-user.target"];
|
timerConfig = {
|
||||||
};
|
OnBootSec = "30"; # Run 30 seconds after system boot
|
||||||
};
|
OnCalendar = "hourly";
|
||||||
|
Persistent = true; # Run service immediately if last window was missed
|
||||||
|
RandomizedDelaySec = "5min"; # Run service OnCalendar +- 5min
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services = let
|
wantedBy = ["multi-user.target"];
|
||||||
ddns-njalla = pkgs.writeShellApplication {
|
|
||||||
name = "ddns-njalla";
|
|
||||||
|
|
||||||
runtimeInputs = with pkgs; [ curl jq ];
|
|
||||||
|
|
||||||
# Thanks chatgpt...
|
|
||||||
text = ''
|
|
||||||
# Path to the JSON file
|
|
||||||
json_file="${cfg.njalla.keysFile}"
|
|
||||||
|
|
||||||
# Convert the JSON object into a series of tab-separated key-value pairs using jq
|
|
||||||
# - `to_entries[]`: Convert the object into an array of key-value pairs.
|
|
||||||
# - `[.key, .value]`: For each pair, create an array containing the key and the value.
|
|
||||||
# - `@tsv`: Convert the array to a tab-separated string.
|
|
||||||
# The output will be a series of lines, each containing a key and a value separated by a tab.
|
|
||||||
jq_command='to_entries[] | [.key, .value] | @tsv'
|
|
||||||
|
|
||||||
# Read the converted output line by line
|
|
||||||
# - `IFS=$'\t'`: Use the tab character as the field separator.
|
|
||||||
# - `read -r key val`: For each line, split it into `key` and `val` based on the tab separator.
|
|
||||||
while IFS=$'\t' read -r key val; do
|
|
||||||
# For each key-value pair, execute the curl command
|
|
||||||
# Replace `''${key}` and `''${val}` in the URL with the actual key and value.
|
|
||||||
curl -s "https://njal.la/update/?h=''${key}&k=''${val}&auto"
|
|
||||||
done < <(jq -r "$jq_command" "$json_file")
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
in mkIf cfg.njalla.enable {
|
|
||||||
ddnsNjalla = {
|
|
||||||
description = "Sets the Njalla DDNS records";
|
|
||||||
|
|
||||||
serviceConfig = {
|
|
||||||
ExecStart = getExe ddns-njalla;
|
|
||||||
Type = "oneshot";
|
|
||||||
};
|
};
|
||||||
};
|
})
|
||||||
};
|
];
|
||||||
|
|
||||||
|
systemd.services = mkMerge [
|
||||||
|
(mkIf cfg.njalla.enable {
|
||||||
|
ddnsNjalla = {
|
||||||
|
description = "Sets the Njalla DDNS records";
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = ''${getExe ddns-njalla} "${cfg.njalla.keysFile}"'';
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
(mkIf (cfg.njalla.vpn.enable && config.nixarr.vpn.enable) {
|
||||||
|
ddnsNjallaVpn = {
|
||||||
|
description = "Sets the Njalla DDNS records over VPN";
|
||||||
|
|
||||||
|
vpnconfinement = {
|
||||||
|
enable = true;
|
||||||
|
vpnnamespace = "wg";
|
||||||
|
};
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
ExecStart = ''${getExe ddns-njalla} "${cfg.njalla.vpn.keysFile}"'';
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -244,7 +244,11 @@ in with lib; {
|
|||||||
# Port mappings
|
# Port mappings
|
||||||
# TODO: openports if expose.vpn
|
# TODO: openports if expose.vpn
|
||||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
portMappings = [{ from = defaultPort; to = defaultPort; }];
|
||||||
|
openVPNPorts = optional cfg.expose.vpn.enable {
|
||||||
|
port = cfg.expose.vpn.port;
|
||||||
|
protocol = "tcp";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.nixarr.lidarr;
|
cfg = config.nixarr.lidarr;
|
||||||
nixarr = config.nixarr;
|
nixarr = config.nixarr;
|
||||||
|
defaultPort = 8686;
|
||||||
in {
|
in {
|
||||||
options.nixarr.lidarr = {
|
options.nixarr.lidarr = {
|
||||||
enable = mkEnableOption "the Lidarr service.";
|
enable = mkEnableOption "the Lidarr service.";
|
||||||
@@ -61,7 +62,7 @@ in {
|
|||||||
# Port mappings
|
# Port mappings
|
||||||
# TODO: openports
|
# TODO: openports
|
||||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
portMappings = [{ from = defaultPort; to = defaultPort; }];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx = mkIf cfg.vpn.enable {
|
services.nginx = mkIf cfg.vpn.enable {
|
||||||
|
|||||||
+33
-9
@@ -6,9 +6,18 @@
|
|||||||
}:
|
}:
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.nixarr;
|
cfg = config.nixarr;
|
||||||
|
list-unlinked = pkgs.writeShellApplication {
|
||||||
|
name = "list-unlinked";
|
||||||
|
runtimeInputs = with pkgs; [util-linux];
|
||||||
|
text = ''
|
||||||
|
find "$1" -type f -links 1 -exec du -h {} + | sort -h
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./jellyfin
|
./jellyfin
|
||||||
|
./bazarr
|
||||||
./ddns
|
./ddns
|
||||||
./radarr
|
./radarr
|
||||||
./lidarr
|
./lidarr
|
||||||
@@ -45,6 +54,7 @@ in {
|
|||||||
The following services are supported:
|
The following services are supported:
|
||||||
|
|
||||||
- [Jellyfin](#nixarr.jellyfin.enable)
|
- [Jellyfin](#nixarr.jellyfin.enable)
|
||||||
|
- [Bazarr](#nixarr.bazarr.enable)
|
||||||
- [Lidarr](#nixarr.lidarr.enable)
|
- [Lidarr](#nixarr.lidarr.enable)
|
||||||
- [Prowlarr](#nixarr.prowlarr.enable)
|
- [Prowlarr](#nixarr.prowlarr.enable)
|
||||||
- [Radarr](#nixarr.radarr.enable)
|
- [Radarr](#nixarr.radarr.enable)
|
||||||
@@ -56,6 +66,15 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mediaUsers = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
example = [ "user" ];
|
||||||
|
description = ''
|
||||||
|
Extra users to add to the media group.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
mediaDir = mkOption {
|
mediaDir = mkOption {
|
||||||
type = types.path;
|
type = types.path;
|
||||||
default = "/data/media";
|
default = "/data/media";
|
||||||
@@ -147,7 +166,7 @@ in {
|
|||||||
];
|
];
|
||||||
|
|
||||||
users.groups = {
|
users.groups = {
|
||||||
media = {};
|
media.members = cfg.mediaUsers;
|
||||||
streamer = {};
|
streamer = {};
|
||||||
torrenter = {};
|
torrenter = {};
|
||||||
};
|
};
|
||||||
@@ -180,9 +199,18 @@ in {
|
|||||||
"d '${cfg.mediaDir}/torrents/readarr' 0755 torrenter media - -"
|
"d '${cfg.mediaDir}/torrents/readarr' 0755 torrenter media - -"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
jdupes
|
||||||
|
list-unlinked
|
||||||
|
];
|
||||||
|
|
||||||
# TODO: wtf to do about openports
|
# TODO: wtf to do about openports
|
||||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
openVPNPorts = optional cfg.vpn.vpnTestService.enable {
|
||||||
|
port = cfg.vpn.vpnTestService.port;
|
||||||
|
protocol = "tcp";
|
||||||
|
};
|
||||||
accessibleFrom = [
|
accessibleFrom = [
|
||||||
"192.168.1.0/24"
|
"192.168.1.0/24"
|
||||||
"127.0.0.1"
|
"127.0.0.1"
|
||||||
@@ -191,8 +219,9 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# TODO: openports
|
# TODO: openports
|
||||||
systemd.services.vpn-test-service = {
|
systemd.services.vpn-test-service = mkIf cfg.vpn.vpnTestService.enable {
|
||||||
enable = cfg.vpn.vpnTestService.enable;
|
enable = true;
|
||||||
|
|
||||||
vpnconfinement = {
|
vpnconfinement = {
|
||||||
enable = true;
|
enable = true;
|
||||||
vpnnamespace = "wg";
|
vpnnamespace = "wg";
|
||||||
@@ -226,7 +255,7 @@ in {
|
|||||||
./dnsleaktest.sh
|
./dnsleaktest.sh
|
||||||
'' + (if cfg.vpn.vpnTestService.port != null then ''
|
'' + (if cfg.vpn.vpnTestService.port != null then ''
|
||||||
echo "starting netcat on port ${builtins.toString cfg.vpn.vpnTestService.port}:"
|
echo "starting netcat on port ${builtins.toString cfg.vpn.vpnTestService.port}:"
|
||||||
nc -vnlpu ${builtins.toString cfg.vpn.vpnTestService.port}
|
nc -vnlp ${builtins.toString cfg.vpn.vpnTestService.port}
|
||||||
'' else "");
|
'' else "");
|
||||||
};
|
};
|
||||||
in "${vpn-test}/bin/vpn-test";
|
in "${vpn-test}/bin/vpn-test";
|
||||||
@@ -234,11 +263,6 @@ in {
|
|||||||
bindsTo = ["netns@wg.service"];
|
bindsTo = ["netns@wg.service"];
|
||||||
requires = ["network-online.target"];
|
requires = ["network-online.target"];
|
||||||
after = ["wg.service"];
|
after = ["wg.service"];
|
||||||
serviceConfig = {
|
|
||||||
#User = "torrenter";
|
|
||||||
NetworkNamespacePath = "/var/run/netns/wg";
|
|
||||||
BindReadOnlyPaths = ["/etc/netns/wg/resolv.conf:/etc/resolv.conf:norbind" "/data/test.file:/etc/test.file:norbind"];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,9 +83,9 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Port mappings
|
# Port mappings
|
||||||
# TODO: openports
|
|
||||||
vpnnamespaces.wg = {
|
vpnnamespaces.wg = {
|
||||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
||||||
|
openVPNPorts = map (x: { port = x; protocol = "both"; }) services.openssh.ports;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ in {
|
|||||||
|
|
||||||
# Port mappings
|
# Port mappings
|
||||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
portMappings = [{ from = defaultPort; to = defaultPort; }];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx = mkIf cfg.vpn.enable {
|
services.nginx = mkIf cfg.vpn.enable {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ in {
|
|||||||
|
|
||||||
# Port mappings
|
# Port mappings
|
||||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
portMappings = [{ from = defaultPort; to = defaultPort; }];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx = mkIf cfg.vpn.enable {
|
services.nginx = mkIf cfg.vpn.enable {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ in {
|
|||||||
|
|
||||||
# Port mappings
|
# Port mappings
|
||||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
portMappings = [{ from = defaultPort; to = defaultPort; }];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx = mkIf cfg.vpn.enable {
|
services.nginx = mkIf cfg.vpn.enable {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ in {
|
|||||||
|
|
||||||
# Port mappings
|
# Port mappings
|
||||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
portMappings = [{ From = defaultPort; To = defaultPort; }];
|
portMappings = [{ from = defaultPort; to = defaultPort; }];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx = mkIf cfg.vpn.enable {
|
services.nginx = mkIf cfg.vpn.enable {
|
||||||
|
|||||||
@@ -224,19 +224,16 @@ in {
|
|||||||
];
|
];
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d '${cfg.stateDir}' 0700 torrenter root - -"
|
"d '${cfg.stateDir}' 0750 torrenter torrenter - -"
|
||||||
# This is fixes a bug in nixpks (https://github.com/NixOS/nixpkgs/issues/291883)
|
# This is fixes a bug in nixpks (https://github.com/NixOS/nixpkgs/issues/291883)
|
||||||
"d '${cfg.stateDir}/.config/transmission-daemon' 0700 torrenter root - -"
|
"d '${cfg.stateDir}/.config/transmission-daemon' 0750 torrenter torrenter - -"
|
||||||
] ++ (
|
] ++ optional cfg-cross-seed.enable
|
||||||
if cfg-cross-seed.enable then
|
"d '${cfg-cross-seed.stateDir}' 0700 cross-seed root - -";
|
||||||
[ "d '${cfg-cross-seed.stateDir}' 0700 cross-seed root - -" ]
|
|
||||||
else []
|
|
||||||
);
|
|
||||||
|
|
||||||
util-nixarr.services.cross-seed = mkIf cfg-cross-seed.enable {
|
util-nixarr.services.cross-seed = mkIf cfg-cross-seed.enable {
|
||||||
enable = true;
|
enable = true;
|
||||||
dataDir = cfg-cross-seed.stateDir;
|
dataDir = cfg-cross-seed.stateDir;
|
||||||
#group = "media";
|
group = "torrenter";
|
||||||
settings = {
|
settings = {
|
||||||
torrentDir = "${nixarr.mediaDir}/torrents";
|
torrentDir = "${nixarr.mediaDir}/torrents";
|
||||||
outputDir = "${nixarr.mediaDir}/torrents/.cross-seed";
|
outputDir = "${nixarr.mediaDir}/torrents/.cross-seed";
|
||||||
@@ -335,11 +332,11 @@ in {
|
|||||||
};
|
};
|
||||||
|
|
||||||
# Port mappings
|
# Port mappings
|
||||||
# TODO: open peerPort
|
|
||||||
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
vpnnamespaces.wg = mkIf cfg.vpn.enable {
|
||||||
portMappings = [{ From = cfg.uiPort; To = cfg.uiPort; }];
|
portMappings = [{ from = cfg.uiPort; to = cfg.uiPort; }];
|
||||||
#openUdpPorts = [cfg.peerPort];
|
openVPNPorts = [
|
||||||
#openTcpPorts = [cfg.peerPort];
|
{ port = cfg.peerPort; protocol = "both"; }
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx = mkIf cfg.vpn.enable {
|
services.nginx = mkIf cfg.vpn.enable {
|
||||||
|
|||||||
Reference in New Issue
Block a user