zaphyra's git: nixfiles

zaphyra's nixfiles

commit 434d3a53effaf621b9796191f22382096a2de177
parent b0bae4159a44b9dde31f5563925e37c0c0b08a43
Author: Katja Ramona Sophie Kwast (zaphyra) <git@zaphyra.eu>
Date: Sat, 6 Sep 2025 11:08:15 +0200

treewide: remove pipe-operator
16 files changed, 553 insertions(+), 510 deletions(-)
M
config/home-manager/zaphyra/configure/gnome.nix
|
11
+++++------
M
config/home-manager/zaphyra/programs/firefox.nix
|
140
++++++++++++++++++++++++++++++++++++++++----------------------------------------
M
config/home-manager/zaphyra/services/wpaperd.nix
|
31
+++++++++++++++----------------
M
config/nixos/dns.nix
|
24
+++++++++++-------------
M
config/nixos/modules/filesystem/rootDisk.nix
|
9
++++-----
M
config/nixos/modules/networking/dn42.nix
|
256
+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
M
config/nixos/modules/nix/enable.nix
|
2
+-
M
config/nixos/modules/presets/zaphyra/dnsServer.nix
|
15
++++++---------
M
config/nixos/modules/presets/zaphyra/enable.nix
|
19
++++++++++---------
M
config/nixos/modules/presets/zaphyra/syncthing.nix
|
18
++++++++++--------
M
config/nixos/modules/services/knot.nix
|
61
++++++++++++++++++++++++++++++++-----------------------------
M
config/nixos/modules/services/knotACME.nix
|
82
++++++++++++++++++++++++++++++++++++++-----------------------------------------
M
config/nixos/modules/services/resticBackup.nix
|
167
+++++++++++++++++++++++++++++++++++++------------------------------------------
M
config/nixos/modules/websites/gts.zaphyra.eu.nix
|
151
++++++++++++++++++++++++++++++++++++++++---------------------------------------
M
config/nixosModules.nix
|
7
++++---
M
flake.nix
|
70
++++++++++++++++++++++++++++++++++++++--------------------------------
diff --git a/config/home-manager/zaphyra/configure/gnome.nix b/config/home-manager/zaphyra/configure/gnome.nix
@@ -69,13 +69,12 @@ in
     with inputs.homeManager.lib.hm.gvariant;
     let
       numWorkspaces = 7;
-      workspaces = (
-        numWorkspaces
-        |> nixStd.list.unfold (
+      workspaces = lib.pipe numWorkspaces [
+        (nixStd.list.unfold (
           n: if n == 0 then nixStd.optional.nothing else nixStd.optional.just (nixStd.tuple.tuple2 n (n - 1))
-        )
-        |> lib.lists.reverseList
-      );
+        ))
+        lib.lists.reverseList
+      ];
     in
     {
       "org/gnome/mutter" = {
diff --git a/config/home-manager/zaphyra/programs/firefox.nix b/config/home-manager/zaphyra/programs/firefox.nix
@@ -173,7 +173,11 @@
           };
         };
       }
-      // (
+      // (lib.mapAttrs
+        (name: value: {
+          Status = "locked";
+          Value = value;
+        })
         {
           # disable some password-manager/autofill features
           "signon.generation.enabled" = false;

@@ -215,79 +219,75 @@
           "browser.newtabpage.activity-stream.section.highlights.includeDownloads" = false;
           "browser.newtabpage.activity-stream.section.highlights.includeVisited" = false;
         }
-        |> lib.mapAttrs (
-          name: value: {
-            Status = "locked";
-            Value = value;
-          }
-        )
       );
 
-      ExtensionSettings = (
-        [
-          [
-            "navbar"
-            "{446900e4-71c2-419f-a6a7-df9c091e268b}"
-          ] # Bitwarden Password Manager
-          [
-            "navbar"
-            "uBlock0@raymondhill.net"
-          ] # uBlock Origin
-          [
-            "menupanel"
-            "@ublacklist"
-          ] # uBlacklist
-          [
-            "menupanel"
-            "@contain-facebook"
-          ] # Facebook Container
-          [
-            "menupanel"
-            "@contain-google"
-          ] # Google Container
-          [
-            "menupanel"
-            "containerise@kinte.sh"
-          ] # Containerise
-          [
-            "menupanel"
-            "{12cf650b-1822-40aa-bff0-996df6948878}"
-          ] # cookies.txt
+      ExtensionSettings =
+        lib.pipe
           [
-            "menupanel"
-            "@testpilot-containers"
-          ] # Firefox Multi-Account Containers
+            [
+              "navbar"
+              "{446900e4-71c2-419f-a6a7-df9c091e268b}"
+            ] # Bitwarden Password Manager
+            [
+              "navbar"
+              "uBlock0@raymondhill.net"
+            ] # uBlock Origin
+            [
+              "menupanel"
+              "@ublacklist"
+            ] # uBlacklist
+            [
+              "menupanel"
+              "@contain-facebook"
+            ] # Facebook Container
+            [
+              "menupanel"
+              "@contain-google"
+            ] # Google Container
+            [
+              "menupanel"
+              "containerise@kinte.sh"
+            ] # Containerise
+            [
+              "menupanel"
+              "{12cf650b-1822-40aa-bff0-996df6948878}"
+            ] # cookies.txt
+            [
+              "menupanel"
+              "@testpilot-containers"
+            ] # Firefox Multi-Account Containers
+            [
+              "menupanel"
+              "{252ee273-8c8d-4609-b54d-62ae345be0a1}"
+            ] # IndicateTLS
+            [
+              "menupanel"
+              "ipvfoo@pmarks.net"
+            ] # IPvFoo
+            [
+              "menupanel"
+              "{e9090647-32ff-48e4-9c3c-1361e8fd270e}"
+            ] # Modern for Wikipedia
+            [
+              "menupanel"
+              "sponsorBlocker@ajay.app"
+            ] # SponsorBlock for YouTube - Skip Sponsorships
+            [
+              "menupanel"
+              "de-DE@dictionaries.addons.mozilla.org"
+            ] # German Dictionary
+          ]
           [
-            "menupanel"
-            "{252ee273-8c8d-4609-b54d-62ae345be0a1}"
-          ] # IndicateTLS
-          [
-            "menupanel"
-            "ipvfoo@pmarks.net"
-          ] # IPvFoo
-          [
-            "menupanel"
-            "{e9090647-32ff-48e4-9c3c-1361e8fd270e}"
-          ] # Modern for Wikipedia
-          [
-            "menupanel"
-            "sponsorBlocker@ajay.app"
-          ] # SponsorBlock for YouTube - Skip Sponsorships
-          [
-            "menupanel"
-            "de-DE@dictionaries.addons.mozilla.org"
-          ] # German Dictionary
-        ]
-        |> lib.map (config: {
-          name = (lib.elemAt config 1);
-          value = {
-            installation_mode = "normal_installed";
-            default_area = (lib.elemAt config 0);
-            install_url = "https://addons.mozilla.org/firefox/downloads/latest/${lib.elemAt config 1}/latest.xpi";
-          };
-        })
-        |> lib.listToAttrs
-      );
+            (lib.map (config: {
+              name = (lib.elemAt config 1);
+              value = {
+                installation_mode = "normal_installed";
+                default_area = (lib.elemAt config 0);
+                install_url = "https://addons.mozilla.org/firefox/downloads/latest/${lib.elemAt config 1}/latest.xpi";
+              };
+            }))
+            lib.listToAttrs
+          ];
     };
   };
 
