From 5d612efb6c21887c85f287f8ba4c199712482838 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 25 Dec 2023 19:25:08 +0100 Subject: [PATCH 1/8] nixos: services: nginx: use attrset for vhosts Attribute sets compose better than lists, it was a mistake to use a list in the first place... --- modules/nixos/services/blog/default.nix | 2 +- .../nixos/services/calibre-web/default.nix | 8 ++-- .../nixos/services/drone/server/default.nix | 8 ++-- modules/nixos/services/flood/default.nix | 8 ++-- modules/nixos/services/gitea/default.nix | 12 +++--- modules/nixos/services/indexers/default.nix | 24 ++++++------ modules/nixos/services/jellyfin/default.nix | 8 ++-- modules/nixos/services/lohr/default.nix | 8 ++-- modules/nixos/services/matrix/default.nix | 20 +++++----- modules/nixos/services/miniflux/default.nix | 8 ++-- modules/nixos/services/monitoring/default.nix | 8 ++-- modules/nixos/services/navidrome/default.nix | 8 ++-- modules/nixos/services/nginx/default.nix | 38 +++++++++---------- modules/nixos/services/nix-cache/default.nix | 8 ++-- modules/nixos/services/paperless/default.nix | 8 ++-- modules/nixos/services/pirate/default.nix | 8 ++-- modules/nixos/services/podgrab/default.nix | 8 ++-- modules/nixos/services/sabnzbd/default.nix | 8 ++-- .../services/tandoor-recipes/default.nix | 8 ++-- .../nixos/services/transmission/default.nix | 8 ++-- modules/nixos/services/vikunja/default.nix | 8 ++-- .../services/woodpecker/server/default.nix | 12 +++--- 22 files changed, 118 insertions(+), 118 deletions(-) diff --git a/modules/nixos/services/blog/default.nix b/modules/nixos/services/blog/default.nix index 4b646c3..38ada5e 100644 --- a/modules/nixos/services/blog/default.nix +++ b/modules/nixos/services/blog/default.nix @@ -9,7 +9,7 @@ let root = "/var/www/${subdomain}"; }; - hostsInfo = map makeHostInfo [ "cv" "dev" "key" ]; + hostsInfo = lib.flip lib.genAttrs makeHostInfo [ "cv" "dev" "key" ]; in { options.my.services.blog = { diff --git a/modules/nixos/services/calibre-web/default.nix b/modules/nixos/services/calibre-web/default.nix index 858851c..fe53b7e 100644 --- a/modules/nixos/services/calibre-web/default.nix +++ b/modules/nixos/services/calibre-web/default.nix @@ -40,12 +40,12 @@ in # Set-up media group users.groups.media = { }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + library = { subdomain = "library"; inherit (cfg) port; - } - ]; + }; + }; my.services.backup = { paths = [ diff --git a/modules/nixos/services/drone/server/default.nix b/modules/nixos/services/drone/server/default.nix index d651f85..2207765 100644 --- a/modules/nixos/services/drone/server/default.nix +++ b/modules/nixos/services/drone/server/default.nix @@ -45,11 +45,11 @@ in }]; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + drone = { subdomain = "drone"; inherit (cfg) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/flood/default.nix b/modules/nixos/services/flood/default.nix index ff5d941..e227dde 100644 --- a/modules/nixos/services/flood/default.nix +++ b/modules/nixos/services/flood/default.nix @@ -40,11 +40,11 @@ in }; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + flood = { subdomain = "flood"; inherit (cfg) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/gitea/default.nix b/modules/nixos/services/gitea/default.nix index 00ba941..4d5429e 100644 --- a/modules/nixos/services/gitea/default.nix +++ b/modules/nixos/services/gitea/default.nix @@ -116,18 +116,18 @@ in }; users.groups.git = { }; - my.services.nginx.virtualHosts = [ + my.services.nginx.virtualHosts = { # Proxy to Gitea - { + git = { subdomain = "git"; inherit (cfg) port; - } + }; # Redirect `gitea.` to actual forge subdomain - { + gitea = { subdomain = "gitea"; redirect = config.services.gitea.settings.server.ROOT_URL; - } - ]; + }; + }; my.services.backup = { paths = [ diff --git a/modules/nixos/services/indexers/default.nix b/modules/nixos/services/indexers/default.nix index fb06a0b..ff2d91c 100644 --- a/modules/nixos/services/indexers/default.nix +++ b/modules/nixos/services/indexers/default.nix @@ -28,12 +28,12 @@ in }; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + jackett = { subdomain = "jackett"; port = jackettPort; - } - ]; + }; + }; }) (lib.mkIf cfg.nzbhydra.enable { @@ -41,12 +41,12 @@ in enable = true; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + nzbhydra = { subdomain = "nzbhydra"; port = nzbhydraPort; - } - ]; + }; + }; }) (lib.mkIf cfg.prowlarr.enable { @@ -54,12 +54,12 @@ in enable = true; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + prowlarr = { subdomain = "prowlarr"; port = prowlarrPort; - } - ]; + }; + }; services.fail2ban.jails = { prowlarr = '' diff --git a/modules/nixos/services/jellyfin/default.nix b/modules/nixos/services/jellyfin/default.nix index 2fcf51e..326dab3 100644 --- a/modules/nixos/services/jellyfin/default.nix +++ b/modules/nixos/services/jellyfin/default.nix @@ -17,8 +17,8 @@ in # Set-up media group users.groups.media = { }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + jellyfin = { subdomain = "jellyfin"; port = 8096; extraConfig = { @@ -33,7 +33,7 @@ in proxyWebsockets = true; }; }; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/lohr/default.nix b/modules/nixos/services/lohr/default.nix index 245567c..af292cc 100644 --- a/modules/nixos/services/lohr/default.nix +++ b/modules/nixos/services/lohr/default.nix @@ -98,11 +98,11 @@ in }; users.groups.lohr = { }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + lohr = { subdomain = "lohr"; inherit (cfg) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/matrix/default.nix b/modules/nixos/services/matrix/default.nix index 52b60c5..3328747 100644 --- a/modules/nixos/services/matrix/default.nix +++ b/modules/nixos/services/matrix/default.nix @@ -117,9 +117,9 @@ in }; }; - my.services.nginx.virtualHosts = [ + my.services.nginx.virtualHosts = { # Element Web app deployment - { + chat = { subdomain = "chat"; root = pkgs.element-web.override { conf = { @@ -145,22 +145,22 @@ in }; }; }; - } + }; # Dummy VHosts for port collision detection - { + matrix-federation = { subdomain = "matrix-federation"; port = federationPort.private; - } - { + }; + matrix-client = { subdomain = "matrix-client"; port = clientPort.private; - } + }; # Sliding sync - { + matrix-sync = { subdomain = "matrix-sync"; inherit (cfg.slidingSync) port; - } - ]; + }; + }; # Those are too complicated to use my wrapper... services.nginx.virtualHosts = { diff --git a/modules/nixos/services/miniflux/default.nix b/modules/nixos/services/miniflux/default.nix index 6d9ffc8..07eb6f8 100644 --- a/modules/nixos/services/miniflux/default.nix +++ b/modules/nixos/services/miniflux/default.nix @@ -43,11 +43,11 @@ in }; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + reader = { subdomain = "reader"; inherit (cfg) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/monitoring/default.nix b/modules/nixos/services/monitoring/default.nix index 829bfe0..2f23ff0 100644 --- a/modules/nixos/services/monitoring/default.nix +++ b/modules/nixos/services/monitoring/default.nix @@ -125,11 +125,11 @@ in ]; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + monitoring = { subdomain = "monitoring"; inherit (cfg.grafana) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/navidrome/default.nix b/modules/nixos/services/navidrome/default.nix index 6c001fd..92f9fd2 100644 --- a/modules/nixos/services/navidrome/default.nix +++ b/modules/nixos/services/navidrome/default.nix @@ -47,11 +47,11 @@ in }; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + music = { subdomain = "music"; inherit (cfg) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/nginx/default.nix b/modules/nixos/services/nginx/default.nix index 6ca2e42..53c947b 100644 --- a/modules/nixos/services/nginx/default.nix +++ b/modules/nixos/services/nginx/default.nix @@ -97,19 +97,19 @@ in }; virtualHosts = mkOption { - type = types.listOf virtualHostOption; - default = [ ]; + type = types.attrsOf virtualHostOption; + default = { }; example = litteralExample '' - [ - { - subdomain = "gitea"; + { + gitea = { + subdomain = "git"; port = 8080; - } - { + }; + dev = { subdomain = "dev"; root = "/var/www/dev"; - } - { + }; + jellyfin = { subdomain = "jellyfin"; port = 8096; extraConfig = { @@ -118,8 +118,8 @@ in proxyWebsockets = true; }; }; - } - ] + }; + } ''; description = '' List of virtual hosts to set-up using default settings. @@ -190,7 +190,7 @@ in config = lib.mkIf cfg.enable { assertions = [ ] - ++ (lib.flip builtins.map cfg.virtualHosts ({ subdomain, ... } @ args: + ++ (lib.flip lib.mapAttrsToList cfg.virtualHosts (_: { subdomain, ... } @ args: let conflicts = [ "port" "root" "socket" "redirect" ]; optionsNotNull = builtins.map (v: args.${v} != null) conflicts; @@ -209,7 +209,7 @@ in ports = lib.my.mapFilter (v: v != null) ({ port, ... }: port) - cfg.virtualHosts; + (lib.attrValues cfg.virtualHosts); portCounts = lib.my.countValues ports; nonUniquesCounts = lib.filterAttrs (_: v: v != 1) portCounts; nonUniques = builtins.attrNames nonUniquesCounts; @@ -221,7 +221,7 @@ in map mkAssertion nonUniques ) ++ ( let - subs = map ({ subdomain, ... }: subdomain) cfg.virtualHosts; + subs = lib.mapAttrsToList (_: { subdomain, ... }: subdomain) cfg.virtualHosts; subsCounts = lib.my.countValues subs; nonUniquesCounts = lib.filterAttrs (_: v: v != 1) subsCounts; nonUniques = builtins.attrNames nonUniquesCounts; @@ -325,7 +325,7 @@ in ]) ); in - lib.my.genAttrs' cfg.virtualHosts mkVHost; + lib.my.genAttrs' (lib.attrValues cfg.virtualHosts) mkVHost; sso = { enable = true; @@ -403,12 +403,12 @@ in }; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + login = { subdomain = "login"; inherit (cfg.sso) port; - } - ]; + }; + }; networking.firewall.allowedTCPPorts = [ 80 443 ]; diff --git a/modules/nixos/services/nix-cache/default.nix b/modules/nixos/services/nix-cache/default.nix index b3bdbf3..5517a78 100644 --- a/modules/nixos/services/nix-cache/default.nix +++ b/modules/nixos/services/nix-cache/default.nix @@ -43,11 +43,11 @@ in signKeyPath = cfg.secretKeyFile; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + cache = { subdomain = "cache"; inherit (cfg) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/paperless/default.nix b/modules/nixos/services/paperless/default.nix index 90f6b0c..87a816a 100644 --- a/modules/nixos/services/paperless/default.nix +++ b/modules/nixos/services/paperless/default.nix @@ -143,8 +143,8 @@ in extraGroups = [ "media" ]; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + paperless = { subdomain = "paperless"; inherit (cfg) port; sso = { @@ -155,8 +155,8 @@ in extraConfig = { locations."/".proxyWebsockets = true; }; - } - ]; + }; + }; my.services.backup = { paths = [ diff --git a/modules/nixos/services/pirate/default.nix b/modules/nixos/services/pirate/default.nix index 59f9794..88a2250 100644 --- a/modules/nixos/services/pirate/default.nix +++ b/modules/nixos/services/pirate/default.nix @@ -21,12 +21,12 @@ let }; mkRedirection = service: { - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + ${service} = { subdomain = service; port = ports.${service}; - } - ]; + }; + }; }; mkFail2Ban = service: lib.mkIf cfg.${service}.enable { diff --git a/modules/nixos/services/podgrab/default.nix b/modules/nixos/services/podgrab/default.nix index 9793d60..e59b20d 100644 --- a/modules/nixos/services/podgrab/default.nix +++ b/modules/nixos/services/podgrab/default.nix @@ -31,11 +31,11 @@ in inherit (cfg) passwordFile port; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + podgrab = { subdomain = "podgrab"; inherit (cfg) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/sabnzbd/default.nix b/modules/nixos/services/sabnzbd/default.nix index 7ab145f..42058e7 100644 --- a/modules/nixos/services/sabnzbd/default.nix +++ b/modules/nixos/services/sabnzbd/default.nix @@ -18,12 +18,12 @@ in # Set-up media group users.groups.media = { }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + sabnzbd = { subdomain = "sabnzbd"; inherit port; - } - ]; + }; + }; services.fail2ban.jails = { sabnzbd = '' diff --git a/modules/nixos/services/tandoor-recipes/default.nix b/modules/nixos/services/tandoor-recipes/default.nix index 541e198..353fac3 100644 --- a/modules/nixos/services/tandoor-recipes/default.nix +++ b/modules/nixos/services/tandoor-recipes/default.nix @@ -70,11 +70,11 @@ in ]; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + recipes = { subdomain = "recipes"; inherit (cfg) port; - } - ]; + }; + }; }; } diff --git a/modules/nixos/services/transmission/default.nix b/modules/nixos/services/transmission/default.nix index 28df477..ce7f9e6 100644 --- a/modules/nixos/services/transmission/default.nix +++ b/modules/nixos/services/transmission/default.nix @@ -80,12 +80,12 @@ in # Default transmission webui, I prefer combustion but its development # seems to have stalled - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + transmission = { subdomain = "transmission"; inherit (cfg) port; - } - ]; + }; + }; networking.firewall = { allowedTCPPorts = [ cfg.peerPort ]; diff --git a/modules/nixos/services/vikunja/default.nix b/modules/nixos/services/vikunja/default.nix index 8c051b0..425698d 100644 --- a/modules/nixos/services/vikunja/default.nix +++ b/modules/nixos/services/vikunja/default.nix @@ -59,8 +59,8 @@ in }; # This is a weird setup - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + vikunja = { inherit subdomain; # Serve the root for the web-ui root = config.services.vikunja.package-frontend; @@ -80,8 +80,8 @@ in }; }; }; - } - ]; + }; + }; systemd.services.vikunja-api = { serviceConfig = { diff --git a/modules/nixos/services/woodpecker/server/default.nix b/modules/nixos/services/woodpecker/server/default.nix index cebbc9b..b5ec0d8 100644 --- a/modules/nixos/services/woodpecker/server/default.nix +++ b/modules/nixos/services/woodpecker/server/default.nix @@ -52,16 +52,16 @@ in }]; }; - my.services.nginx.virtualHosts = [ - { + my.services.nginx.virtualHosts = { + woodpecker = { subdomain = "woodpecker"; inherit (cfg) port; - } + }; # I might want to be able to RPC from other hosts in the future - { + woodpecker-rpc = { subdomain = "woodpecker-rpc"; port = cfg.rpcPort; - } - ]; + }; + }; }; } From 5572b7b049c7a96c8bec4613ac5f052d8b665da8 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 25 Dec 2023 19:28:53 +0100 Subject: [PATCH 2/8] nixos: services: nginx: add default subdomain In almost all cases, the subdomain should be the same as the attribute name... --- modules/nixos/services/nginx/default.nix | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/nixos/services/nginx/default.nix b/modules/nixos/services/nginx/default.nix index 53c947b..e916c9c 100644 --- a/modules/nixos/services/nginx/default.nix +++ b/modules/nixos/services/nginx/default.nix @@ -5,10 +5,11 @@ let domain = config.networking.domain; - virtualHostOption = with lib; types.submodule { + virtualHostOption = with lib; types.submodule ({ name, ... }: { options = { subdomain = mkOption { type = types.str; + default = name; example = "dev"; description = '' Which subdomain, under config.networking.domain, to use @@ -72,7 +73,7 @@ let ''; }; }; - }; + }); in { imports = [ @@ -106,11 +107,9 @@ in port = 8080; }; dev = { - subdomain = "dev"; root = "/var/www/dev"; }; jellyfin = { - subdomain = "jellyfin"; port = 8096; extraConfig = { locations."/socket" = { From c2867b3483e4273b530129a3a6caa67d66646312 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 25 Dec 2023 19:42:20 +0100 Subject: [PATCH 3/8] nixos: services: remove redundant subdomains See previous commit for the defaults. --- modules/nixos/services/blog/default.nix | 1 - modules/nixos/services/calibre-web/default.nix | 1 - modules/nixos/services/drone/server/default.nix | 1 - modules/nixos/services/flood/default.nix | 1 - modules/nixos/services/gitea/default.nix | 2 -- modules/nixos/services/indexers/default.nix | 3 --- modules/nixos/services/jellyfin/default.nix | 1 - modules/nixos/services/lohr/default.nix | 1 - modules/nixos/services/matrix/default.nix | 4 ---- modules/nixos/services/miniflux/default.nix | 1 - modules/nixos/services/monitoring/default.nix | 1 - modules/nixos/services/navidrome/default.nix | 1 - modules/nixos/services/nginx/default.nix | 1 - modules/nixos/services/nix-cache/default.nix | 1 - modules/nixos/services/paperless/default.nix | 1 - modules/nixos/services/pirate/default.nix | 1 - modules/nixos/services/podgrab/default.nix | 1 - modules/nixos/services/sabnzbd/default.nix | 1 - modules/nixos/services/tandoor-recipes/default.nix | 1 - modules/nixos/services/transmission/default.nix | 1 - modules/nixos/services/vikunja/default.nix | 3 +-- modules/nixos/services/woodpecker/server/default.nix | 2 -- 22 files changed, 1 insertion(+), 30 deletions(-) diff --git a/modules/nixos/services/blog/default.nix b/modules/nixos/services/blog/default.nix index 38ada5e..3e68df2 100644 --- a/modules/nixos/services/blog/default.nix +++ b/modules/nixos/services/blog/default.nix @@ -5,7 +5,6 @@ let domain = config.networking.domain; makeHostInfo = subdomain: { - inherit subdomain; root = "/var/www/${subdomain}"; }; diff --git a/modules/nixos/services/calibre-web/default.nix b/modules/nixos/services/calibre-web/default.nix index fe53b7e..b7bf9df 100644 --- a/modules/nixos/services/calibre-web/default.nix +++ b/modules/nixos/services/calibre-web/default.nix @@ -42,7 +42,6 @@ in my.services.nginx.virtualHosts = { library = { - subdomain = "library"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/drone/server/default.nix b/modules/nixos/services/drone/server/default.nix index 2207765..a3a1e49 100644 --- a/modules/nixos/services/drone/server/default.nix +++ b/modules/nixos/services/drone/server/default.nix @@ -47,7 +47,6 @@ in my.services.nginx.virtualHosts = { drone = { - subdomain = "drone"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/flood/default.nix b/modules/nixos/services/flood/default.nix index e227dde..155e73d 100644 --- a/modules/nixos/services/flood/default.nix +++ b/modules/nixos/services/flood/default.nix @@ -42,7 +42,6 @@ in my.services.nginx.virtualHosts = { flood = { - subdomain = "flood"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/gitea/default.nix b/modules/nixos/services/gitea/default.nix index 4d5429e..4a8a3bb 100644 --- a/modules/nixos/services/gitea/default.nix +++ b/modules/nixos/services/gitea/default.nix @@ -119,12 +119,10 @@ in my.services.nginx.virtualHosts = { # Proxy to Gitea git = { - subdomain = "git"; inherit (cfg) port; }; # Redirect `gitea.` to actual forge subdomain gitea = { - subdomain = "gitea"; redirect = config.services.gitea.settings.server.ROOT_URL; }; }; diff --git a/modules/nixos/services/indexers/default.nix b/modules/nixos/services/indexers/default.nix index ff2d91c..8a42345 100644 --- a/modules/nixos/services/indexers/default.nix +++ b/modules/nixos/services/indexers/default.nix @@ -30,7 +30,6 @@ in my.services.nginx.virtualHosts = { jackett = { - subdomain = "jackett"; port = jackettPort; }; }; @@ -43,7 +42,6 @@ in my.services.nginx.virtualHosts = { nzbhydra = { - subdomain = "nzbhydra"; port = nzbhydraPort; }; }; @@ -56,7 +54,6 @@ in my.services.nginx.virtualHosts = { prowlarr = { - subdomain = "prowlarr"; port = prowlarrPort; }; }; diff --git a/modules/nixos/services/jellyfin/default.nix b/modules/nixos/services/jellyfin/default.nix index 326dab3..9efe11e 100644 --- a/modules/nixos/services/jellyfin/default.nix +++ b/modules/nixos/services/jellyfin/default.nix @@ -19,7 +19,6 @@ in my.services.nginx.virtualHosts = { jellyfin = { - subdomain = "jellyfin"; port = 8096; extraConfig = { locations."/" = { diff --git a/modules/nixos/services/lohr/default.nix b/modules/nixos/services/lohr/default.nix index af292cc..dd4eea8 100644 --- a/modules/nixos/services/lohr/default.nix +++ b/modules/nixos/services/lohr/default.nix @@ -100,7 +100,6 @@ in my.services.nginx.virtualHosts = { lohr = { - subdomain = "lohr"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/matrix/default.nix b/modules/nixos/services/matrix/default.nix index 3328747..bd2a017 100644 --- a/modules/nixos/services/matrix/default.nix +++ b/modules/nixos/services/matrix/default.nix @@ -120,7 +120,6 @@ in my.services.nginx.virtualHosts = { # Element Web app deployment chat = { - subdomain = "chat"; root = pkgs.element-web.override { conf = { default_server_config = { @@ -148,16 +147,13 @@ in }; # Dummy VHosts for port collision detection matrix-federation = { - subdomain = "matrix-federation"; port = federationPort.private; }; matrix-client = { - subdomain = "matrix-client"; port = clientPort.private; }; # Sliding sync matrix-sync = { - subdomain = "matrix-sync"; inherit (cfg.slidingSync) port; }; }; diff --git a/modules/nixos/services/miniflux/default.nix b/modules/nixos/services/miniflux/default.nix index 07eb6f8..5104c8b 100644 --- a/modules/nixos/services/miniflux/default.nix +++ b/modules/nixos/services/miniflux/default.nix @@ -45,7 +45,6 @@ in my.services.nginx.virtualHosts = { reader = { - subdomain = "reader"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/monitoring/default.nix b/modules/nixos/services/monitoring/default.nix index 2f23ff0..49919c1 100644 --- a/modules/nixos/services/monitoring/default.nix +++ b/modules/nixos/services/monitoring/default.nix @@ -127,7 +127,6 @@ in my.services.nginx.virtualHosts = { monitoring = { - subdomain = "monitoring"; inherit (cfg.grafana) port; }; }; diff --git a/modules/nixos/services/navidrome/default.nix b/modules/nixos/services/navidrome/default.nix index 92f9fd2..944a97a 100644 --- a/modules/nixos/services/navidrome/default.nix +++ b/modules/nixos/services/navidrome/default.nix @@ -49,7 +49,6 @@ in my.services.nginx.virtualHosts = { music = { - subdomain = "music"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/nginx/default.nix b/modules/nixos/services/nginx/default.nix index e916c9c..ae6c0dc 100644 --- a/modules/nixos/services/nginx/default.nix +++ b/modules/nixos/services/nginx/default.nix @@ -404,7 +404,6 @@ in my.services.nginx.virtualHosts = { login = { - subdomain = "login"; inherit (cfg.sso) port; }; }; diff --git a/modules/nixos/services/nix-cache/default.nix b/modules/nixos/services/nix-cache/default.nix index 5517a78..1ce3161 100644 --- a/modules/nixos/services/nix-cache/default.nix +++ b/modules/nixos/services/nix-cache/default.nix @@ -45,7 +45,6 @@ in my.services.nginx.virtualHosts = { cache = { - subdomain = "cache"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/paperless/default.nix b/modules/nixos/services/paperless/default.nix index 87a816a..c40e895 100644 --- a/modules/nixos/services/paperless/default.nix +++ b/modules/nixos/services/paperless/default.nix @@ -145,7 +145,6 @@ in my.services.nginx.virtualHosts = { paperless = { - subdomain = "paperless"; inherit (cfg) port; sso = { enable = true; diff --git a/modules/nixos/services/pirate/default.nix b/modules/nixos/services/pirate/default.nix index 88a2250..e500b54 100644 --- a/modules/nixos/services/pirate/default.nix +++ b/modules/nixos/services/pirate/default.nix @@ -23,7 +23,6 @@ let mkRedirection = service: { my.services.nginx.virtualHosts = { ${service} = { - subdomain = service; port = ports.${service}; }; }; diff --git a/modules/nixos/services/podgrab/default.nix b/modules/nixos/services/podgrab/default.nix index e59b20d..5ceebb6 100644 --- a/modules/nixos/services/podgrab/default.nix +++ b/modules/nixos/services/podgrab/default.nix @@ -33,7 +33,6 @@ in my.services.nginx.virtualHosts = { podgrab = { - subdomain = "podgrab"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/sabnzbd/default.nix b/modules/nixos/services/sabnzbd/default.nix index 42058e7..9e0d9c3 100644 --- a/modules/nixos/services/sabnzbd/default.nix +++ b/modules/nixos/services/sabnzbd/default.nix @@ -20,7 +20,6 @@ in my.services.nginx.virtualHosts = { sabnzbd = { - subdomain = "sabnzbd"; inherit port; }; }; diff --git a/modules/nixos/services/tandoor-recipes/default.nix b/modules/nixos/services/tandoor-recipes/default.nix index 353fac3..f5dc2db 100644 --- a/modules/nixos/services/tandoor-recipes/default.nix +++ b/modules/nixos/services/tandoor-recipes/default.nix @@ -72,7 +72,6 @@ in my.services.nginx.virtualHosts = { recipes = { - subdomain = "recipes"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/transmission/default.nix b/modules/nixos/services/transmission/default.nix index ce7f9e6..aeb88b7 100644 --- a/modules/nixos/services/transmission/default.nix +++ b/modules/nixos/services/transmission/default.nix @@ -82,7 +82,6 @@ in # seems to have stalled my.services.nginx.virtualHosts = { transmission = { - subdomain = "transmission"; inherit (cfg) port; }; }; diff --git a/modules/nixos/services/vikunja/default.nix b/modules/nixos/services/vikunja/default.nix index 425698d..9767d00 100644 --- a/modules/nixos/services/vikunja/default.nix +++ b/modules/nixos/services/vikunja/default.nix @@ -60,8 +60,7 @@ in # This is a weird setup my.services.nginx.virtualHosts = { - vikunja = { - inherit subdomain; + ${subdomain} = { # Serve the root for the web-ui root = config.services.vikunja.package-frontend; diff --git a/modules/nixos/services/woodpecker/server/default.nix b/modules/nixos/services/woodpecker/server/default.nix index b5ec0d8..f02a5c5 100644 --- a/modules/nixos/services/woodpecker/server/default.nix +++ b/modules/nixos/services/woodpecker/server/default.nix @@ -54,12 +54,10 @@ in my.services.nginx.virtualHosts = { woodpecker = { - subdomain = "woodpecker"; inherit (cfg) port; }; # I might want to be able to RPC from other hosts in the future woodpecker-rpc = { - subdomain = "woodpecker-rpc"; port = cfg.rpcPort; }; }; From a3c2135c2625f69d6ca293fd26a20e42cd1566ce Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Mon, 25 Dec 2023 19:43:44 +0100 Subject: [PATCH 4/8] nixos: services: nginx: fix SSO subdomain --- modules/nixos/services/nginx/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nixos/services/nginx/default.nix b/modules/nixos/services/nginx/default.nix index ae6c0dc..7980ad9 100644 --- a/modules/nixos/services/nginx/default.nix +++ b/modules/nixos/services/nginx/default.nix @@ -403,7 +403,7 @@ in }; my.services.nginx.virtualHosts = { - login = { + ${cfg.sso.subdomain} = { inherit (cfg.sso) port; }; }; From e42d611ebad8803a5889501f4304efc84144495b Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Sun, 24 Dec 2023 22:56:50 +0100 Subject: [PATCH 5/8] nixos: services: add pyload --- modules/nixos/services/default.nix | 1 + modules/nixos/services/pyload/default.nix | 66 +++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 modules/nixos/services/pyload/default.nix diff --git a/modules/nixos/services/default.nix b/modules/nixos/services/default.nix index b27570d..cb06808 100644 --- a/modules/nixos/services/default.nix +++ b/modules/nixos/services/default.nix @@ -26,6 +26,7 @@ ./podgrab ./postgresql ./postgresql-backup + ./pyload ./quassel ./rss-bridge ./sabnzbd diff --git a/modules/nixos/services/pyload/default.nix b/modules/nixos/services/pyload/default.nix new file mode 100644 index 0000000..e6a978f --- /dev/null +++ b/modules/nixos/services/pyload/default.nix @@ -0,0 +1,66 @@ +{ config, lib, ... }: +let + cfg = config.my.services.pyload; +in +{ + imports = [ + ./nixos.nix + ]; + + options.my.services.pyload = with lib; { + enable = mkEnableOption "pyload download manager"; + + credentialsFile = mkOption { + type = types.path; + example = "/run/secrets/pyload-credentials.env"; + description = "pyload credentials"; + }; + + downloadDirectory = mkOption { + type = types.str; + default = "/data/downloads"; + example = "/var/lib/pyload/download"; + description = "Download directory"; + }; + + port = mkOption { + type = types.port; + default = 9093; + example = 8080; + description = "Internal port for webui"; + }; + }; + + config = lib.mkIf cfg.enable { + services.pyload = { + enable = true; + + # Listening on `localhost` leads to 502 with the reverse proxy... + listenAddress = "127.0.0.1"; + + inherit (cfg) + credentialsFile + downloadDirectory + port + ; + }; + + # User media group when downloading files + systemd. services. pyload = { + serviceConfig = { + Group = lib.mkForce "media"; + }; + }; + + # Set-up media group + users.groups.media = { }; + + my.services.nginx.virtualHosts = { + pyload = { + inherit (cfg) port; + }; + }; + + # FIXME: fail2ban + }; +} From cd96ffe5ee01e0bd3c69e4abeb601b4003402ad5 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Sun, 24 Dec 2023 22:57:37 +0100 Subject: [PATCH 6/8] hosts: nixos: porthos: secrets: add pyload creds --- hosts/nixos/porthos/secrets/pyload/credentials.age | 7 +++++++ hosts/nixos/porthos/secrets/secrets.nix | 2 ++ 2 files changed, 9 insertions(+) create mode 100644 hosts/nixos/porthos/secrets/pyload/credentials.age diff --git a/hosts/nixos/porthos/secrets/pyload/credentials.age b/hosts/nixos/porthos/secrets/pyload/credentials.age new file mode 100644 index 0000000..089f962 --- /dev/null +++ b/hosts/nixos/porthos/secrets/pyload/credentials.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 cKojmg nJbOfp0/wmFOZLzcWjoGB7wEB8e56aO1NntSmn5KomU +/Vio4Z/t7IPJrdzdwUPidVH3wrouSkwRzNHP0T4z3x0 +-> ssh-ed25519 jPowng QXg/xqs7/VfkYQg3X77w4i53q64bL9oYeTxqb9NVhiQ +sMHIXlmrIxtIr+s0X4lBqev/PPd3AKD5P7AP5K4NeJg +--- gzTn+6+aa4Ptic1lsvSt+r3IEBysHrvMMIyONogMDF0 +ˮUE_ Date: Sun, 24 Dec 2023 22:58:03 +0100 Subject: [PATCH 7/8] hosts: nixos: porthos: services: enable pyload --- hosts/nixos/porthos/services.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hosts/nixos/porthos/services.nix b/hosts/nixos/porthos/services.nix index d73cdc1..2486752 100644 --- a/hosts/nixos/porthos/services.nix +++ b/hosts/nixos/porthos/services.nix @@ -134,6 +134,10 @@ in }; # Regular backups postgresql-backup.enable = true; + pyload = { + enable = true; + credentialsFile = secrets."pyload/credentials".path; + }; # RSS provider for websites that do not provide any feeds rss-bridge.enable = true; # Usenet client From 99cdb697f156fb4f917e87cf24f0424d6bb735d3 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Sun, 24 Dec 2023 22:58:18 +0100 Subject: [PATCH 8/8] WIP: WAITING FOR NIXPKS UPDATE --- modules/nixos/services/pyload/nixos.nix | 144 ++++++++++++++++++ .../declarative-config.patch | 18 +++ .../declarative-default-user.patch | 15 ++ .../default.nix | 4 + .../package.nix | 60 ++++++++ 5 files changed, 241 insertions(+) create mode 100644 modules/nixos/services/pyload/nixos.nix create mode 100644 overlays/pyload-declarative-user-management/declarative-config.patch create mode 100644 overlays/pyload-declarative-user-management/declarative-default-user.patch create mode 100644 overlays/pyload-declarative-user-management/default.nix create mode 100644 overlays/pyload-declarative-user-management/package.nix diff --git a/modules/nixos/services/pyload/nixos.nix b/modules/nixos/services/pyload/nixos.nix new file mode 100644 index 0000000..5ce7d7c --- /dev/null +++ b/modules/nixos/services/pyload/nixos.nix @@ -0,0 +1,144 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.pyload; + + stateDir = "/var/lib/pyload"; + userDir = "${stateDir}/config"; +in +{ + options = with lib; { + services.pyload = { + enable = mkEnableOption "pyload download manager"; + + package = mkPackageOption pkgs "pyload-ng" { }; + + listenAddress = mkOption { + type = types.str; + default = "localhost"; + example = "0.0.0.0"; + description = "Address to listen on for the web UI."; + }; + + port = mkOption { + type = types.port; + default = 8000; + example = 9876; + description = "Port to listen on for the web UI."; + }; + + downloadDirectory = mkOption { + type = types.path; + default = "${stateDir}/downloads"; + example = "/mnt/downloads"; + description = "Directory to store downloads"; + }; + + credentialsFile = mkOption { + type = with types; nullOr path; + default = null; + example = "/run/secrets/pyload-credentials.env"; + description = '' + File containing PYLOAD_DEFAULT_USERNAME and PYLOAD_DEFAULT_PASSWORD + in the format of an EnvironmentFile=, as described by systemd.exec(5). + + If not given, they default to the username/password combo of + pyload/pyload. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.tmpfiles.rules = [ + "d ${cfg.downloadDirectory}" + ]; + + systemd.services.pyload = { + description = "pyload service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + # NOTE: unlike what the documentation says, it looks like `HOME` is not + # defined with this service definition... + # Since pyload tries to do the equivalent of `cd ~`, it needs to be able + # to resolve $HOME, which fails when `RootDirectory` is set. + # FIXME: check if `SetLoginEnvironment` fixes this issue in version 255 + environment = { + HOME = stateDir; + PYLOAD__WEBUI__HOST = cfg.listenAddress; + PYLOAD__WEBUI__PORT = builtins.toString cfg.port; + }; + + serviceConfig = { + # FIXME: use getExe + ExecStart = "${lib.getExe' cfg.package "pyload"} ${lib.escapeShellArgs [ + "--userdir" userDir + "--storagedir" cfg.downloadDirectory + ]}"; + + User = "pyload"; + Group = "pyload"; + DynamicUser = true; + + EnvironmentFile = lib.optional (cfg.credentialsFile != null) cfg.credentialsFile; + + StateDirectory = "pyload"; + WorkingDirectory = stateDir; + RuntimeDirectory = "pyload"; + RuntimeDirectoryMode = "0700"; + RootDirectory = "/run/pyload"; + BindReadOnlyPaths = [ + builtins.storeDir # Needed to run the python interpreter + ]; + BindPaths = [ + cfg.downloadDirectory + ]; + + # Hardening options + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RemoveIPC = true; + RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX"; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" "~@resources" "~@privileged" ]; + UMask = "0002"; + CapabilityBoundingSet = [ + "~CAP_BLOCK_SUSPEND" + "~CAP_BPF" + "~CAP_CHOWN" + "~CAP_IPC_LOCK" + "~CAP_KILL" + "~CAP_LEASE" + "~CAP_LINUX_IMMUTABLE" + "~CAP_NET_ADMIN" + "~CAP_SYS_ADMIN" + "~CAP_SYS_BOOT" + "~CAP_SYS_CHROOT" + "~CAP_SYS_NICE" + "~CAP_SYS_PACCT" + "~CAP_SYS_PTRACE" + "~CAP_SYS_RESOURCE" + "~CAP_SYS_TTY_CONFIG" + ]; + }; + }; + }; +} diff --git a/overlays/pyload-declarative-user-management/declarative-config.patch b/overlays/pyload-declarative-user-management/declarative-config.patch new file mode 100644 index 0000000..42f89ee --- /dev/null +++ b/overlays/pyload-declarative-user-management/declarative-config.patch @@ -0,0 +1,18 @@ +diff --git a/src/pyload/core/__init__.py b/src/pyload/core/__init__.py +index 4324fc700..5d915a85e 100644 +--- a/src/pyload/core/__init__.py ++++ b/src/pyload/core/__init__.py +@@ -128,6 +128,13 @@ class Core: + else: + self._debug = max(0, int(debug)) + ++ # Allow setting any option declaratively, for the NixOS module ++ for env, value in os.environ.items(): ++ if not env.startswith("PYLOAD__"): ++ continue ++ section, opt = env.removeprefix("PYLOAD__").lower().split("__") ++ self.config.set(section, opt, value) ++ + # If no argument set, read storage dir from config file, + # otherwise save setting to config dir + if storagedir is None: diff --git a/overlays/pyload-declarative-user-management/declarative-default-user.patch b/overlays/pyload-declarative-user-management/declarative-default-user.patch new file mode 100644 index 0000000..3c3e6f4 --- /dev/null +++ b/overlays/pyload-declarative-user-management/declarative-default-user.patch @@ -0,0 +1,15 @@ +diff --git a/src/pyload/core/__init__.py b/src/pyload/core/__init__.py +index 4324fc700..f7fcd66ec 100644 +--- a/src/pyload/core/__init__.py ++++ b/src/pyload/core/__init__.py +@@ -46,8 +46,8 @@ class Exit(Exception): + # improve external scripts + class Core: + LOCALE_DOMAIN = APPID +- DEFAULT_USERNAME = APPID +- DEFAULT_PASSWORD = APPID ++ DEFAULT_USERNAME = os.getenv("PYLOAD_DEFAULT_USERNAME", APPID) ++ DEFAULT_PASSWORD = os.getenv("PYLOAD_DEFAULT_PASSWORD", APPID) + DEFAULT_DATADIR = os.path.join( + os.getenv("APPDATA") or USERHOMEDIR, "pyLoad" if os.name == "nt" else ".pyload" + ) diff --git a/overlays/pyload-declarative-user-management/default.nix b/overlays/pyload-declarative-user-management/default.nix new file mode 100644 index 0000000..475f126 --- /dev/null +++ b/overlays/pyload-declarative-user-management/default.nix @@ -0,0 +1,4 @@ +self: _super: +{ + pyload-ng = self.callPackage ./package.nix { }; +} diff --git a/overlays/pyload-declarative-user-management/package.nix b/overlays/pyload-declarative-user-management/package.nix new file mode 100644 index 0000000..4daa125 --- /dev/null +++ b/overlays/pyload-declarative-user-management/package.nix @@ -0,0 +1,60 @@ +{ lib, fetchPypi, python3 }: + +python3.pkgs.buildPythonApplication rec { + version = "0.5.0b3.dev75"; + pname = "pyload-ng"; + pyproject = true; + + src = fetchPypi { + inherit pname version; + hash = "sha256-1lPIKkZESonDaVCnac0iUu/gCqXVDBhNZrk5S0eC6F0="; + }; + + patches = [ + # Makes it possible to change the default username/password in the module + ./declarative-default-user.patch + ./declarative-config.patch + ]; + + postPatch = '' + # relax version bounds + sed -i 's/\([A-z0-9]*\)~=.*$/\1/' setup.cfg + # not sure what Flask-Session2 is but flask-session works just fine + sed -i '/Flask-Session2/d' setup.cfg + ''; + + propagatedBuildInputs = with python3.pkgs; [ + bitmath + certifi + cheroot + cryptography + filetype + flask + flask-babel + flask-caching + flask-compress + flask-session + flask-themes2 + js2py + pycurl + semver + setuptools + ]; + + passthru.optional-dependencies = { + plugins = with python3.pkgs; [ + beautifulsoup4 # for some plugins + colorlog # colorful console logging + pillow # for some CAPTCHA plugin + send2trash # send some files to trash instead of deleting them + slixmpp # XMPP plugin + ]; + }; + + meta = with lib; { + description = "Free and open-source download manager with support for 1-click-hosting sites"; + homepage = "https://github.com/pyload/pyload"; + license = licenses.agpl3Plus; + maintainers = with maintainers; [ ruby0b ]; + }; +}