ctucx.git: nixfiles

ctucx' nixfiles

commit b42924441413d875dd79bd8f30def6852ec0be1d
parent 0366dc389ad0daaf12adf79b03509b7eee85fad5
Author: Katja (ctucx) <git@ctu.cx>
Date: Tue, 4 Mar 2025 11:46:29 +0100

flake: refactor
42 files changed, 742 insertions(+), 650 deletions(-)
M
configurations/nixos/services/dns-server.nix
|
10
+++++-----
M
configurations/nixos/services/mailserver/default.nix
|
4
++--
M
configurations/nixos/websites/ctu.cx.nix
|
6
+++---
M
configurations/nixos/websites/fedi.ctu.cx.nix
|
9
+++------
M
configurations/nixos/websites/ip.ctu.cx.nix
|
8
++++----
M
configurations/nixos/websites/zuggeschmack.de.nix
|
4
++--
M
configurations/nixos/wm/gnome.nix
|
13
+++++++++++--
M
flake.nix
|
229
++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
A
lib/toBase64.nix
|
34
++++++++++++++++++++++++++++++++++
A
lib/writePythonScriptBin.nix
|
21
+++++++++++++++++++++
M
machines/blechkasten/default.nix
|
18
+++++++++++-------
M
machines/briefkasten/default.nix
|
140
+++++++++++++++++++++++++++++++++++++++++--------------------------------------
M
machines/hector/default.nix
|
176
++++++++++++++++++++++++++++++++++++++++---------------------------------------
M
machines/seifenkiste/default.nix
|
70
+++++++++++++++++++++++++++++++++++++---------------------------------
M
machines/trabbi/default.nix
|
119
++++++++++++++++++++++++++++++++++++++++---------------------------------------
M
machines/wanderduene/default.nix
|
200
++++++++++++++++++++++++++++++++++++++++---------------------------------------
M
modules/nixos/dns.nix
|
35
++++++++++++++++++++++++-----------
R
pkgs/adwaita-colors.nix -> pkgs/all/adwaita-colors-icon-theme.nix
|
0
R
pkgs/agenix/agenix.sh -> pkgs/all/agenix/agenix.sh
|
0
R
pkgs/agenix/default.nix -> pkgs/all/agenix/default.nix
|
0
A
pkgs/all/bgiparser.nix
|
47
+++++++++++++++++++++++++++++++++++++++++++++++
R
pkgs/cinny.nix -> pkgs/all/cinny.nix
|
0
R
pkgs/gotosocial/default.nix -> pkgs/all/gotosocial/default.nix
|
0
A
pkgs/all/homebridge/default.nix
|
27
+++++++++++++++++++++++++++
R
pkgs/homebridge/package.json -> pkgs/all/homebridge/package.json
|
0
R
pkgs/homebridge/yarn.lock -> pkgs/all/homebridge/yarn.lock
|
0
R
pkgs/masto-fe-standalone/0001-set-a-default-instance.patch -> pkgs/all/masto-fe-standalone/0001-set-a-default-instance.patch
|
0
R
pkgs/masto-fe-standalone/0002-update-default-state.patch -> pkgs/all/masto-fe-standalone/0002-update-default-state.patch
|
0
R
pkgs/masto-fe-standalone/default.nix -> pkgs/all/masto-fe-standalone/default.nix
|
0
A
pkgs/all/mbusd.nix
|
23
+++++++++++++++++++++++
R
pkgs/phockup.nix -> pkgs/all/phockup.nix
|
0
R
pkgs/rofi-iwd-wifi-menu.nix -> pkgs/all/rofi-iwd-wifi-menu.nix
|
0
R
pkgs/slurp.nix -> pkgs/all/slurp.nix
|
0
D
pkgs/bgiparser.nix
|
39
---------------------------------------
M
pkgs/darwin/XPCEventStreamHandler/default.nix
|
10
+++++++++-
D
pkgs/darwin/default.nix
|
21
---------------------
A
pkgs/darwinOverlay.nix
|
19
+++++++++++++++++++
D
pkgs/homebridge/default.nix
|
18
------------------
D
pkgs/mbusd.nix
|
15
---------------
D
pkgs/overlay.nix
|
20
--------------------
D
pkgs/toBase64.nix
|
37
-------------------------------------
D
pkgs/writePythonScriptBin.nix
|
20
--------------------
diff --git a/configurations/nixos/services/dns-server.nix b/configurations/nixos/services/dns-server.nix
@@ -1,4 +1,4 @@
-{ nodes, config, lib, pkgs, ...}:
+{ nodes, config, dnsNix, ctucxLib, lib, pkgs, ...}:
 
 let
   acmeZone = "acme.ctu.cx";