diff --git a/config/home-manager/zaphyra/services/wpaperd.nix b/config/home-manager/zaphyra/services/wpaperd.nix
@@ -18,27 +18,26 @@
         duration = "30m";
         mode = "center";
         sorting = "ascending";
-        transition.hexagonalize = { };
+        transition.bounce = { };
       };
 
       any.path = pkgs.buildEnv {
         name = "nixos-artwork";
-        paths = (
-          pkgs.nixos-artwork.wallpapers
-          |> lib.attrNames
-          |> lib.remove "override"
-          |> lib.remove "overrideDerivation"
+        paths = lib.pipe pkgs.nixos-artwork.wallpapers [
+          lib.attrNames
+          (lib.remove "override")
+          (lib.remove "overrideDerivation")
           # removed because too bright
-          |> lib.remove "binary-white"
-          |> lib.remove "catppuccin-latte"
-          |> lib.remove "moonscape"
-          |> lib.remove "nineish-catppuccin-latte"
-          |> lib.remove "nineish-catppuccin-latte-alt"
-          |> lib.remove "nineish-solarized-light"
-          |> lib.remove "nineish"
-          |> lib.remove "simple-light-gray"
-          |> map (name: "${pkgs.nixos-artwork.wallpapers.${name}}/share/backgrounds/nixos")
-        );
+          (lib.remove "binary-white")
+          (lib.remove "catppuccin-latte")
+          (lib.remove "moonscape")
+          (lib.remove "nineish-catppuccin-latte")
+          (lib.remove "nineish-catppuccin-latte-alt")
+          (lib.remove "nineish-solarized-light")
+          (lib.remove "nineish")
+          (lib.remove "simple-light-gray")
+          (map (name: "${pkgs.nixos-artwork.wallpapers.${name}}/share/backgrounds/nixos"))
+        ];
       };
     };
   };
diff --git a/config/nixos/dns.nix b/config/nixos/dns.nix
@@ -35,26 +35,24 @@ in
     zoneFiles = {
       type = types.attrsOf types.path;
       readOnly = true;
-      default = (
-        cfg.allZones
-        |> lib.mapAttrs (
-          name: zone:
-          toString (
-            pkgs.writeTextFile {
-              name = "${name}.zone";
-              text = dnsNix.types.zoneToString name (dnsNix.evalZone name zone);
-            }
-          )
+      default = lib.mapAttrs (
+        name: zone:
+        toString (
+          pkgs.writeTextFile {
+            name = "${name}.zone";
+            text = dnsNix.types.zoneToString name (dnsNix.evalZone name zone);
+          }
         )
-      );
+      ) cfg.allZones;
     };
   };
 
   config = lib.mkIf cfg.enable {
     # serve records defined in all host configs
     dns.allZones = lib.mkMerge (
-      inputs.self.nixosConfigurations
-      |> lib.mapAttrsToList (hostName: hostConfig: hostConfig.config.dns.zones)
+      lib.mapAttrsToList (
+        hostName: hostConfig: hostConfig.config.dns.zones
+      ) inputs.self.nixosConfigurations
     );
   };
 
diff --git a/config/nixos/modules/filesystem/rootDisk.nix b/config/nixos/modules/filesystem/rootDisk.nix
@@ -10,11 +10,10 @@
 let
   inherit (lib) types;
   cfg = lib.getAttrFromPath povSelf config;
-  users = (
-    config.modules.users
-    |> lib.mapAttrsToList (name: value: if value.enable then name else null)
-    |> lib.filter (element: !builtins.isNull element)
-  );
+  users = lib.pipe config.modules.users [
+    (lib.mapAttrsToList (name: value: if value.enable then name else null))
+    (lib.filter (element: !builtins.isNull element))
+  ];
   part =
     name: content:
     if cfg.encrypt then
diff --git a/config/nixos/modules/networking/dn42.nix b/config/nixos/modules/networking/dn42.nix
@@ -55,6 +55,23 @@ in
           };
         });
     };
