From 8951443e005295167d4cee4968a2c803dc07b430 Mon Sep 17 00:00:00 2001 From: Mel Date: Mon, 16 Dec 2024 23:09:24 +0100 Subject: Deploy Transmission + VPN services Signed-off-by: Mel --- machines/corsac/default.nix | 1 + modules/foundation/services.nix | 41 +++++++++++++++++-- secrets/pia-login-secrets.age | Bin 0 -> 590 bytes secrets/secrets.nix | 4 ++ services/transmission.nix | 85 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 secrets/pia-login-secrets.age create mode 100644 services/transmission.nix diff --git a/machines/corsac/default.nix b/machines/corsac/default.nix index b01b241..a80993f 100644 --- a/machines/corsac/default.nix +++ b/machines/corsac/default.nix @@ -14,6 +14,7 @@ ../../modules/jellyfin.nix ../../services/immich.nix + ../../services/transmission.nix ]; system.stateVersion = "24.05"; diff --git a/modules/foundation/services.nix b/modules/foundation/services.nix index 5acb0c6..bedceb1 100644 --- a/modules/foundation/services.nix +++ b/modules/foundation/services.nix @@ -38,6 +38,16 @@ let default = [ ]; }; + devices = mkOption { + type = with types; listOf str; + default = [ ]; + }; + + capabilities = mkOption { + type = with types; listOf str; + default = [ ]; + }; + entrypoint = mkOption { type = types.nullOr types.str; default = null; @@ -62,6 +72,11 @@ let type = types.listOf types.path; default = [ ]; }; + + customNetwork = mkOption { + type = types.nullOr types.str; + default = null; + }; }; }; @@ -178,11 +193,15 @@ in image, ports, volumes, + devices, + capabilities, entrypoint ? null, cmd ? null, workdir ? null, environment ? null, environmentFiles ? null, + customNetwork ? null, + group, ... }: @@ -196,10 +215,24 @@ in ; ports = map mkOciPort ports; volumes = map mkOciVolume volumes; - extraOptions = lib.mkIf (group != "") [ - "--network-alias=${name}" - "--network=${group}" - ]; + + extraOptions = let + mapOptions = optionName: values: + map (v: "--${optionName}=${v}") values; + + networkOptions = + if customNetwork != null then [ + "--network=${customNetwork}" + ] else if group != "" then [ + "--network-alias=${name}" + "--network=${group}" + ] else []; + + capabilityOptions = mapOptions "cap-add" capabilities; + + deviceOptions = mapOptions "device" devices; + in + networkOptions ++ capabilityOptions ++ deviceOptions; } // (mkImage { oldImage = fullImage; diff --git a/secrets/pia-login-secrets.age b/secrets/pia-login-secrets.age new file mode 100644 index 0000000..5f66af1 Binary files /dev/null and b/secrets/pia-login-secrets.age differ diff --git a/secrets/secrets.nix b/secrets/secrets.nix index 604ca1e..823420b 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -18,5 +18,9 @@ in lapin ] ++ allAdmins; + "pia-login-secrets.age".publicKeys = [ + corsac + ] ++ allAdmins; + "password.age".publicKeys = allSystems ++ allAdmins; } diff --git a/services/transmission.nix b/services/transmission.nix new file mode 100644 index 0000000..ec98177 --- /dev/null +++ b/services/transmission.nix @@ -0,0 +1,85 @@ +{ + me, + config, + lib, + pkgs, + auxiliaryPkgs, + ... +}: + +let + inherit (pkgs) dockerTools; + inherit (auxiliaryPkgs) common; + + transmission = pkgs.transmission_4; + + transmissionLocalPort = 2018; + transmissionDir = "/srv/transmission"; + + transmissionImage = dockerTools.streamLayeredImage { + name = "transmission"; + tag = transmission.version; + fromImage = common.alpine.base; + contents = [ transmission ]; + }; + + gluetunImage = common.pullImage { + name = "qmcgaw/gluetun"; + tag = "v3.39"; + digest = "sha256:6a8058e626763cbf735ac2f78c774dbb24fec2490bd9d9f7d67e22592cb4a991"; + x86.sha256 = "1cg43lmp3ql64zsfwp2f52kigijs30n3hnja12msr9npbgq8a8ga"; + }; + + piaCountries = [ + "Albania" "Austria" "Belgium" "Bosnia and Herzegovina" "Bulgaria" + "Czech Republic" "ES Madrid" "ES Valencia" "Estonia" "Georgia" "Greece" + "Hungary" "IT Milano" "Poland" "Portugal" "Romania" "Serbia" "Turkey" "Ukraine" + ]; +in +{ + age.secrets.pia-login-secrets = { + file = ../secrets/pia-login-secrets.age; + }; + + foundation.services = { + transmission = { + image = transmissionImage; + + volumes = [ + [ "${transmissionDir}/config" "/var/lib/transmission/config" ] + [ "${transmissionDir}/download" "/var/lib/transmission/download" ] + [ "${transmissionDir}/torrents" "/var/lib/transmission/torrents" ] + ]; + + entrypoint = lib.getExe' transmission "transmission-daemon"; + cmd = [ + "--foreground" + "--config-dir" "/var/lib/transmission/config" + ]; + + customNetwork = "container:vpn"; + }; + + vpn = { + fullImage = gluetunImage; + + ports = [ + (common.tailnetPort me [ transmissionLocalPort 9091 ]) + ]; + + volumes = [ + [ "${transmissionDir}/gluetun" "/gluetun" ] + ]; + + capabilities = [ "NET_ADMIN" ]; + devices = [ "/dev/net/tun" ]; + + environment = { + VPN_SERVICE_PROVIDER = "private internet access"; + SERVER_REGIONS = lib.concatStringsSep "," piaCountries; + }; + + environmentFiles = [ config.age.secrets.pia-login-secrets.path ]; + }; + }; +} -- cgit 1.4.1