@@ -63,8 +63,8 @@ in {
       user     = "knot";
       mode     = "770";
       age      = "-";
-      argument = pkgs.toBase64 (
-        pkgs.dns.lib.types.zoneToString acmeZone (pkgs.dns.lib.evalZone acmeZone (with pkgs.dns.lib.combinators; {
+      argument = ctucxLib.toBase64 (
+        dnsNix.types.zoneToString acmeZone (dnsNix.evalZone acmeZone (with dnsNix.combinators; {
           NS  = [ "ns1.ctu.cx." "ns2.ctu.cx." ];
           SOA = {
             nameServer = "ns1.ctu.cx.";

@@ -77,7 +77,7 @@ in {
   };
 
   dns = {
-    enable     = lib.mkDefault (builtins.elem "dnsServer" config.deployment.tags);
+    enable     = true;
     primary    = lib.mkDefault (config.networking.hostName == "hector");
     keyFiles   = lib.mkIf config.dns.primary [ config.age.secrets.knotKeys.path ];
     extraZones = lib.mkIf config.dns.primary {

@@ -111,7 +111,7 @@ in {
       })
     );
 
-    allZones = with pkgs.dns.lib.combinators; let
+    allZones = with dnsNix.combinators; let
       CAA = [ { issuerCritical = false; tag = "issue"; value = "letsencrypt.org"; } ];
       NS  = [ "ns1.ctu.cx." "ns2.ctu.cx." ];
       SOA = {
diff --git a/configurations/nixos/services/mailserver/default.nix b/configurations/nixos/services/mailserver/default.nix
@@ -1,4 +1,4 @@
-{ inputs, pkgs, config, ... }:
+{ dnsNix, pkgs, config, ... }:
 
 let
   mailAutoConfig = ''

@@ -35,7 +35,7 @@ in {
   age.secrets.mail-password-info-zug.file    = ./. + "/../../../../secrets/${config.networking.hostName}/mail/password-info-zuggeschmack.de.age";
   age.secrets.mail-password-vaultwarden.file = ./. + "/../../../../secrets/${config.networking.hostName}/mail/password-vaultwarden-ctu.cx.age";
 
-  dns.zones = with pkgs.dns.lib.combinators; let
+  dns.zones = with dnsNix.combinators; let
     TXT   = [ "v=spf1 a mx ip4:${config.networking.primaryIP4} +ip6:${config.networking.primaryIP} ~all" ];
     DMARC = "v=DMARC1; p=none";
     MX    = with mx; [ (mx 10 "${config.networking.fqdn}.") ];
diff --git a/configurations/nixos/websites/ctu.cx.nix b/configurations/nixos/websites/ctu.cx.nix
@@ -1,9 +1,9 @@
-{ pkgs, lib, config, ...}:
+{ dnsNix, pkgs, lib, config, ...}:
 
 {
 
-  dns.zones."ctu.cx"    = (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
-  dns.zones."katja.wtf" = (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
+  dns.zones."ctu.cx"    = (dnsNix.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
+  dns.zones."katja.wtf" = (dnsNix.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
 
   services.nginx = {
     enable = true;
diff --git a/configurations/nixos/websites/fedi.ctu.cx.nix b/configurations/nixos/websites/fedi.ctu.cx.nix
@@ -1,9 +1,6 @@
 { pkgs, lib, config, ... }:
 
-let
-  gotosocial = pkgs.callPackage ../../../pkgs/gotosocial {};
-
-in {
+{
 
   dns.zones."ctu.cx".subdomains."fedi".CNAME = [ "${config.networking.fqdn}." ];
 

@@ -20,7 +17,7 @@ in {
     sqliteDatabases = [ "/var/lib/gotosocial/db.sqlite" ];
     paths           = [ "/var/lib/gotosocial/storage" "/var/lib/gotosocial/backup.json" ];
     runBeforeBackup = ''
-      ${gotosocial}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path /var/lib/gotosocial/backup.json
+      ${pkgs.gotosocial}/bin/gotosocial --config-path /etc/gotosocial.yaml admin export --path /var/lib/gotosocial/backup.json
     '';
   };
 

@@ -29,7 +26,7 @@ in {
 
   services.gotosocial = {
     enable          = true;
-    package         = gotosocial;
+    package         = pkgs.gotosocial;
     group           = "nginx";
     environmentFile = config.age.secrets.gotosocial-env.path;
     settings        = {
diff --git a/configurations/nixos/websites/ip.ctu.cx.nix b/configurations/nixos/websites/ip.ctu.cx.nix
@@ -1,10 +1,10 @@
-{ pkgs, config, ... }:
+{ dnsNix, pkgs, config, ... }:
 
 {
 
-  dns.zones."ctu.cx".subdomains."ip"       = (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
-  dns.zones."ctu.cx".subdomains."ip4".A    = [ (pkgs.dns.lib.combinators.a    config.networking.primaryIP4) ];
-  dns.zones."ctu.cx".subdomains."ip6".AAAA = [ (pkgs.dns.lib.combinators.aaaa config.networking.primaryIP) ];
+  dns.zones."ctu.cx".subdomains."ip"       = (dnsNix.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
+  dns.zones."ctu.cx".subdomains."ip4".A    = [ config.networking.primaryIP4 ];
+  dns.zones."ctu.cx".subdomains."ip6".AAAA = [ config.networking.primaryIP ];
 
   services.nginx.virtualHosts."ip.${config.networking.domain}" = {
     useACMEHost = "${config.networking.hostName}.${config.networking.domain}";
diff --git a/configurations/nixos/websites/zuggeschmack.de.nix b/configurations/nixos/websites/zuggeschmack.de.nix
@@ -1,8 +1,8 @@
-{ pkgs, lib, config, ... }:
+{ dnsNix, pkgs, lib, config, ... }:
 
 {
 
-  dns.zones."zuggeschmack.de" = (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP) // {
+  dns.zones."zuggeschmack.de" = (dnsNix.combinators.host config.networking.primaryIP4 config.networking.primaryIP) // {
     subdomains."client".CNAME = [ "${config.networking.fqdn}." ];
   };
 
diff --git a/configurations/nixos/wm/gnome.nix b/configurations/nixos/wm/gnome.nix
@@ -1,4 +1,4 @@
-{ inputs, config, ctucxConfig, lib, pkgs, homeManager, ... }:
+{ inputs, nixStd, config, ctucxConfig, lib, pkgs, homeManager, ... }:
 
 {
 

@@ -152,7 +152,16 @@
     # Use `dconf watch /` to track stateful changes you are doing and store them here.
     dconf.settings = with inputs.homeManager.lib.hm.gvariant; let
       numWorkspaces = 7;
-      workspaces = lib.lists.reverseList( pkgs.std.list.unfold( n: if n == 0 then pkgs.std.optional.nothing else pkgs.std.optional.just( pkgs.std.tuple.tuple2 n (n - 1))) numWorkspaces);
+      workspaces    = (
+        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
+      );
     in {
       "org/gnome/mutter" = {
         edge-tiling        = true;
diff --git a/flake.nix b/flake.nix
@@ -2,113 +2,154 @@
 
   description = "A flake for building my infra";
 
-  outputs = { self, ... } @ inputs: rec {
+  outputs = inputs: let
+    forAllSystems = function: (
+      inputs.nixpkgs.lib.genAttrs [
+        "x86_64-linux"
+        "aarch64-linux"
+        "aarch64-darwin"
+      ] (system: function inputs.nixpkgs.legacyPackages."${system}")
+    );
+
+    transformer = name: value: (
+      if name == [] then value else (
+        if (builtins.hasAttr "default" value) then value.default else value
+      )
+
+    );
 
     loadDir = path: inputs.haumea.lib.load {
       src         = path;
       loader      = inputs.haumea.lib.loaders.path;
-      transformer = name: value: (
-        if name == [] then value else (
-          if (builtins.hasAttr "default" value) then value.default else value
-        )
-      );
+      transformer = transformer;
     };
 
-    ctucxModules.darwin = loadDir ./modules/darwin;
-    ctucxModules.nixos  = loadDir ./modules/nixos;
-
-    ctucxConfig.common = loadDir ./configurations/common;
-    ctucxConfig.darwin = inputs.nixpkgs.lib.recursiveUpdate ctucxConfig.common (loadDir ./configurations/darwin);
-    ctucxConfig.nixos  = inputs.nixpkgs.lib.recursiveUpdate ctucxConfig.common (loadDir ./configurations/nixos);
-
-    darwinConfigurations = {
-      blechkasten = inputs.nixDarwin.lib.darwinSystem rec {
-
-        pkgs = import inputs.nixpkgsDarwin {
-          system   = "aarch64-darwin";
-          overlays = overlays ++ [(import ./pkgs/darwin)];
-          config.allowUnfree = true;
-        };
-
-        specialArgs = {
-          ctucxConfig = ctucxConfig.darwin;
-          inherit inputs;
-        };
-
-        modules = [
-          inputs.lixModule.nixosModules.default
-          inputs.homeManager.darwinModules.default
-          inputs.agenix.darwinModules.default
-          ctucxConfig.darwin.default
-          ctucxModules.darwin.default
-          ./machines/blechkasten
+    ctucxMachines = inputs.haumea.lib.load {
+      src         = ./machines;
+      loader      = inputs.haumea.lib.loaders.verbatim;
+      transformer = transformer;
+    };
+
+    darwinMachines = inputs.nixpkgs.lib.filterAttrs (name: machine: inputs.nixpkgs.lib.strings.hasSuffix "darwin" machine.system) ctucxMachines;
+    nixosMachines  = inputs.nixpkgs.lib.filterAttrs (name: machine: inputs.nixpkgs.lib.strings.hasSuffix "linux"  machine.system) ctucxMachines;
+
+  in {
+
+    ctucxConfig.common  = loadDir ./configurations/common;
+    ctucxConfig.nixos   = inputs.nixpkgs.lib.recursiveUpdate inputs.self.ctucxConfig.common (loadDir ./configurations/nixos);
+    ctucxConfig.darwin  = inputs.nixpkgs.lib.recursiveUpdate inputs.self.ctucxConfig.common (loadDir ./configurations/darwin);
+
+    nixosModules        = loadDir ./modules/nixos;
+    darwinModules       = loadDir ./modules/darwin;
+
+    lib = inputs.haumea.lib.load {
+      src         = ./lib;
+      loader      = path: path: import path inputs;
+      transformer = transformer;
+    };
+
+    overlays.unstable      = final: prev: { unstable = inputs.nixpkgsUnstable.legacyPackages.${prev.system}; };
+    overlays.darwinOverlay = import ./pkgs/darwinOverlay.nix;
+
+    overlays.packages = final: prev: inputs.haumea.lib.load {
+      src         = ./pkgs/all;
+      loader      = path: path: final.callPackage path {};
+      transformer = transformer;
+    };
+
+    overlays.darwinPackages = final: prev: inputs.haumea.lib.load {
+      src         = ./pkgs/darwin;
+      loader      = path: path: final.callPackage path {};
+      transformer = transformer;
+    };
+
+
+    nixosConfigurations  = (inputs.colmena.lib.makeHive inputs.self.outputs.colmena).nodes;
+    darwinConfigurations = builtins.mapAttrs (name: machine: inputs.nixDarwin.lib.darwinSystem {
+      pkgs = import inputs.nixpkgsDarwin {
+        system   = machine.system;
+        overlays = [
+          inputs.self.overlays.unstable
+          inputs.self.overlays.packages
+          inputs.self.overlays.darwinPackages
+          inputs.self.overlays.darwinOverlay
+
+          inputs.ctucxWebsite.overlays.default
         ];
       };
-    };
 
-    colmena = {
-      meta = rec {
-        allowApplyAll = false;
-
-        nixpkgs = import inputs.nixpkgs {
-          system   = "x86_64-linux";
-          overlays = overlays;
-          config.permittedInsecurePackages = [ "olm-3.2.16" ];
-        };          
-
-        specialArgs = {
-          inherit inputs;
-          ctucxConfig = ctucxConfig.nixos;
-        };
+      specialArgs = {
+        inputs      = inputs;
+        ctucxConfig = inputs.self.ctucxConfig.darwin;
+        ctucxLib    = inputs.self.lib;
+        nixStd      = inputs.nixStd.lib;
       };
 
-      defaults = {
-        imports = [
-          inputs.lixModule.nixosModules.default
-          inputs.impermanence.nixosModules.default
-          inputs.homeManager.nixosModules.default
-          inputs.agenix.nixosModules.default
-          inputs.lanzaboote.nixosModules.lanzaboote
-          inputs.simpleNixosMailserver.nixosModules.default
-          inputs.ctucxThings.nixosModule
-          ctucxModules.nixos.default
-          ctucxConfig.nixos.default
-        ];
+      modules = [
+        inputs.lixModule.nixosModules.default
+        inputs.homeManager.darwinModules.default
+        inputs.agenix.darwinModules.default
+        inputs.self.darwinModules.default
+        inputs.self.ctucxConfig.darwin.default
+        machine.configuration
+      ];
+
+    }) darwinMachines;
+
+    colmena = {
+      meta.allowApplyAll = false;
+      meta.nixpkgs       = import inputs.nixpkgs { system = "x86_64-linux"; };
+      meta.specialArgs   = {
+        inputs      = inputs;
+        ctucxConfig = inputs.self.ctucxConfig.nixos;
+        ctucxLib    = inputs.self.lib;
+        dnsNix      = inputs.dnsNix.lib;
+        nixStd      = inputs.nixStd.lib;
       };
 
-    } // loadDir ./machines;
-
-    colmenaHive         = inputs.colmena.lib.makeHive self.outputs.colmena;
-    nixosConfigurations = (import (inputs.colmena + "/src/nix/hive/eval.nix") {
-      rawFlake = inputs.self;
-      colmenaOptions = import (inputs.colmena + "/src/nix/hive/options.nix");
-      colmenaModules = import (inputs.colmena + "/src/nix/hive/modules.nix");
-    }).nodes;
-
-    overlays = [
-      (import ./pkgs/overlay.nix)
-
-      (final: prev: {
-        dns         = inputs.dnsNix;
-        std         = inputs.nixStd.lib;
-        unstable    = inputs.nixpkgsUnstable.legacyPackages.${prev.system};
-        inherit ctucxConfig ctucxModules;
-      })
-
-      inputs.colmena.overlay
-
-      inputs.stagit.overlay
-      inputs.travelynx2fedi.overlay
-
-      inputs.mqttWebUI.overlay
-      inputs.ctucxThings.overlay
-      inputs.ctucxGallery.overlay
-      inputs.ctucxWebsite.overlay
-      inputs.trainsearch.overlay
-      inputs.flauschehornSexy.overlay
-      inputs.gpxMap.overlay
-      inputs.mobileCoverageMap.overlay
-    ];
+      meta.nodeNixpkgs = builtins.mapAttrs (name: machine: import inputs.nixpkgs {
+        system   = machine.system;
+        overlays = [
+          inputs.self.overlays.packages
+          inputs.self.overlays.unstable
+
+          inputs.colmena.overlays.default
+          inputs.stagit.overlays.default
+          inputs.travelynx2fedi.overlays.default
+
+          inputs.mqttWebUI.overlays.default
+          inputs.ctucxThings.overlays.default
+          inputs.ctucxGallery.overlays.default
+          inputs.ctucxWebsite.overlays.default
+          inputs.trainsearch.overlays.default
+          inputs.flauschehornSexy.overlays.default
+          inputs.gpxMap.overlays.default
+          inputs.mobileCoverageMap.overlays.default
+        ];
+      }) nixosMachines;
+
+      defaults.imports = [
+        inputs.lixModule.nixosModules.default
+        inputs.impermanence.nixosModules.default
+        inputs.homeManager.nixosModules.default
+        inputs.agenix.nixosModules.default
+        inputs.lanzaboote.nixosModules.lanzaboote
+        inputs.simpleNixosMailserver.nixosModules.default
+        inputs.ctucxThings.nixosModules.default
+        inputs.self.nixosModules.default
+        inputs.self.ctucxConfig.nixos.default
+      ];
+    } // builtins.mapAttrs (name: machine: machine.configuration) nixosMachines;
+
+    packages = forAllSystems (pkgs: let
+      loader = path: path: pkgs.callPackage path {};
+    in (inputs.haumea.lib.load {
+      inherit loader transformer;
+      src = ./pkgs/all;
+    }) // (if pkgs.stdenv.isDarwin then (inputs.haumea.lib.load {
+      inherit loader transformer;
+      src = ./pkgs/darwin;
+    }) else {}));
 
   };
 
diff --git a/lib/toBase64.nix b/lib/toBase64.nix
@@ -0,0 +1,34 @@
+inputs:
+
+text: let
+  inherit (inputs.nixpkgs.lib) sublist mod stringToCharacters concatMapStrings;
+  inherit (inputs.nixpkgs.lib.strings) charToInt;
+  inherit (builtins) substring foldl' genList elemAt length concatStringsSep stringLength;
+
+  lookup = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  sliceN = size: list: n: sublist (n * size) size list;
+  pows = [(64 * 64 * 64) (64 * 64) 64 1];
+  intSextets = i: map (j: mod (i / j) 64) pows;
+  compose = f: g: x: f (g x);
+  intToChar = elemAt lookup;
+  convertTripletInt = sliceInt: concatMapStrings intToChar (intSextets sliceInt);
+  sliceToInt = foldl' (acc: val: acc * 256 + val) 0;
+  convertTriplet = compose convertTripletInt sliceToInt;
+  join = concatStringsSep "";
+  convertLastSlice = slice: let
+    len = length slice;
+  in
+    if len == 1
+    then (substring 0 2 (convertTripletInt ((sliceToInt slice) * 256 * 256))) + "=="
+    else if len == 2
+    then (substring 0 3 (convertTripletInt ((sliceToInt slice) * 256))) + "="
+    else "";
+  len = stringLength text;
+  nFullSlices = len / 3;
+  bytes = map charToInt (stringToCharacters text);
+  tripletAt = sliceN 3 bytes;
+  head = genList (compose convertTriplet tripletAt) nFullSlices;
+  tail = convertLastSlice (tripletAt nFullSlices);
+
+in
+  join (head ++ [tail])
diff --git a/lib/writePythonScriptBin.nix b/lib/writePythonScriptBin.nix
@@ -0,0 +1,21 @@
+{ writeTextFile, stdenv, python3, ... }:
+
+name: packagesSelectionFun: text:
+let
+  mkScriptName = s: (builtins.replaceStrings [ "\\" ] [ "-" ] s);
+  x = writeTextFile {
+    name        = "unit-script.py";
+    executable  = true;
+    destination = "/bin/${mkScriptName name}";
+    text        = "#!/usr/bin/env python3\n${text}";
+  };
+
+in stdenv.mkDerivation {
+  name         = mkScriptName name;
+  buildInputs  = [ (python3.withPackages (pythonPackages: packagesSelectionFun pythonPackages)) ];
+  unpackPhase  = "true";
+  installPhase = ''
+    mkdir -p $out/bin
+    cp ${x}/bin/${mkScriptName name} $out/bin/${mkScriptName name}
+  '';
+}
diff --git a/machines/blechkasten/default.nix b/machines/blechkasten/default.nix
@@ -1,11 +1,14 @@
-{ config, pkgs, lib, ... }:
-
 {
 
-  networking.hostName     = "blechkasten";
-  networking.computerName = config.networking.hostName;
+  system        = "aarch64-darwin";
+  configuration = { config, pkgs, lib, ... }: {
+
+    networking.hostName     = "blechkasten";
+    networking.computerName = config.networking.hostName;
+
+    home-manager.users.katja.home.stateVersion = "24.11";
+    system.stateVersion = 4;
 
-  home-manager.users.katja.home.stateVersion = "24.11";
-  system.stateVersion = 4;
+  };
 
-}
+}+
\ No newline at end of file
diff --git a/machines/briefkasten/default.nix b/machines/briefkasten/default.nix
@@ -1,94 +1,97 @@
-{ inputs, config, ctucxConfig, lib, pkgs, ... }:
-
 {
 
-  imports = [
-    ./hardware-configuration.nix
-    ./impermanence.nix
+  system        = "x86_64-linux";
+  configuration = { config, ctucxConfig, lib, pkgs, ... }: {
 
-    ctucxConfig.programs.yt-dlp
-    ctucxConfig.programs.ocrmypdf
+    imports = [
+      ./hardware-configuration.nix
+      ./impermanence.nix
 
-    ctucxConfig.configure.router
-    ctucxConfig.configure.smarthome
+      ctucxConfig.programs.yt-dlp
+      ctucxConfig.programs.ocrmypdf
 
-    ctucxConfig.services.prometheus-exporters
-    ctucxConfig.services.restic-server
+      ctucxConfig.configure.router
+      ctucxConfig.configure.smarthome
 
+      ctucxConfig.services.prometheus-exporters
+      ctucxConfig.services.restic-server
 
-    ctucxConfig.websites."music.home.ctu.cx"
-    ctucxConfig.websites."audiobooks.home.ctu.cx"
-    ctucxConfig.websites."fedi.home.ctu.cx"
 
-    # syncthing (and it's backup)
-    ./syncthing.nix
+      ctucxConfig.websites."music.home.ctu.cx"
+      ctucxConfig.websites."audiobooks.home.ctu.cx"
+      ctucxConfig.websites."fedi.home.ctu.cx"
 
-    ./scanner-sftp.nix
-  ];
+      # syncthing (and it's backup)
+      ./syncthing.nix
 
-  age.secrets = {
-    restic-server-briefkasten.file = ../../secrets/restic-server/briefkasten.age;
-    restic-server-wanderduene.file = ../../secrets/restic-server/wanderduene.age;
-  };
+      ./scanner-sftp.nix
+    ];
 
-  dns.zones."ctu.cx".subdomains = {
-    briefkasten.AAAA        = [ config.networking.primaryIP ];
-    home.AAAA               = [ config.networking.primaryIP ];
-    "briefkasten.home".AAAA = [ config.networking.primaryIP ];
-  };
+    age.secrets = {
+      restic-server-briefkasten.file = ../../secrets/restic-server/briefkasten.age;
+      restic-server-wanderduene.file = ../../secrets/restic-server/wanderduene.age;
+    };
 
-  boot = {
-    kernelModules = [ "intel_rapl_common" ];
+    dns.zones."ctu.cx".subdomains = {
+      briefkasten.AAAA        = [ config.networking.primaryIP ];
+      home.AAAA               = [ config.networking.primaryIP ];
+      "briefkasten.home".AAAA = [ config.networking.primaryIP ];
+    };
 
-    # seems to make realtek ethernet faster?
-    kernelParams = [ "pcie_aspm=off" ];
+    boot = {
+      kernelModules = [ "intel_rapl_common" ];
 
-    initrd.network = {
-      enable = true;
-      ssh    = {
-        enable         = true;
-        port           = 22;
-        hostKeys       = [ /etc/ssh/ssh_host_rsa_key ];
-        authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
-      };
+      # seems to make realtek ethernet faster?
+      kernelParams = [ "pcie_aspm=off" ];
 
-      postCommands = ''
-        echo 'cryptsetup-askpass' >> /root/.profile
+      initrd.network = {
+        enable = true;
+        ssh    = {
+          enable         = true;
+          port           = 22;
+          hostKeys       = [ "/nix/persist/etc/ssh/ssh_host_ed25519_key" ];
+          authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
+        };
 
-        sysctl -w net.ipv6.conf.enp1s0.autoconf=0
-        sysctl -w net.ipv6.conf.enp1s0.accept_ra=0
+        postCommands = ''
+          echo 'cryptsetup-askpass' >> /root/.profile
+
+          sysctl -w net.ipv6.conf.enp1s0.autoconf=0
+          sysctl -w net.ipv6.conf.enp1s0.accept_ra=0
+
+          ip link set dev enp1s0 up
+          ip addr add 10.0.0.1/8 dev enp1s0
+          ip addr add 2a03:4000:4d:5e:acab::1/112 dev enp1s0
+        '';
+      };
 
-        ip link set dev enp1s0 up
-        ip addr add 10.0.0.1/8 dev enp1s0
-        ip addr add 2a03:4000:4d:5e:acab::1/112 dev enp1s0
-      '';
     };
 
-  };
+    nix.optimise.automatic = false;
+    nix.gc.automatic       = false;
 
-  nix.optimise.automatic = false;
-  nix.gc.automatic       = false;
+    services.logind.extraConfig = ''
+      # don’t shutdown when power button is short-pressed
+      HandlePowerKey=ignore
+    '';
 
-  services.logind.extraConfig = ''
-    # don’t shutdown when power button is short-pressed
-    HandlePowerKey=ignore
-  '';
+    networking = {
+      domain     = "home.ctu.cx";
+      primaryIP  = "2a03:4000:4d:5e:acab::1";
+      primaryIP4 = "10.0.0.1";
+    };
 
-  networking = {
-    domain     = "home.ctu.cx";
-    primaryIP  = "2a03:4000:4d:5e:acab::1";
-    primaryIP4 = "10.0.0.1";
-  };
+    services = {
+      usbmuxd.enable = true;
+      email-notify.enable = true;
+    };
 
-  services = {
-    usbmuxd.enable = true;
-    email-notify.enable = true;
-  };
+    powerManagement.cpuFreqGovernor    = "powersave";
+    hardware.cpu.intel.updateMicrocode = true;
 
-  powerManagement.cpuFreqGovernor    = "powersave";
-  hardware.cpu.intel.updateMicrocode = true;
+    system.stateVersion = "22.11"; # Did you read the comment?
+    home-manager.users.katja.home.stateVersion = "22.11";
 
-  system.stateVersion = "22.11"; # Did you read the comment?
-  home-manager.users.katja.home.stateVersion = "22.11";
+  };
 
-}
+}+
\ No newline at end of file
diff --git a/machines/hector/default.nix b/machines/hector/default.nix
@@ -1,115 +1,118 @@
-{ config, ctucxConfig, lib, pkgs, ... }:
-
 {
 
-  imports = [
-    ./hardware-configuration.nix
-
-    ctucxConfig.services.prometheus-exporters
-    ctucxConfig.services.dns-server
-    ctucxConfig.services.syncthing
+  system        = "x86_64-linux";
+  configuration = { config, dnsNix, ctucxConfig, lib, pkgs, ... }: {
 
-    # website / webservices
-    ctucxConfig.websites."ctu.cx"
-    ctucxConfig.websites."things.ctu.cx"
-    ctucxConfig.websites."bikemap.ctu.cx"
-    ctucxConfig.websites."photos.ctu.cx"
-    ctucxConfig.websites."grocy.ctu.cx"
+    imports = [
+      ./hardware-configuration.nix
 
-    # monitoring
-    ctucxConfig.websites."prometheus.ctu.cx"
-    ctucxConfig.websites."grafana.ctu.cx"
+      ctucxConfig.services.prometheus-exporters
+      ctucxConfig.services.dns-server
+      ctucxConfig.services.syncthing
 
-    # cal-/card-dav server (radicale)
-    ctucxConfig.websites."dav.ctu.cx"
+      # website / webservices
+      ctucxConfig.websites."ctu.cx"
+      ctucxConfig.websites."things.ctu.cx"
+      ctucxConfig.websites."bikemap.ctu.cx"
+      ctucxConfig.websites."photos.ctu.cx"
+      ctucxConfig.websites."grocy.ctu.cx"
 
-    # vaultwarden password-store
-    ctucxConfig.websites."vault.ctu.cx"
+      # monitoring
+      ctucxConfig.websites."prometheus.ctu.cx"
+      ctucxConfig.websites."grafana.ctu.cx"
 
-    # git server (gitolite+stagit)
-    ctucxConfig.websites."git.ctu.cx"
+      # cal-/card-dav server (radicale)
+      ctucxConfig.websites."dav.ctu.cx"
 
-    # fediverse server (gotosocial)
-    ctucxConfig.websites."fedi.ctu.cx"
+      # vaultwarden password-store
+      ctucxConfig.websites."vault.ctu.cx"
 
-    # mailserver
-    ctucxConfig.services.mailserver
+      # git server (gitolite+stagit)
+      ctucxConfig.websites."git.ctu.cx"
 
-    # matrix server
-    ctucxConfig.services.matrix-synapse
-    ctucxConfig.services.mautrix-whatsapp
-  ];
+      # fediverse server (gotosocial)
+      ctucxConfig.websites."fedi.ctu.cx"
 
-  dns.zones."ctu.cx".subdomains."${config.networking.hostName}" = (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
+      # mailserver
+      ctucxConfig.services.mailserver
 
-  age.secrets.restic-server-briefkasten.file = ../../secrets/restic-server/briefkasten.age;
-  age.secrets.restic-server-wanderduene.file = ../../secrets/restic-server/wanderduene.age;
-
-  boot.initrd.network = {
-    enable = true;
-    ssh    = {
-      enable         = true;
-      port           = 22;
-      hostKeys       = [ /etc/ssh/ssh_host_rsa_key ];
-      authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
-    };
+      # matrix server
+      ctucxConfig.services.matrix-synapse
+      ctucxConfig.services.mautrix-whatsapp
+    ];
 
-    postCommands = ''
-      ip link set dev ens3 up
+    dns.zones."ctu.cx".subdomains."${config.networking.hostName}" = dnsNix.combinators.host config.networking.primaryIP4 config.networking.primaryIP;
 
-      ip addr add ${config.networking.primaryIP}/128 dev ens3
-      ip route add default via fe80::1 dev ens3 onlink
+    age.secrets.restic-server-briefkasten.file = ../../secrets/restic-server/briefkasten.age;
+    age.secrets.restic-server-wanderduene.file = ../../secrets/restic-server/wanderduene.age;
 
-      ip addr add ${config.networking.primaryIP4}/22 dev ens3
-      ip route add default via 194.59.204.1 dev ens3 onlink
+    boot.initrd.network = {
+      enable = true;
+      ssh    = {
+        enable         = true;
+        port           = 22;
+        hostKeys       = [ "/etc/ssh/ssh_host_ed25519_key" ];
+        authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
+      };
 
-      echo 'cryptsetup-askpass' >> /root/.profile
-    '';
-  };
+      postCommands = ''
+        ip link set dev ens3 up
 
-  networking = {
-    primaryIP    = "2a03:4000:34:23e::1";
-    primaryIP4   = "194.59.205.194";
+        ip addr add ${config.networking.primaryIP}/128 dev ens3
+        ip route add default via fe80::1 dev ens3 onlink
 
-    useNetworkd  = true;
-    useDHCP      = false;
+        ip addr add ${config.networking.primaryIP4}/22 dev ens3
+        ip route add default via 194.59.204.1 dev ens3 onlink
 
-    firewall.enable = true;
-    nftables.enable = true;
-  };
+        echo 'cryptsetup-askpass' >> /root/.profile
+      '';
+    };
 
-  systemd.network = {
-    enable             = true;
-    wait-online.enable = false;
+    networking = {
+      primaryIP    = "2a03:4000:34:23e::1";
+      primaryIP4   = "194.59.205.194";
 
-    networks = {
-      "10-ens3" = {
-        matchConfig.Name = "ens3";
+      useNetworkd  = true;
+      useDHCP      = false;
 
-        address = [ "${config.networking.primaryIP4}/22" "${config.networking.primaryIP}/64" ];
+      firewall.enable = true;
+      nftables.enable = true;
+    };
 
-        networkConfig = {
-          DNS = [ "8.8.8.8" "1.1.1.1" ];
+    systemd.network = {
+      enable             = true;
+      wait-online.enable = false;
+
+      networks = {
+        "10-ens3" = {
+          matchConfig.Name = "ens3";
+
+          address = [ "${config.networking.primaryIP4}/22" "${config.networking.primaryIP}/64" ];
+
+          networkConfig = {
+            DNS = [ "8.8.8.8" "1.1.1.1" ];
+          };
+
+          routes = [
+            {
+              Gateway       = "fe80::1";
+              GatewayOnLink = true;
+            }
+            {
+              Gateway       = "194.59.204.1";
+              GatewayOnLink = true;
+            }
+          ];
         };
-
-        routes = [
-          {
-            Gateway       = "fe80::1";
-            GatewayOnLink = true;
-          }
-          {
-            Gateway       = "194.59.204.1";
-            GatewayOnLink = true;
-          }
-        ];
       };
     };
-  };
 
-  services.syncthing.dataDir   = "/home/katja/syncthing";
-  services.email-notify.enable = true;
+    services.syncthing.dataDir   = "/home/katja/syncthing";
+    services.email-notify.enable = true;
+
+    system.stateVersion = "24.11";
+    home-manager.users.katja.home.stateVersion = "24.11";
 
-  system.stateVersion = "24.11";
-  home-manager.users.katja.home.stateVersion = "24.11";
+  };
 
-}
+}+
\ No newline at end of file
diff --git a/machines/seifenkiste/default.nix b/machines/seifenkiste/default.nix
@@ -1,51 +1,55 @@
-{ config, ctucxConfig, lib, pkgs, ... }:
-
 {
 
-  imports = [
-    ./hardware-configuration.nix
+  system        = "x86_64-linux";
+  configuration = { config, ctucxConfig, lib, pkgs, ... }: {
+
+    imports = [
+      ./hardware-configuration.nix
+
+      ctucxConfig.services.prometheus-exporters
+      ctucxConfig.services.keyd
 
-    ctucxConfig.services.prometheus-exporters
-    ctucxConfig.services.keyd
+      ctucxConfig.wm.gnome
+    ];
 
-    ctucxConfig.wm.gnome
-  ];
+    deployment.allowLocalDeployment = true;
 
-  deployment.allowLocalDeployment = true;
+    boot = {
+      loader.systemd-boot.enable = lib.mkForce false;
 
-  boot = {
-    loader.systemd-boot.enable = lib.mkForce false;
+      lanzaboote = {
+        enable = true;
+        pkiBundle = "/etc/secureboot";
+      };
 
-    lanzaboote = {
-      enable = true;
-      pkiBundle = "/etc/secureboot";
+      kernelPackages = pkgs.linuxPackages_latest;
+
+      initrd.systemd.enable = true;
     };
 
-    kernelPackages = pkgs.linuxPackages_latest;
+    nix = {
+      settings.experimental-features = [ "pipe-operator" ];
+      gc.automatic = lib.mkForce false;
+    };
 
-    initrd.systemd.enable = true;
-  };
+    services = {
+      openssh.enable = true;
+      fprintd.enable = true;
+      fwupd.enable   = true;
+    };
 
-  nix = {
-    settings.experimental-features = [ "pipe-operator" ];
-    gc.automatic = lib.mkForce false;
-  };
+    security.pam.services.login.fprintAuth = lib.mkForce false;
 
-  services = {
-    openssh.enable = true;
-    fprintd.enable = true;
-    fwupd.enable   = true;
-  };
+    networking.networkmanager.fccUnlockScripts = [
+      { id = "2c7c:030a"; path = "${pkgs.modemmanager}/share/ModemManager/fcc-unlock.available.d/2c7c"; }
+    ];
 
-  security.pam.services.login.fprintAuth = lib.mkForce false;
+    hardware.cpu.intel.updateMicrocode = true;
 
-  networking.networkmanager.fccUnlockScripts = [
-    { id = "2c7c:030a"; path = "${pkgs.modemmanager}/share/ModemManager/fcc-unlock.available.d/2c7c"; }
-  ];
+    system.stateVersion = "24.11";
+    home-manager.users.katja.home.stateVersion = "24.11";
 
-  hardware.cpu.intel.updateMicrocode = true;
+  };
 
-  system.stateVersion = "24.11";
-  home-manager.users.katja.home.stateVersion = "24.11";
 }
 
diff --git a/machines/trabbi/default.nix b/machines/trabbi/default.nix
@@ -1,75 +1,77 @@
-{ config, ctucxConfig, lib, pkgs, ... }:
-
 {
 
-  imports = [
-    ./hardware-configuration.nix
-
-    ctucxConfig.services.prometheus-exporters
-    ctucxConfig.services.dns-server
+  system        = "x86_64-linux";
+  configuration = { config, dnsNix, ctucxConfig, lib, pkgs, ... }: {
 
-    ctucxConfig.websites."zuggeschmack.de"
-  ];
+    imports = [
+      ./hardware-configuration.nix
 
-  dns.zones."ctu.cx".subdomains."${config.networking.hostName}" = (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
+      ctucxConfig.services.prometheus-exporters
+      ctucxConfig.services.dns-server
 
-  age.secrets.restic-server-briefkasten.file = ../../secrets/restic-server/briefkasten.age;
-  age.secrets.restic-server-wanderduene.file = ../../secrets/restic-server/wanderduene.age;
+      ctucxConfig.websites."zuggeschmack.de"
+    ];
 
-  boot.initrd.network = {
-    enable = true;
-    ssh    = {
-      enable         = true;
-      port           = 22;
-      hostKeys       = [ /etc/ssh/ssh_host_rsa_key ];
-      authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
-    };
+    dns.zones."ctu.cx".subdomains."${config.networking.hostName}" = (dnsNix.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
 
-    postCommands = ''
-      ip link set dev ens3 up
-      ip addr add ${config.networking.primaryIP}/128 dev ens3
-      ip route add default via fe80::1 dev ens3 onlink
-
-      ip addr add ${config.networking.primaryIP4}/22 dev ens3
-      ip route add default via ${config.networking.defaultGateway.address} dev ens3 onlink
-      echo 'cryptsetup-askpass' >> /root/.profile
-    '';
-  };
+    age.secrets.restic-server-briefkasten.file = ../../secrets/restic-server/briefkasten.age;
+    age.secrets.restic-server-wanderduene.file = ../../secrets/restic-server/wanderduene.age;
 
-  networking = {
-    primaryIP    = "2a03:4000:50:e8::1";
-    primaryIP4   = "94.16.104.148";
+    boot.initrd.network = {
+      enable = true;
+      ssh    = {
+        enable         = true;
+        port           = 22;
+        hostKeys       = [ "/etc/ssh/ssh_host_ed25519_key" ];
+        authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
+      };
 
-    resolvconf.enable = false;
-    nameservers       = [ "8.8.8.8" "1.1.1.1" ];
+      postCommands = ''
+        ip link set dev ens3 up
+        ip addr add ${config.networking.primaryIP}/128 dev ens3
+        ip route add default via fe80::1 dev ens3 onlink
 
-    defaultGateway  = {
-      interface = "ens3";
-      address    = "94.16.104.1";
-    };
-    defaultGateway6 = {
-      interface = "ens3";
-      address   = "fe80::1";
+        ip addr add ${config.networking.primaryIP4}/22 dev ens3
+        ip route add default via ${config.networking.defaultGateway.address} dev ens3 onlink
+        echo 'cryptsetup-askpass' >> /root/.profile
+      '';
     };
 
-    interfaces.ens3 = {
-      ipv4.addresses = [{
-        address = config.networking.primaryIP4;
-        prefixLength = 22;
-      }];
-      ipv6.addresses = [{
-        address      = config.networking.primaryIP;
-        prefixLength = 64;
-      }];
+    networking = {
+      primaryIP    = "2a03:4000:50:e8::1";
+      primaryIP4   = "94.16.104.148";
+
+      resolvconf.enable = false;
+      nameservers       = [ "8.8.8.8" "1.1.1.1" ];
+
+      defaultGateway  = {
+        interface = "ens3";
+        address    = "94.16.104.1";
+      };
+      defaultGateway6 = {
+        interface = "ens3";
+        address   = "fe80::1";
+      };
+
+      interfaces.ens3 = {
+        ipv4.addresses = [{
+          address = config.networking.primaryIP4;
+          prefixLength = 22;
+        }];
+        ipv6.addresses = [{
+          address      = config.networking.primaryIP;
+          prefixLength = 64;
+        }];
+      };
+
+      nftables.enable = true;
     };
 
-    nftables.enable = true;
-  };
-
-  services.email-notify.enable = true;
+    services.email-notify.enable = true;
 
-  system.stateVersion = "23.11";
-  home-manager.users.katja.home.stateVersion = "23.11";
+    system.stateVersion = "23.11";
+    home-manager.users.katja.home.stateVersion = "23.11";
 
-}
+  };
 
+}+
\ No newline at end of file
diff --git a/machines/wanderduene/default.nix b/machines/wanderduene/default.nix
@@ -1,138 +1,141 @@
-{ nodes, config, ctucxConfig, lib, pkgs, ... }:
-
 {
 
-  deployment.buildOnTarget = false;
+  system        = "x86_64-linux";
+  configuration = { nodes, config, dnsNix, ctucxConfig, lib, pkgs, ... }: {
 
+    deployment.buildOnTarget = false;
 
-  imports = [
-    ./hardware-configuration.nix
 
-    ctucxConfig.services.prometheus-exporters
-    ctucxConfig.services.dns-server
+    imports = [
+      ./hardware-configuration.nix
 
-    ctucxConfig.websites."ip.ctu.cx"
-    ctucxConfig.websites."dendrite.ctucx.de"
+      ctucxConfig.services.prometheus-exporters
+      ctucxConfig.services.dns-server
 
-    ./rclone-restic-server.nix
-    ./syncthing.nix
-  ];
+      ctucxConfig.websites."ip.ctu.cx"
+      ctucxConfig.websites."dendrite.ctucx.de"
 
-  documentation.nixos.enable = false;
+      ./rclone-restic-server.nix
+      ./syncthing.nix
+    ];
 
-  dns.zones."ctu.cx".subdomains."${config.networking.hostName}" = (pkgs.dns.lib.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
+    documentation.nixos.enable = false;
 
-  age.secrets.wireguard-privkey = {
-    file = ../../secrets/wanderduene/wireguard-privkey.age;
-    owner = "systemd-network";
-    group = "systemd-network";
-  };
+    dns.zones."ctu.cx".subdomains."${config.networking.hostName}" = (dnsNix.combinators.host config.networking.primaryIP4 config.networking.primaryIP);
 
-  boot.kernel.sysctl."net.ipv6.conf.all.proxy_ndp" = true;
-  boot.initrd.network = {
-    enable = true;
-    ssh    = {
-      enable         = true;
-      port           = 22;
-      hostKeys       = [ /etc/ssh/ssh_host_rsa_key ];
-      authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
+    age.secrets.wireguard-privkey = {
+      file = ../../secrets/wanderduene/wireguard-privkey.age;
+      owner = "systemd-network";
+      group = "systemd-network";
     };
 
-    postCommands = ''
-      ip link set dev ens3 up
+    boot.kernel.sysctl."net.ipv6.conf.all.proxy_ndp" = true;
+    boot.initrd.network = {
+      enable = true;
+      ssh    = {
+        enable         = true;
+        port           = 22;
+        hostKeys       = [ "/etc/ssh/ssh_host_ed25519_key" ];
+        authorizedKeys = with lib; concatLists (mapAttrsToList (name: user: if elem "wheel" user.extraGroups then user.openssh.authorizedKeys.keys else []) config.users.users);
+      };
 
-      ip addr add ${config.networking.primaryIP}/128 dev ens3
-      ip route add default via fe80::1 dev ens3 onlink
+      postCommands = ''
+        ip link set dev ens3 up
 
-      ip addr add ${config.networking.primaryIP4}/22 dev ens3
-      ip route add default via 194.36.144.1 dev ens3 onlink
+        ip addr add ${config.networking.primaryIP}/128 dev ens3
+        ip route add default via fe80::1 dev ens3 onlink
 
-      echo 'cryptsetup-askpass' >> /root/.profile
-    '';
-  };
+        ip addr add ${config.networking.primaryIP4}/22 dev ens3
+        ip route add default via 194.36.144.1 dev ens3 onlink
 
-  networking = {
-    primaryIP    = "2a03:4000:4d:5e::1";
-    primaryIP4   = "194.36.145.49";
+        echo 'cryptsetup-askpass' >> /root/.profile
+      '';
+    };
 
-    useNetworkd  = true;
-    useDHCP      = false;
+    networking = {
+      primaryIP    = "2a03:4000:4d:5e::1";
+      primaryIP4   = "194.36.145.49";
 
-    nftables.enable = true;
+      useNetworkd  = true;
+      useDHCP      = false;
 
-    firewall = {
-      enable          = true;
-      allowedUDPPorts = [ 51820 ];
-    };
-  };
+      nftables.enable = true;
 
-  systemd.network = {
-    enable             = true;
-    wait-online.enable = false;
-    
-    config.networkConfig = {
-      IPv6Forwarding = true;
+      firewall = {
+        enable          = true;
+        allowedUDPPorts = [ 51820 ];
+      };
     };
 
-    netdevs."20-wg0" = {
-      netdevConfig = {
-        Kind = "wireguard";
-        Name = "wg0";
+    systemd.network = {
+      enable             = true;
+      wait-online.enable = false;
+      
+      config.networkConfig = {
+        IPv6Forwarding = true;
       };
 
-      wireguardConfig = {
-        PrivateKeyFile = config.age.secrets.wireguard-privkey.path;
-        ListenPort     = 51820;
-        FirewallMark   = 51820;
+      netdevs."20-wg0" = {
+        netdevConfig = {
+          Kind = "wireguard";
+          Name = "wg0";
+        };
+
+        wireguardConfig = {
+          PrivateKeyFile = config.age.secrets.wireguard-privkey.path;
+          ListenPort     = 51820;
+          FirewallMark   = 51820;
+        };
+
+        wireguardPeers = [{
+          PublicKey           = "nvyhYuWJl/dKyV/2+bDrUisvL3mi38PsNzfdIDDwSjY=";
+          AllowedIPs          = [ "172.17.0.0/24" "2a03:4000:4d:5e:acab::/112" ];
+          PersistentKeepalive = 10;
+        }];
       };
 
-      wireguardPeers = [{
-        PublicKey           = "nvyhYuWJl/dKyV/2+bDrUisvL3mi38PsNzfdIDDwSjY=";
-        AllowedIPs          = [ "172.17.0.0/24" "2a03:4000:4d:5e:acab::/112" ];
-        PersistentKeepalive = 10;
-      }];
-    };
 
+      networks = {
+        "10-ens3" = {
+          matchConfig.Name = "ens3";
 
-    networks = {
-      "10-ens3" = {
-        matchConfig.Name = "ens3";
+          address = [ "${config.networking.primaryIP4}/24" "${config.networking.primaryIP}/64" ];
 
-        address = [ "${config.networking.primaryIP4}/24" "${config.networking.primaryIP}/64" ];
+          networkConfig = {
+            DNS = [ "8.8.8.8" "1.1.1.1" ];
+          };
 
-        networkConfig = {
-          DNS = [ "8.8.8.8" "1.1.1.1" ];
+          routes = [
+            {
+              Gateway       = "fe80::1";
+              GatewayOnLink = true;
+            }
+            {
+              Gateway       = "194.36.144.1";
+              GatewayOnLink = true;
+            }
+          ];
         };
 
-        routes = [
-          {
-            Gateway       = "fe80::1";
-            GatewayOnLink = true;
-          }
-          {
-            Gateway       = "194.36.144.1";
-            GatewayOnLink = true;
-          }
-        ];
-      };
+        "20-wg0" ={
+          matchConfig.Name = "wg0";
 
-      "20-wg0" ={
-        matchConfig.Name = "wg0";
-
-        address = [ "2a03:4000:4d:5e:acab::100/112"];
+          address = [ "2a03:4000:4d:5e:acab::100/112"];
+        };
       };
     };
-  };
 
-  services.ndppd = {
-    enable = true;
-    proxies.ens3.rules."2a03:4000:4d:5e:acab::/112" = {
-      method    = "iface";
-      interface = "wg0";
+    services.ndppd = {
+      enable = true;
+      proxies.ens3.rules."2a03:4000:4d:5e:acab::/112" = {
+        method    = "iface";
+        interface = "wg0";
+      };
     };
-  };
 
-  system.stateVersion = "23.05";
-  home-manager.users.katja.home.stateVersion = "23.05";
+    system.stateVersion = "23.05";
+    home-manager.users.katja.home.stateVersion = "23.05";
+
+  };
 
-}
+}+
\ No newline at end of file
diff --git a/modules/nixos/dns.nix b/modules/nixos/dns.nix
@@ -1,4 +1,4 @@
-{ nodes, config, lib, pkgs, ... }:
+{ dnsNix, nodes, config, lib, pkgs, ... }:
 
 #
 # this module requires lix' experimental `pipe-operator` feature!

@@ -60,13 +60,13 @@ in {
 
     # contains dns entries defined on the local host
     zones = mkOption {
-      type    = lib.types.attrsOf pkgs.dns.lib.types.subzone;
+      type    = lib.types.attrsOf dnsNix.types.subzone;
       default = {};
     };
 
     # contains dns entries defined on the local host and on remote hosts, merged together
     allZones = mkOption {
-      type    = lib.types.attrsOf pkgs.dns.lib.types.zone;
+      type    = lib.types.attrsOf dnsNix.types.zone;
       default = {};
     };
 

@@ -81,7 +81,20 @@ in {
     };
   };
 
-  config = mkIf cfg.enable {
+  config = mkIf cfg.enable (let 
+    zoneFiles = (
+      cfg.allZones
+      |> lib.mapAttrs' (name: zone: {
+        name  = name;
+        value = pkgs.writeTextFile {
+          name = "${name}.zone";
+          text = dnsNix.types.zoneToString name (dnsNix.evalZone name zone);
+        };
+      })
+    );
+
+  in {
+
     networking.firewall.allowedTCPPorts = [ 53 ];
     networking.firewall.allowedUDPPorts = [ 53 ];
 

@@ -92,10 +105,10 @@ in {
     );
 
     environment.etc = lib.mkIf cfg.primary (
-      cfg.allZones
-      |> lib.mapAttrs' (name: zone: {
-         name = "${cfg.zonesDir}/${name}.zone";
-         value = { source = pkgs.dns.util."${config.nixpkgs.system}".writeZone name zone; };
+      zoneFiles
+      |> lib.mapAttrs' (name: file: {
+        name = "${cfg.zonesDir}/${name}.zone";
+        value.source = file;
       })
     );
 

@@ -201,8 +214,8 @@ in {
 
     systemd.services.knot = lib.mkIf cfg.primary {
       reloadTriggers = (
-        cfg.allZones
-        |> lib.mapAttrsToList (name: zone: pkgs.dns.util."${config.nixpkgs.system}".writeZone name zone)
+        zoneFiles
+        |> lib.mapAttrsToList (name: zone: zone)
        ) ++ (
         cfg.extraZones
         |> lib.mapAttrsToList (name: zone: (if (builtins.hasAttr "storage" zone) then "${zone.storage}/${zone.file}" else "${zone.file}"))

@@ -224,6 +237,6 @@ in {
         ${config.services.knot.package}/bin/knotc reload
       '');
     };
-  };
+  });
 
 }
diff --git a/pkgs/adwaita-colors.nix b/pkgs/all/adwaita-colors-icon-theme.nix
diff --git a/pkgs/agenix/agenix.sh b/pkgs/all/agenix/agenix.sh
diff --git a/pkgs/agenix/default.nix b/pkgs/all/agenix/default.nix
diff --git a/pkgs/all/bgiparser.nix b/pkgs/all/bgiparser.nix
@@ -0,0 +1,47 @@
+{ lib, pkgs, stdenv, ... }:
+
+stdenv.mkDerivation {
+
+  name = "bgiparser";
+
+  buildInputs = [ pkgs.python3 ];
+
+  src = [
+    (pkgs.fetchFromGitHub {
+      name   = "bgiparser";
+      owner  = "mnrkbys";
+      repo   = "bgiparser";
+      rev    = "c9f7443cbe59f9af933e09f95fea804bbd9175f7";
+      sha256 = "0aa433pr09ins99g21bj2yp0p3h282cki9j1yxi27rln3cdyhcaq";
+    })
+    (pkgs.fetchFromGitHub {
+      name   = "ccl-bplist";
+      owner  = "cclgroupltd";
+      repo   = "ccl-bplist";
+      rev    = "76d04b7fc20c403f27248d8dcae646b524cdcc0a";
+      sha256 = "0br0r2gmwmdibla45mildhyf1mmyywxzw4yxd208qqlmzhiab7kk";
+    })
+  ];
+
+  sourceRoot = ".";
+
+  installPhase = ''
+    mkdir -p "$out/bin";
+    mkdir -p "$out/lib";
+
+    cp "./ccl-bplist/ccl_bplist.py"          "$out/lib/ccl_bplist.py";
+    cp "./bgiparser/bgiparser_foundation.py" "$out/lib/bgiparser_foundation.py";
+    cp "./bgiparser/bgiparser.py"            "$out/lib/bgiparser.py";
+
+    ln -s "$out/lib/bgiparser.py"            "$out/bin/bgiparser";
+
+    chmod +x "$out/lib/bgiparser.py";
+  '';
+
+  meta = with lib; {
+    description = "backgrounditems.btm/BackgroundItems-v*.btm parser";
+    homepage    = "https://github.com/mnrkbys/bgiparser";
+    license     = licenses.asl20;
+  };
+
+}
diff --git a/pkgs/cinny.nix b/pkgs/all/cinny.nix
diff --git a/pkgs/gotosocial/default.nix b/pkgs/all/gotosocial/default.nix
diff --git a/pkgs/all/homebridge/default.nix b/pkgs/all/homebridge/default.nix
@@ -0,0 +1,26 @@
+{ lib, mkYarnPackage, ... }:
+
+mkYarnPackage rec {
+
+  src  = ../homebridge;
+
+  packageJSON = ./package.json;
+  yarnLock    = ./yarn.lock;
+
+  buildPhase = "true";
+  distPhase  = "true";
+  installPhase = ''
+    mkdir -p $out/bin
+    ln -sf ''${node_modules}/.bin/homebridge $out/bin/homebridge
+    cat > $out/env <<EOF
+    NODE_PATH=''${node_modules}
+    EOF
+  '';
+
+  meta = with lib; {
+    description = "HomeKit support for the impatient.";
+    homepage    = "https://github.com/homebridge/homebridge";
+    license     = licenses.asl20;
+  };
+
+}+
\ No newline at end of file
diff --git a/pkgs/homebridge/package.json b/pkgs/all/homebridge/package.json
diff --git a/pkgs/homebridge/yarn.lock b/pkgs/all/homebridge/yarn.lock
diff --git a/pkgs/masto-fe-standalone/0001-set-a-default-instance.patch b/pkgs/all/masto-fe-standalone/0001-set-a-default-instance.patch
diff --git a/pkgs/masto-fe-standalone/0002-update-default-state.patch b/pkgs/all/masto-fe-standalone/0002-update-default-state.patch
diff --git a/pkgs/masto-fe-standalone/default.nix b/pkgs/all/masto-fe-standalone/default.nix
diff --git a/pkgs/all/mbusd.nix b/pkgs/all/mbusd.nix
@@ -0,0 +1,23 @@
+{ lib, stdenv, fetchFromGitHub, cmake, pkg-config, ... }:
+
+stdenv.mkDerivation rec {
+
+  pname = "mbusd";
+  version = "0.5.0";
+
+  src = fetchFromGitHub {
+    owner  = "3cky";
+    repo   = pname;
+    rev    = "v${version}";
+    sha256 = "1mvrwr02vcsgf9lc9bq4mhr0s6ww5z7ml7lwpyrl4axpz59i4l9s";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config ];
+
+  meta = with lib; {
+    description = "mbusd is open-source Modbus TCP to Modbus RTU (RS-232/485) gateway";
+    homepage    = "https://github.com/3cky/mbusd";
+    license     = licenses.bsd3;
+  };
+
+}
diff --git a/pkgs/phockup.nix b/pkgs/all/phockup.nix
diff --git a/pkgs/rofi-iwd-wifi-menu.nix b/pkgs/all/rofi-iwd-wifi-menu.nix
diff --git a/pkgs/slurp.nix b/pkgs/all/slurp.nix
diff --git a/pkgs/bgiparser.nix b/pkgs/bgiparser.nix
@@ -1,39 +0,0 @@
-{ pkgs, stdenv, ... }:
-
-stdenv.mkDerivation {
-  name = "bgiparser";
-
-  buildInputs = [ pkgs.python3 ];
-
-  src = [
-    (pkgs.fetchFromGitHub {
-      name   = "bgiparser";
-      owner  = "mnrkbys";
-      repo   = "bgiparser";
-      rev    = "c9f7443cbe59f9af933e09f95fea804bbd9175f7";
-      sha256 = "0aa433pr09ins99g21bj2yp0p3h282cki9j1yxi27rln3cdyhcaq";
-    })
-    (pkgs.fetchFromGitHub {
-      name   = "ccl-bplist";
-      owner  = "cclgroupltd";
-      repo   = "ccl-bplist";
-      rev    = "76d04b7fc20c403f27248d8dcae646b524cdcc0a";
-      sha256 = "0br0r2gmwmdibla45mildhyf1mmyywxzw4yxd208qqlmzhiab7kk";
-    })
-  ];
-
-  sourceRoot = ".";
-
-  installPhase = ''
-    mkdir -p "$out/bin";
-    mkdir -p "$out/lib";
-
-    cp "./ccl-bplist/ccl_bplist.py"          "$out/lib/ccl_bplist.py";
-    cp "./bgiparser/bgiparser_foundation.py" "$out/lib/bgiparser_foundation.py";
-    cp "./bgiparser/bgiparser.py"            "$out/lib/bgiparser.py";
-
-    ln -s "$out/lib/bgiparser.py"            "$out/bin/bgiparser";
-
-    chmod +x "$out/lib/bgiparser.py";
-  '';
-}
diff --git a/pkgs/darwin/XPCEventStreamHandler/default.nix b/pkgs/darwin/XPCEventStreamHandler/default.nix
@@ -1,4 +1,4 @@
-{stdenv, runCommand, ...}:
+{ lib, stdenv, runCommand, ... }:
 
 let
   buildSymlinks = runCommand "macvim-build-symlinks" {} ''

@@ -24,4 +24,12 @@ in stdenv.mkDerivation {
     mkdir -p $out/bin
     cp xpc_set_event_stream_handler $out/bin/
   '';
+
+  meta = with lib; {
+    description = "Consume a com.apple.iokit.matching event, then run the executable specified in the first parameter.";
+    homepage    = "https://github.com/snosrap/xpc_set_event_stream_handler";
+    license     = licenses.mit;
+    platforms   = platforms.darwin;
+  };
+
 }
diff --git a/pkgs/darwin/default.nix b/pkgs/darwin/default.nix
@@ -1,20 +0,0 @@
-final: prev:
-
-{
-
-  uhubDaemon             = final.callPackage ./uhubDaemon.nix {};
-  XPCEventStreamHandler  = final.callPackage ./XPCEventStreamHandler {};
-
-  # disable pyopenssl-dependency on cloudscraper since it is broken on aarch64
-  python3 = prev.python3.override {
-    packageOverrides = python3-final: python3-prev: {
-      cloudscraper = python3-prev.cloudscraper.override {
-        requests-toolbelt = (python3-prev.requests-toolbelt.override {
-          pyopenssl = null;
-        }).overridePythonAttrs (old: {
-          doCheck = false;
-        });
-      };
-    };
-  };
-}-
\ No newline at end of file
diff --git a/pkgs/darwinOverlay.nix b/pkgs/darwinOverlay.nix
@@ -0,0 +1,18 @@
+final: prev:
+
+{
+
+  # disable pyopenssl-dependency on cloudscraper since it is broken on aarch64
+  python3 = prev.python3.override {
+    packageOverrides = python3-final: python3-prev: {
+      cloudscraper = python3-prev.cloudscraper.override {
+        requests-toolbelt = (python3-prev.requests-toolbelt.override {
+          pyopenssl = null;
+        }).overridePythonAttrs (old: {
+          doCheck = false;
+        });
+      };
+    };
+  };
+
+}+
\ No newline at end of file
diff --git a/pkgs/homebridge/default.nix b/pkgs/homebridge/default.nix
@@ -1,17 +0,0 @@
-{ mkYarnPackage, ... }:
-
-mkYarnPackage rec {
-  src  = ../homebridge;
-
-  packageJSON = ./package.json;
-  yarnLock    = ./yarn.lock;
-  buildPhase = "true";
-  distPhase  = "true";
-  installPhase = ''
-    mkdir -p $out/bin
-    ln -sf ''${node_modules}/.bin/homebridge $out/bin/homebridge
-    cat > $out/env <<EOF
-    NODE_PATH=''${node_modules}
-    EOF
-  '';
-}-
\ No newline at end of file
diff --git a/pkgs/mbusd.nix b/pkgs/mbusd.nix
@@ -1,15 +0,0 @@
-{ stdenv, fetchFromGitHub, cmake, pkg-config, ... }:
-
-stdenv.mkDerivation rec {
-  pname = "mbusd";
-  version = "0.5.0";
-
-  src = fetchFromGitHub {
-    owner = "3cky";
-    repo = pname;
-    rev = "v${version}";
-    sha256 = "1mvrwr02vcsgf9lc9bq4mhr0s6ww5z7ml7lwpyrl4axpz59i4l9s";
-  };
-
-  nativeBuildInputs = [ cmake pkg-config ];
-}
diff --git a/pkgs/overlay.nix b/pkgs/overlay.nix
@@ -1,20 +0,0 @@
-final: prev:
-
-{
-
-  toBase64                 = (final.callPackage ./toBase64.nix {}).toBase64;
-  writePythonScriptBin     = (final.callPackage ./writePythonScriptBin.nix {}).writePythonScriptBin;
-
-  adwaita-colors-icon-theme = final.callPackage ./adwaita-colors.nix {};
-  phockup                   = final.callPackage ./phockup.nix {};
-  gotosocial                = final.callPackage ./gotosocial {};
-  cinny                     = final.callPackage ./cinny.nix {};
-  mbusd                     = final.callPackage ./mbusd.nix {};
-  homebridge                = final.callPackage ./homebridge {};
-  agenix                    = final.callPackage ./agenix {};
-  rofi-iwd-wifi-menu        = final.callPackage ./rofi-iwd-wifi-menu.nix {};
-  masto-fe-standalone       = final.callPackage ./masto-fe-standalone {};
-  slurp                     = final.callPackage ./slurp.nix {};
-  bgiparser                 = final.callPackage ./bgiparser.nix {};
-
-}
diff --git a/pkgs/toBase64.nix b/pkgs/toBase64.nix
@@ -1,36 +0,0 @@
-{ lib, ... }:
-
-{
-
-  toBase64 = text: let
-    inherit (lib) sublist mod stringToCharacters concatMapStrings;
-    inherit (lib.strings) charToInt;
-    inherit (builtins) substring foldl' genList elemAt length concatStringsSep stringLength;
-    lookup = stringToCharacters "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-    sliceN = size: list: n: sublist (n * size) size list;
-    pows = [(64 * 64 * 64) (64 * 64) 64 1];
-    intSextets = i: map (j: mod (i / j) 64) pows;
-    compose = f: g: x: f (g x);
-    intToChar = elemAt lookup;
-    convertTripletInt = sliceInt: concatMapStrings intToChar (intSextets sliceInt);
-    sliceToInt = foldl' (acc: val: acc * 256 + val) 0;
-    convertTriplet = compose convertTripletInt sliceToInt;
-    join = concatStringsSep "";
-    convertLastSlice = slice: let
-      len = length slice;
-    in
-      if len == 1
-      then (substring 0 2 (convertTripletInt ((sliceToInt slice) * 256 * 256))) + "=="
-      else if len == 2
-      then (substring 0 3 (convertTripletInt ((sliceToInt slice) * 256))) + "="
-      else "";
-    len = stringLength text;
-    nFullSlices = len / 3;
-    bytes = map charToInt (stringToCharacters text);
-    tripletAt = sliceN 3 bytes;
-    head = genList (compose convertTriplet tripletAt) nFullSlices;
-    tail = convertLastSlice (tripletAt nFullSlices);
-  in
-    join (head ++ [tail]);
-
-}-
\ No newline at end of file
diff --git a/pkgs/writePythonScriptBin.nix b/pkgs/writePythonScriptBin.nix
@@ -1,20 +0,0 @@
-{ writeTextFile, stdenv, python3 }:
-
-{
-
-  writePythonScriptBin = name: packagesSelectionFun: text:
-    let
-      mkScriptName = s: (builtins.replaceStrings [ "\\" ] [ "-" ] s);
-      x = writeTextFile { name = "unit-script.py"; executable = true; destination = "/bin/${mkScriptName name}"; text = "#!/usr/bin/env python3\n${text}"; };
-      deriv = stdenv.mkDerivation {
-        name = mkScriptName name;
-        buildInputs = [ (python3.withPackages (pythonPackages: packagesSelectionFun pythonPackages)) ];
-        unpackPhase = "true";
-        installPhase = ''
-          mkdir -p $out/bin
-          cp ${x}/bin/${mkScriptName name} $out/bin/${mkScriptName name}
-        '';
-      };
-    in "${deriv}/bin/${mkScriptName name}";
-
-}