+    babel.enable = {
+      type = types.bool;
+      default = false;
+    };
+    babel.peerings = {
+      default = { };
+      type =
+        with types;
+        attrsOf (submodule {
+          options = {
+            type = lib.mkOption {
+              type = types.str;
+              default = "tunnel";
+            };
+          };
+        });
+    };
   };
 
   config = lib.mkIf cfg.enable {

@@ -64,9 +81,8 @@ in
 
     systemd.services.systemd-networkd.after = [ "sops-install-secrets.service" ];
 
-    sops.secrets = (
-      cfg.peerings
-      |> lib.mapAttrsToList (
+    sops.secrets = lib.pipe cfg.peerings [
+      (lib.mapAttrsToList (
         name: peerConfig:
         [
           (lib.nameValuePair "dn42/peerings/${name}/wgPrivateKey" {

@@ -80,10 +96,10 @@ in
             group = "systemd-network";
           })
         ]
-      )
-      |> lib.lists.flatten
-      |> lib.listToAttrs
-    );
+      ))
+      lib.lists.flatten
+      lib.listToAttrs
+    ];
 
     systemd.network = {
       netdevs = lib.mapAttrs' (

@@ -93,14 +109,13 @@ in
             Kind = "wireguard";
             Name = "dn42${name}";
           };
-          wireguardConfig =
-            {
-              ListenPort = peerConfig.listenPort;
-              PrivateKeyFile = config.sops.secrets."dn42/peerings/${name}/wgPrivateKey".path;
-            }
-            // (lib.optionalAttrs peerConfig.hasPresharedKey {
-              PresharedKeyFile = config.sops.secrets."dn42/peerings/${name}/wgPresharedKey".path;
-            });
+          wireguardConfig = {
+            ListenPort = peerConfig.listenPort;
+            PrivateKeyFile = config.sops.secrets."dn42/peerings/${name}/wgPrivateKey".path;
+          }
+          // (lib.optionalAttrs peerConfig.hasPresharedKey {
+            PresharedKeyFile = config.sops.secrets."dn42/peerings/${name}/wgPresharedKey".path;
+          });
           wireguardPeers = [
             {
               PersistentKeepalive = 30;

@@ -156,116 +171,149 @@ in
 
         cat -n bird.conf # here for debugging purposes
       '';
-      config =
-        ''
-          log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };
-          log stderr all;
+      config = ''
+        log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };
+        log stderr all;
 
-          define OWNAS = ${toString cfg.asn};
-          define OWNNET = ${cfg.range};
-          define OWNNETSET = [ ${cfg.range} ];
-          define OWNIP = ${cfg.address};
+        define OWNAS = ${toString cfg.asn};
+        define OWNNET = ${cfg.range};
+        define OWNNETSET = [ ${cfg.range} ];
+        define OWNIP = ${cfg.address};
 
-          router id ${toString cfg.routerId};
-          hostname "${config.networking.hostName}";
+        router id ${toString cfg.routerId};
+        hostname "${config.networking.hostName}";
 
-          roa6 table dn42_roa;
+        roa6 table dn42_roa;
 
-          function is_self_net() -> bool {
-            return net ~ OWNNETSET;
-          }
-
-          function is_valid_network() -> bool {
-            return net ~ [
-              fd00::/8{44,64}
-            ];
-          }
+        function is_self_net() -> bool {
+          return net ~ OWNNETSET;
+        }
 
-          function import_filter() {
-            if (net.type != NET_IP6 || ! is_valid_network() || is_self_net()) then
-              reject;
+        function is_valid_network() -> bool {
+          return net ~ [
+            fd00::/8{44,64}
+          ];
+        }
 
-            if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
-              # Reject when unknown or invalid according to ROA
-              print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
-              reject;
-            }
+        function import_filter() {
+          if (net.type != NET_IP6 || ! is_valid_network() || is_self_net()) then
+            reject;
 
-            accept;
+          if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
+            # Reject when unknown or invalid according to ROA
+            print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
+            reject;
           }
 
-          function export_filter() {
-            if ( ! is_valid_network() ) then
-              reject;
+          accept;
+        }
 
-            if (source !~ [RTS_STATIC, RTS_BGP]) then
-              reject;
+        function export_filter() {
+          if ( ! is_valid_network() ) then
+            reject;
 
-            accept;
-          }
+          if (source !~ [RTS_STATIC, RTS_BGP]) then
+            reject;
 
-          protocol rpki {
-            roa6 { table dn42_roa; };
-            remote ::1;
-            port 8282;
-            refresh 600;
-            retry 300;
-            expire 7200;
-          }
+          accept;
+        }
 
-          protocol device {
-            scan time 10;
-          }
+        protocol rpki {
+          roa6 { table dn42_roa; };
+          remote ::1;
+          port 8282;
+          refresh 600;
+          retry 300;
+          expire 7200;
+        }
 
-          protocol static {
-            route OWNNET unreachable;
+        protocol device {
+          scan time 10;
+        }
 
-            ipv6 {
-              import all;
-              export none;
-            };
-          }
+        protocol static {
+          route OWNNET unreachable;
 
-          protocol kernel {
-            scan time 20;
-
-            ipv6 {
-              import none;
-              export filter {
-                # dont export static routes
-                if source = RTS_STATIC then reject;
-                # preferred outgoing source address
-                krt_prefsrc = OWNIP;
-                accept;
-              };
+          ipv6 {
+            import all;
+            export none;
+          };
+        }
+
+        protocol kernel {
+          scan time 20;
+
+          ipv6 {
+            import none;
+            export filter {
+              # dont export static routes
+              if source = RTS_STATIC then reject;
+              # preferred outgoing source address
+              krt_prefsrc = OWNIP;
+              accept;
             };
-          }
+          };
+        }
 
-          template bgp dn42_peers {
-            local as OWNAS;
-            path metric 1;
-            advertise hostname on;
-            enforce first as on;
-            med metric on;
+        template bgp dn42_peers {
+          local as OWNAS;
+          path metric 1;
+          advertise hostname on;
+          enforce first as on;
+          med metric on;
 
-            ipv6 {
-              import keep filtered;
-              import limit 9000 action block;
-              import where import_filter();
-              next hop self; # advertise this router as next hop
+          ipv6 {
+            import keep filtered;
+            import limit 9000 action block;
+            import where import_filter();
+            next hop self; # advertise this router as next hop
 
-              export where export_filter();
-            };
+            export where export_filter();
+          };
+        }
+      ''
+      + (lib.concatStringsSep "\n" (
+        lib.mapAttrsToList (name: peerConfig: ''
+          protocol bgp ${name} from dn42_peers {
+            neighbor ${peerConfig.remoteLinkLocalAddress}%dn42${name} as ${toString peerConfig.asn};
+            enable extended messages;
           }
-        ''
-        + (lib.concatStringsSep "\n" (
-          lib.mapAttrsToList (name: peerConfig: ''
-            protocol bgp ${name} from dn42_peers {
-              neighbor ${peerConfig.remoteLinkLocalAddress}%dn42${name} as ${toString peerConfig.asn};
-              enable extended messages;
-            }
-          '') cfg.peerings
-        ));
+        '') cfg.peerings
+      ))
+      + (lib.optionalString cfg.babel.enable ''
+        /* babel config */
+        protocol direct {
+          ipv6 {
+            import where net ~ [ fd00::/8+ ];
+            export where net ~ [ fd00::/8+ ];
+          };
+
+          ${lib.concatStringsSep "\n" (
+            lib.mapAttrsToList (name: peerConfig: ''
+              interface "${name}";
+            '') cfg.babel.peerings
+          )}
+        };
+
+        protocol babel {
+          randomize router id on;
+
+          ipv6 {
+            import where source != RTS_BGP && is_self_net();
+            export where source != RTS_BGP && is_self_net();
+          };
+
+          ${lib.concatStringsSep "\n" (
+            lib.mapAttrsToList (name: peerConfig: ''
+              interface "${name}" {
+                type ${peerConfig.type};
+                next hop prefer ipv6;
+              };
+            '') cfg.babel.peerings
+          )}
+        };
+        /* End of babel config */
+      '');
     };
   };
 
diff --git a/config/nixos/modules/nix/enable.nix b/config/nixos/modules/nix/enable.nix
@@ -35,7 +35,7 @@ in
           experimental-features = [
             "flakes"
             "nix-command"
-            "pipe-operator"
+            # "pipe-operator"
           ];
         };
       };
diff --git a/config/nixos/modules/presets/zaphyra/dnsServer.nix b/config/nixos/modules/presets/zaphyra/dnsServer.nix
@@ -156,15 +156,12 @@ in
           enable = true;
           primary = cfg.isPrimary;
           zones = lib.mkIf cfg.isPrimary (
-            config.dns.zoneFiles
-            |> lib.mapAttrs (
-              name: value: {
-                file = value;
-                journal-content = "all";
-                zonefile-sync = -1;
-                zonefile-load = "difference-no-serial";
-              }
-            )
+            lib.mapAttrs (name: value: {
+              file = value;
+              journal-content = "all";
+              zonefile-sync = -1;
+              zonefile-load = "difference-no-serial";
+            }) config.dns.zoneFiles
           );
         };
         knotACME = lib.mkIf cfg.isPrimary {
diff --git a/config/nixos/modules/presets/zaphyra/enable.nix b/config/nixos/modules/presets/zaphyra/enable.nix
@@ -91,15 +91,16 @@ in
             certs."${config.networking.fqdn}" = {
               group = lib.mkIf config.services.nginx.enable "nginx";
               extraDomainNames = (
-                config.services.nginx.virtualHosts
-                |> lib.mapAttrsToList (
-                  key: config: [
-                    (if config ? serverAliases then config.serverAliases else [ ])
-                    key
-                  ]
-                )
-                |> lib.flatten
-                |> lib.filter (domain: !(lib.hasSuffix "dn42" domain))
+                lib.pipe config.services.nginx.virtualHosts [
+                  (lib.mapAttrsToList (
+                    key: config: [
+                      (if config ? serverAliases then config.serverAliases else [ ])
+                      key
+                    ]
+                  ))
+                  lib.flatten
+                  (lib.filter (domain: !(lib.hasSuffix "dn42" domain)))
+                ]
               );
             };
           };
diff --git a/config/nixos/modules/presets/zaphyra/syncthing.nix b/config/nixos/modules/presets/zaphyra/syncthing.nix
@@ -69,14 +69,16 @@ in
 
       isCurrentHost = key: value: key != config.networking.hostName;
 
-      deviceNames = (syncthingDevices |> lib.filterAttrs isCurrentHost |> builtins.attrNames);
+      deviceNames = lib.pipe syncthingDevices [
+        (lib.filterAttrs isCurrentHost)
+        builtins.attrNames
+      ];
 
       shareDeviceNames =
         share:
-        (
-          syncthingDevices
-          |> lib.filterAttrs isCurrentHost
-          |> lib.filterAttrs (
+        (lib.pipe syncthingDevices [
+          (lib.filterAttrs isCurrentHost)
+          (lib.filterAttrs (
             name: value:
             let
               syncthingCfg = inputs.self.zaphyraHosts."${name}".config.modules.presets.zaphyra.syncthing;

@@ -87,9 +89,9 @@ in
               else
                 false
             )
-          )
-          |> builtins.attrNames
-        );
+          ))
+          builtins.attrNames
+        ]);
 
       devices = lib.filterAttrs isCurrentHost syncthingDevices;
 
diff --git a/config/nixos/modules/services/knot.nix b/config/nixos/modules/services/knot.nix
@@ -13,16 +13,15 @@ let
 
   dnsServerAddresses =
     isPrimary:
-    lib.flatten (
-      inputs.self.nixosConfigurations
-      |> lib.filterAttrs (
+    (lib.pipe inputs.self.nixosConfigurations [
+      (lib.filterAttrs (
         hostName: hostConfig:
         let
           cfgModule = lib.getAttrFromPath povSelf hostConfig.config;
         in
         (cfgModule.enable && cfgModule.primary == isPrimary)
-      )
-      |> lib.mapAttrsToList (
+      ))
+      (lib.mapAttrsToList (
         hostName: hostConfig: [
           (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip6Address != "")
             inputs.self.hosts."${hostName}".networking.ip6Address

@@ -31,30 +30,32 @@ let
             inputs.self.hosts."${hostName}".networking.ip4Address
           )
         ]
-      )
-    );
+      ))
+      lib.flatten
+    ]);
 
   dnsServerSecondaries = (
-    inputs.self.nixosConfigurations
-    |> lib.filterAttrs (
-      hostName: hostConfig:
-      let
-        cfgModule = lib.getAttrFromPath povSelf hostConfig.config;
-      in
-      (cfgModule.enable && !cfgModule.primary)
-    )
-    |> lib.mapAttrs (
-      hostName: hostConfig: {
-        address = [
-          (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip6Address != "")
-            inputs.self.hosts."${hostName}".networking.ip6Address
-          )
-          (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip4Address != "")
-            inputs.self.hosts."${hostName}".networking.ip4Address
-          )
-        ];
-      }
-    )
+    lib.pipe inputs.self.nixosConfigurations [
+      (lib.filterAttrs (
+        hostName: hostConfig:
+        let
+          cfgModule = lib.getAttrFromPath povSelf hostConfig.config;
+        in
+        (cfgModule.enable && !cfgModule.primary)
+      ))
+      (lib.mapAttrs (
+        hostName: hostConfig: {
+          address = [
+            (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip6Address != "")
+              inputs.self.hosts."${hostName}".networking.ip6Address
+            )
+            (lib.mkIf (inputs.self.hosts."${hostName}".networking.ip4Address != "")
+              inputs.self.hosts."${hostName}".networking.ip4Address
+            )
+          ];
+        }
+      ))
+    ]
   );
 
 in

@@ -144,7 +145,8 @@ in
 
           remote = {
             primary.address = primaryAddresses;
-          } // secondaries;
+          }
+          // secondaries;
 
           acl = {
             allowTransfer = lib.mkIf (secondaryAddresses != [ ]) {

@@ -154,7 +156,8 @@ in
 
             allowNotify.address = primaryAddresses;
             allowNotify.action = "notify";
-          } // cfg.extraACL;
+          }
+          // cfg.extraACL;
 
           template =
             let
diff --git a/config/nixos/modules/services/knotACME.nix b/config/nixos/modules/services/knotACME.nix
@@ -37,52 +37,53 @@ in
     let
       generateACMERecord = recordName: ((builtins.hashString "sha1" recordName) + ".${cfg.zone}.");
 
-      nodesWithACMERecords = (
-        inputs.self.zaphyraHosts
-        |> lib.filterAttrs (hostName: nodeCfg: nodeCfg.config.security.acme.certs != { })
-      );
+      nodesWithACMERecords = lib.filterAttrs (
+        hostName: nodeCfg: nodeCfg.config.security.acme.certs != { }
+      ) inputs.self.zaphyraHosts;
 
       getAllDomainsPerNode =
         hostName:
-        (
-          inputs.self.nixosConfigurations.${hostName}.config.security.acme.certs
-          |> lib.mapAttrsToList (domain: cfg: [ domain ] ++ cfg.extraDomainNames)
-          |> lib.flatten
-        );
+        (lib.pipe inputs.self.nixosConfigurations.${hostName}.config.security.acme.certs [
+          (lib.mapAttrsToList (domain: cfg: [ domain ] ++ cfg.extraDomainNames))
+          lib.flatten
+        ]);
 
       getACMERecordsPerNode =
         hostName:
-        (hostName |> getAllDomainsPerNode |> builtins.map (recordName: (generateACMERecord recordName)));
+        lib.pipe hostName [
+          getAllDomainsPerNode
+          (builtins.map (recordName: (generateACMERecord recordName)))
+        ];
 
       generateACMERecordsPerZone =
         zoneName:
-        (
-          nodesWithACMERecords
-          |> lib.mapAttrsToList (hostName: _: (getAllDomainsPerNode hostName))
-          |> lib.flatten
-          |> builtins.filter (lib.hasSuffix zoneName)
-          |> builtins.map (recordName: {
+        (lib.pipe nodesWithACMERecords [
+          (lib.mapAttrsToList (hostName: _: (getAllDomainsPerNode hostName)))
+          lib.flatten
+          (builtins.filter (lib.hasSuffix zoneName))
+          (builtins.map (recordName: {
             name = "_acme-challenge${
               if zoneName != recordName then "." else ""
             }${lib.removeSuffix "${if zoneName != recordName then "." else ""}${zoneName}" recordName}";
             value = {
               CNAME = [ (generateACMERecord recordName) ];
             };
-          })
-          |> builtins.listToAttrs
-        );
+          }))
+          builtins.listToAttrs
+        ]);
 
     in
     {
       dns.allZones = (
-        cfg.zones
-        |> lib.map (
-          element:
-          lib.nameValuePair element {
-            subdomains = generateACMERecordsPerZone element;
-          }
-        )
-        |> lib.listToAttrs
+        lib.pipe cfg.zones [
+          (lib.map (
+            element:
+            lib.nameValuePair element {
+              subdomains = generateACMERecordsPerZone element;
+            }
+          ))
+          lib.listToAttrs
+        ]
       );
 
       systemd.services.knot =

@@ -139,25 +140,20 @@ in
             journal-content = "all";
 
             acl = lib.mkIf ((lib.attrNames nodesWithACMERecords) != [ ]) (
-              nodesWithACMERecords |> lib.mapAttrsToList (hostName: _: "acme-nix-${hostName}")
+              lib.mapAttrsToList (hostName: _: "acme-nix-${hostName}") nodesWithACMERecords
             );
           };
         };
-        extraACL = (
-          nodesWithACMERecords
-          |> lib.mapAttrs' (
-            hostName: _: {
-              name = "acme-nix-${hostName}";
-              value = {
-                key = [ "acme-nix-${hostName}" ];
-                action = "update";
-                update-owner = "name";
-                update-owner-match = "equal";
-                update-owner-name = getACMERecordsPerNode hostName;
-              };
-            }
-          )
-        );
+        extraACL = lib.mapAttrs' (hostName: _: {
+          name = "acme-nix-${hostName}";
+          value = {
+            key = [ "acme-nix-${hostName}" ];
+            action = "update";
+            update-owner = "name";
+            update-owner-match = "equal";
+            update-owner-name = getACMERecordsPerNode hostName;
+          };
+        }) nodesWithACMERecords;
       };
     }
   );
diff --git a/config/nixos/modules/services/resticBackup.nix b/config/nixos/modules/services/resticBackup.nix
@@ -89,110 +89,101 @@ in
 
   config = lib.mkIf (cfg.paths != { }) {
 
-    systemd.services = (
-      cfg.paths
-      |> lib.attrsToList
-      |> lib.map (
+    systemd.services = lib.pipe cfg.paths [
+      lib.attrsToList
+      (lib.map (
         element:
         (
           if element.value.enable then
-            (
-              element.value.targets
-              |> lib.map (
-                target:
-                lib.nameValuePair "restic-backups-${element.name}-${target}" {
-                  serviceConfig.EnvironmentFile =
-                    [
-                      cfg.targets."${target}".environmentFile
-                    ]
-                    ++ (lib.optionals (element.value.environmentFile != null) [
-                      element.value.environmentFile
-                    ]);
-                }
-              )
-            )
+            (lib.map (
+              target:
+              lib.nameValuePair "restic-backups-${element.name}-${target}" {
+                serviceConfig.EnvironmentFile = [
+                  cfg.targets."${target}".environmentFile
+                ]
+                ++ (lib.optionals (element.value.environmentFile != null) [
+                  element.value.environmentFile
+                ]);
+              }
+            ) element.value.targets)
           else
             [ ]
         )
-      )
-      |> lib.flatten
-      |> lib.listToAttrs
-    );
+      ))
+      lib.flatten
+      lib.listToAttrs
+    ];
 
-    services.restic.backups = (
-      cfg.paths
-      |> lib.attrsToList
-      |> lib.map (
+    services.restic.backups = lib.pipe cfg.paths [
+      lib.attrsToList
+      (lib.map (
         element:
         (
           if element.value.enable then
-            (
-              element.value.targets
-              |> lib.map (
-                target:
-                lib.nameValuePair "${element.name}-${target}" {
-                  initialize = true;
-                  user = element.value.user;
-                  passwordFile = element.value.passwordFile;
-                  timerConfig = element.value.timerConfig;
-                  repository = cfg.targets."${target}".repository + "/${config.networking.hostName}-${element.name}";
-                  paths = lib.mkMerge [
-                    element.value.paths
-                    (lib.mkIf (element.value.postgresDatabases != [ ]) (
-                      lib.map (element: "/tmp/postgresDatabases/${element}.sql.zst") element.value.postgresDatabases
+            (lib.map (
+              target:
+              lib.nameValuePair "${element.name}-${target}" {
+                initialize = true;
+                user = element.value.user;
+                passwordFile = element.value.passwordFile;
+                timerConfig = element.value.timerConfig;
+                repository = cfg.targets."${target}".repository + "/${config.networking.hostName}-${element.name}";
+                paths = lib.mkMerge [
+                  element.value.paths
+                  (lib.mkIf (element.value.postgresDatabases != [ ]) (
+                    lib.map (element: "/tmp/postgresDatabases/${element}.sql.zst") element.value.postgresDatabases
+                  ))
+                  (lib.mkIf (element.value.sqliteDatabases != [ ]) (
+                    lib.map (
+                      element: "/tmp/sqliteDatabases/${builtins.baseNameOf element}.sqlite"
+                    ) element.value.sqliteDatabases
+                  ))
+                  (lib.mkIf (element.value.influxBuckets != [ ]) (
+                    lib.map (element: "/tmp/influxBuckets/${element}") element.value.influxBuckets
+                  ))
+                ];
+                backupPrepareCommand = (
+                  element.value.runBeforeBackup
+                  +
+                    #dump postgresql databases
+                    (lib.optionalString (element.value.postgresDatabases != [ ]) (
+                      lib.concatMapStringsSep "\n" (db: ''
+                        echo "Dumping Postgres-database: ${db}"
+                        mkdir -p /tmp/postgresDatabases
+                        pg_dump ${db} | zstd --rsyncable > /tmp/postgresDatabases/${db}.sql.zst
+                        [ $(du -b /tmp/postgresDatabases/${db}.sql.zst | cut -f1) -gt "50" ] || exit 1
+                      '') element.value.postgresDatabases
                     ))
-                    (lib.mkIf (element.value.sqliteDatabases != [ ]) (
-                      lib.map (
-                        element: "/tmp/sqliteDatabases/${builtins.baseNameOf element}.sqlite"
-                      ) element.value.sqliteDatabases
+                  +
+                    #dump sqlite databases
+                    (lib.optionalString (element.value.sqliteDatabases != [ ]) (
+                      lib.concatMapStringsSep "\n" (db: ''
+                        echo "Dumping sqlite-database: ${db}"
+                        mkdir -p /tmp/sqliteDatabases
+                        ${pkgs.sqlite}/bin/sqlite3 ${db} ".backup '/tmp/sqliteDatabases/${builtins.baseNameOf db}.sqlite'"
+                        [ $(du -b /tmp/sqliteDatabases/${builtins.baseNameOf db}.sqlite | cut -f1) -gt "50" ] || exit 1
+                      '') element.value.sqliteDatabases
                     ))
-                    (lib.mkIf (element.value.influxBuckets != [ ]) (
-                      lib.map (element: "/tmp/influxBuckets/${element}") element.value.influxBuckets
+                  +
+                    #dump influx buckets
+                    (lib.optionalString (element.value.influxBuckets != [ ]) (
+                      lib.concatMapStringsSep "\n" (db: ''
+                        echo "Dumping influx-bucket: ${db}"
+                        mkdir -p /tmp/influxBuckets
+                        ${pkgs.influxdb2}/bin/influx backup --compression=none --bucket=${db} /tmp/influxBuckets/${db}
+                        [ $(du -b /tmp/influxBuckets/${db} | cut -f1) -gt "50" ] || exit 1
+                      '') element.value.influxBuckets
                     ))
-                  ];
-                  backupPrepareCommand = (
-                    element.value.runBeforeBackup
-                    +
-                      #dump postgresql databases
-                      (lib.optionalString (element.value.postgresDatabases != [ ]) (
-                        lib.concatMapStringsSep "\n" (db: ''
-                          echo "Dumping Postgres-database: ${db}"
-                          mkdir -p /tmp/postgresDatabases
-                          pg_dump ${db} | zstd --rsyncable > /tmp/postgresDatabases/${db}.sql.zst
-                          [ $(du -b /tmp/postgresDatabases/${db}.sql.zst | cut -f1) -gt "50" ] || exit 1
-                        '') element.value.postgresDatabases
-                      ))
-                    +
-                      #dump sqlite databases
-                      (lib.optionalString (element.value.sqliteDatabases != [ ]) (
-                        lib.concatMapStringsSep "\n" (db: ''
-                          echo "Dumping sqlite-database: ${db}"
-                          mkdir -p /tmp/sqliteDatabases
-                          ${pkgs.sqlite}/bin/sqlite3 ${db} ".backup '/tmp/sqliteDatabases/${builtins.baseNameOf db}.sqlite'"
-                          [ $(du -b /tmp/sqliteDatabases/${builtins.baseNameOf db}.sqlite | cut -f1) -gt "50" ] || exit 1
-                        '') element.value.sqliteDatabases
-                      ))
-                    +
-                      #dump influx buckets
-                      (lib.optionalString (element.value.influxBuckets != [ ]) (
-                        lib.concatMapStringsSep "\n" (db: ''
-                          echo "Dumping influx-bucket: ${db}"
-                          mkdir -p /tmp/influxBuckets
-                          ${pkgs.influxdb2}/bin/influx backup --compression=none --bucket=${db} /tmp/influxBuckets/${db}
-                          [ $(du -b /tmp/influxBuckets/${db} | cut -f1) -gt "50" ] || exit 1
-                        '') element.value.influxBuckets
-                      ))
-                  );
-                }
-              )
-            )
+                );
+              }
+            ) element.value.targets)
           else
             [ ]
         )
-      )
-      |> lib.flatten
-      |> lib.listToAttrs
-    );
+      ))
+      lib.flatten
+      lib.listToAttrs
+    ];
   };
 
 }
diff --git a/config/nixos/modules/websites/gts.zaphyra.eu.nix b/config/nixos/modules/websites/gts.zaphyra.eu.nix
@@ -122,6 +122,8 @@ in
           "en-us"
         ];
 
+        media-emoji-local-max-size = "100KiB";
+
         media-local-max-size = "50MiB";
         media-remote-max-size = "50MiB";
 

@@ -132,6 +134,8 @@ in
         smtp-port = 587;
         smtp-username = "gts@zaphyra.eu";
         smtp-from = "gts@zaphyra.eu";
+
+        advanced-rate-limit-requests = 3000;
       };
     };
 

@@ -139,86 +143,85 @@ in
       appendHttpConfig = ''
         proxy_cache_path /var/cache/nginx keys_zone=gotosocial_ap_public_responses:10m inactive=1w;
       '';
-      virtualHosts =
-        {
-          "${config.tgc.services.gotosocial.settings.host}" = {
-            useACMEHost = lib.mkDefault "${config.networking.fqdn}";
-            forceSSL = lib.mkDefault true;
-            kTLS = lib.mkDefault true;
-            locations = {
-              "/" = {
-                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
-                proxyWebsockets = true;
-              };
-
-              "/client/" = {
-                index = "index.html";
-                alias = "${
-                  pkgs.tgc.phanpy.override {
-                    clientName = "zaphyra's fedi";
-                    website = "https://gts.zaphyra.eu/client/";
-                    defaultInstance = "gts.zaphyra.eu";
-                  }
-                }/";
-              };
-              "~ /.well-known/(webfinger|host-meta)$" = {
-                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
-                extraConfig = ''
-                  proxy_cache gotosocial_ap_public_responses;
-                  proxy_cache_background_update on;
-                  proxy_cache_key $scheme://$host$uri$is_args$query_string;
-                  proxy_cache_valid 200 10m;
-                  proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
-                  proxy_cache_lock on;
-                  add_header X-Cache-Status $upstream_cache_status;
-                '';
-              };
+      virtualHosts = {
+        "${config.tgc.services.gotosocial.settings.host}" = {
+          useACMEHost = lib.mkDefault "${config.networking.fqdn}";
+          forceSSL = lib.mkDefault true;
+          kTLS = lib.mkDefault true;
+          locations = {
+            "/" = {
+              proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
+              proxyWebsockets = true;
+            };
 
-              "~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$" = {
-                proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
-                extraConfig = ''
-                  proxy_cache gotosocial_ap_public_responses;
-                  proxy_cache_background_update on;
-                  proxy_cache_key $scheme://$host$uri;
-                  proxy_cache_valid 200 604800s;
-                  proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
-                  proxy_cache_lock on;
-
-                  add_header X-Cache-Status $upstream_cache_status;
-                '';
-              };
+            "/client/" = {
+              index = "index.html";
+              alias = "${
+                pkgs.tgc.phanpy.override {
+                  clientName = "zaphyra's fedi";
+                  website = "https://gts.zaphyra.eu/client/";
+                  defaultInstance = "gts.zaphyra.eu";
+                }
+              }/";
+            };
+            "~ /.well-known/(webfinger|host-meta)$" = {
+              proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
+              extraConfig = ''
+                proxy_cache gotosocial_ap_public_responses;
+                proxy_cache_background_update on;
+                proxy_cache_key $scheme://$host$uri$is_args$query_string;
+                proxy_cache_valid 200 10m;
+                proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
+                proxy_cache_lock on;
+                add_header X-Cache-Status $upstream_cache_status;
+              '';
+            };
 
-              "/assets/".extraConfig = ''
-                alias ${config.tgc.services.gotosocial.package}/share/gotosocial/web/assets/;
-                autoindex off;
-                expires max;
-                add_header Cache-Control "public, immutable";
+            "~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$" = {
+              proxyPass = "http://${toString config.tgc.services.gotosocial.settings.bind-address}:${toString config.tgc.services.gotosocial.settings.port}";
+              extraConfig = ''
+                proxy_cache gotosocial_ap_public_responses;
+                proxy_cache_background_update on;
+                proxy_cache_key $scheme://$host$uri;
+                proxy_cache_valid 200 604800s;
+                proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
+                proxy_cache_lock on;
+
+                add_header X-Cache-Status $upstream_cache_status;
               '';
             };
+
+            "/assets/".extraConfig = ''
+              alias ${config.tgc.services.gotosocial.package}/share/gotosocial/web/assets/;
+              autoindex off;
+              expires max;
+              add_header Cache-Control "public, immutable";
+            '';
           };
-        }
-        // (
-          if
-            (
-              config.tgc.services.gotosocial.settings.account-domain
-              != config.tgc.services.gotosocial.settings.host
-            )
-          then
-            {
-              "${config.tgc.services.gotosocial.settings.account-domain}" = {
-                locations = {
-                  "= /.well-known/host-meta".extraConfig =
-                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
-                  "= /.well-known/webfinger".extraConfig =
-                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
-                  "= /.well-known/nodeinfo".extraConfig =
-                    "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
-                };
+        };
+      }
+      // (
+        if
+          (
+            config.tgc.services.gotosocial.settings.account-domain
+            != config.tgc.services.gotosocial.settings.host
+          )
+        then
+          {
+            "${config.tgc.services.gotosocial.settings.account-domain}" = {
+              locations = {
+                "= /.well-known/host-meta".extraConfig =
+                  "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
+                "= /.well-known/webfinger".extraConfig =
+                  "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
+                "= /.well-known/nodeinfo".extraConfig =
+                  "return 301 https://${config.tgc.services.gotosocial.settings.host}$request_uri;";
               };
-            }
-          else
-            { }
-        );
+            };
+          }
+        else
+          { }
+      );
     };
   };
 
diff --git a/config/nixosModules.nix b/config/nixosModules.nix
@@ -64,9 +64,10 @@ in
   options = modules.options;
 
   config = lib.mkMerge (
-    (lib.removeAttrs modules [ "options" ])
-    |> lib.collect (element: element ? config)
-    |> lib.map (element: element.config)
+    lib.pipe (lib.removeAttrs modules [ "options" ]) [
+      (lib.collect (element: element ? config))
+      (lib.map (element: element.config))
+    ]
   );
 
 }
diff --git a/flake.nix b/flake.nix
@@ -129,48 +129,54 @@
       ) inputs.self.hosts;
 
       zaphyraHosts = (
-        inputs.self.nixosConfigurations
-        |> nixpkgsLib.filterAttrs (
+        nixpkgsLib.filterAttrs (
           name: value:
           if (builtins.isNull value.config.networking.domain) then
             false
           else
             nixpkgsLib.hasSuffix "zaphyra.eu" value.config.networking.domain
-        )
+        ) inputs.self.nixosConfigurations
       );
 
       homeConfigurations = builtins.listToAttrs (
-        builtins.map (
-          name:
-          (nixpkgsLib.nameValuePair name (
-            inputs.homeManager.lib.homeManagerConfiguration {
-              pkgs = import inputs.nixpkgs {
-                system = "x86_64-linux";
-                overlays = inputs.self.nixpkgsOverlays;
-                config = {
-                  allowUnfree = true;
-                };
-              };
-
-              modules = [
-                inputs.self.homeManagerModules."${name}".home
-                inputs.self.homeManagerModules.common.home
-                {
-                  home = {
-                    username = nixpkgsLib.mkDefault name;
-                    homeDirectory = nixpkgsLib.mkDefault "/home/${name}";
+        builtins.map
+          (
+            name:
+            (nixpkgsLib.nameValuePair name (
+              inputs.homeManager.lib.homeManagerConfiguration {
+                pkgs = import inputs.nixpkgs {
+                  system = "x86_64-linux";
+                  overlays = inputs.self.nixpkgsOverlays;
+                  config = {
+                    allowUnfree = true;
                   };
-                  programs.home-manager.enable = true;
-                }
-              ];
+                };
 
-              extraSpecialArgs = {
-                inherit inputs;
-                inherit (inputs.self) homeManagerModules;
-              };
-            }
-          ))
-        ) (inputs.self.homeManagerModules |> nixpkgsLib.attrNames |> nixpkgsLib.remove "common")
+                modules = [
+                  inputs.self.homeManagerModules."${name}".home
+                  inputs.self.homeManagerModules.common.home
+                  {
+                    home = {
+                      username = nixpkgsLib.mkDefault name;
+                      homeDirectory = nixpkgsLib.mkDefault "/home/${name}";
+                    };
+                    programs.home-manager.enable = true;
+                  }
+                ];
+
+                extraSpecialArgs = {
+                  inherit inputs;
+                  inherit (inputs.self) homeManagerModules;
+                };
+              }
+            ))
+          )
+          (
+            nixpkgsLib.pipe inputs.self.homeManagerModules [
+              nixpkgsLib.attrNames
+              (nixpkgsLib.remove "common")
+            ]
+          )
       );
 
       hydraJobs = builtins.listToAttrs (