Commit 28f1bc67aea8

Vincent Demeester <vincent@sbr.pm>
2025-11-27 20:16:04
refactor(wakasu): fix system-manager compatibility system-manager-wakasu
- Disable overlays and NixOS-specific options to prevent infinite recursion - Simplify WireGuard setup to use private key file instead of full config - Enable successful build of wakasu system-manager configuration Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Vincent Demeester <vincent@sbr.pm>
imperative/wakasu/apply.sh
@@ -58,6 +58,7 @@ setup.nix() {
 
 	# Source Nix profile
 	if [ -f /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]; then
+		# shellcheck source=/dev/null
 		. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
 		log_info "Nix installed successfully! Please restart your shell or run: source /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh"
 	else
@@ -101,33 +102,22 @@ setup.wireguard() {
 	log_info "Install wireguard..."
 	sudo dnf install -y wireguard-tools
 
-	log_info "Setup wireguard configuration..."
+	log_info "Setup wireguard private key..."
 	if [ -z "${WG_PRIVATE_KEY:-}" ]; then
 		log_warn "WG_PRIVATE_KEY not set, skipping wireguard configuration"
 		log_warn "Set WG_PRIVATE_KEY environment variable and re-run to configure"
 		return 0
 	fi
 
-	sudo tee /etc/wireguard/wg0.conf <<EOF
-[Interface]
-PrivateKey = ${WG_PRIVATE_KEY}
-## Client IP
-Address = 10.100.0.90/24
+	# Create wireguard directory if it doesn't exist
+	sudo mkdir -p /etc/wireguard
 
-## if you have DNS server running
-# DNS = 192.168.11.1
+	# Write the private key to the expected location for the wireguard-client module
+	echo "${WG_PRIVATE_KEY}" | sudo tee /etc/wireguard/private.key > /dev/null
+	sudo chmod 600 /etc/wireguard/private.key
 
-[Peer]
-PublicKey = +H3fxErP9HoFUrPgU19ra9+GDLQw+VwvLWx3lMct7QI=
-
-## to pass internet trafic 0.0.0.0 but for peer connection only use 192.168.11.0/24, or you can also specify comma separated IPs
-AllowedIPs =  10.100.0.0/24
-
-Endpoint = 167.99.17.238:51820
-PersistentKeepalive = 25
-EOF
-
-	log_info "Wireguard configuration created at /etc/wireguard/wg0.conf"
+	log_info "Wireguard private key created at /etc/wireguard/private.key"
+	log_info "The rest of the WireGuard configuration is managed by system-manager"
 }
 
 setup.default_packages() {
@@ -146,8 +136,10 @@ setup.system_manager() {
 	fi
 
 	# Get the path to this script to locate the repository
-	local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-	local repo_root="$(cd "${script_dir}/../.." && pwd)"
+	local script_dir
+	script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+	local repo_root
+	repo_root="$(cd "${script_dir}/../.." && pwd)"
 
 	log_info "Repository root: ${repo_root}"
 
lib/default.nix
@@ -221,7 +221,9 @@
     inputs.system-manager.lib.makeSystemConfig {
       inherit extraSpecialArgs;
       modules = [
-        # self.nixosModules.wireguard-client
+        ../modules/system-manager-firewall-stub.nix
+        ../modules/system-manager-syncthing.nix
+        ../modules/system-manager-wireguard.nix
         # inputs.agenix.nixosModules.default
         homeInput.nixosModules.home-manager
         {
modules/system-manager-firewall-stub.nix
@@ -0,0 +1,27 @@
+# Stub module for networking.firewall on system-manager
+# Some nixpkgs modules try to configure firewall even when disabled
+# This provides the minimal interface they expect
+{ lib, ... }:
+{
+  options = {
+    networking.firewall = {
+      enable = lib.mkEnableOption "firewall" // {
+        default = false;
+      };
+      allowedTCPPorts = lib.mkOption {
+        type = lib.types.listOf lib.types.port;
+        default = [ ];
+      };
+      allowedUDPPorts = lib.mkOption {
+        type = lib.types.listOf lib.types.port;
+        default = [ ];
+      };
+      trustedInterfaces = lib.mkOption {
+        type = lib.types.listOf lib.types.str;
+        default = [ ];
+      };
+    };
+  };
+
+  # No config needed - this is just a stub to prevent errors
+}
modules/system-manager-syncthing.nix
@@ -0,0 +1,8 @@
+# Wrapper module to import nixpkgs syncthing module for system-manager
+# This avoids circular dependency by using inputs.nixpkgs instead of pkgs.path
+{ inputs, ... }:
+{
+  imports = [
+    "${inputs.nixpkgs}/nixos/modules/services/networking/syncthing.nix"
+  ];
+}
modules/system-manager-wireguard.nix
@@ -0,0 +1,100 @@
+# Wrapper module for WireGuard on system-manager
+# This imports the base wireguard module and provides a simpler interface
+# similar to wireguard-client.nix but compatible with system-manager
+{
+  config,
+  inputs,
+  lib,
+  pkgs,
+  ...
+}:
+let
+  inherit (lib)
+    mkEnableOption
+    mkIf
+    mkOption
+    types
+    ;
+  cfg = config.services.wireguard;
+in
+{
+  imports = [
+    "${inputs.nixpkgs}/nixos/modules/services/networking/wireguard.nix"
+  ];
+
+  options = {
+    services.wireguard = {
+      enable = mkEnableOption "Enable a wireguard client";
+      ips = mkOption {
+        type = with types; listOf str;
+        description = ''
+          The peer IPs
+        '';
+      };
+      allowedIPs = mkOption {
+        default = [ "10.100.0.0/24" ];
+        type = with types; listOf str;
+        description = ''
+          The peer (server) allowedIPs
+        '';
+      };
+      endpoint = mkOption {
+        type = with types; str;
+        description = ''
+          The endpoint IP to target
+        '';
+      };
+      endpointPort = mkOption {
+        default = 51820;
+        type = with types; int;
+        description = ''
+          The endpoint Port to target
+        '';
+      };
+      endpointPublicKey = mkOption {
+        type = with types; str;
+        description = ''
+          The peer (server) public key
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    assertions = [
+      {
+        assertion = cfg.endpoint != "";
+        message = "services.wireguard.endpoint must be set.";
+      }
+      {
+        assertion = cfg.endpointPublicKey != "";
+        message = "services.wireguard.endpointPublicKey must be set.";
+      }
+      {
+        assertion = cfg.ips != [ ];
+        message = "services.wireguard.ips must be set.";
+      }
+    ];
+
+    environment.systemPackages = [ pkgs.wireguard-tools ];
+
+    # Note: networking.firewall doesn't exist in system-manager, so we skip that
+    # networking.firewall.trustedInterfaces = [ "wg0" ];
+
+    networking.wireguard.enable = true;
+    networking.wireguard.interfaces = {
+      wg0 = {
+        inherit (cfg) ips;
+        privateKeyFile = "/etc/wireguard/private.key";
+        peers = [
+          {
+            publicKey = cfg.endpointPublicKey;
+            inherit (cfg) allowedIPs;
+            endpoint = "${cfg.endpoint}:${toString cfg.endpointPort}";
+            persistentKeepalive = 25;
+          }
+        ];
+      };
+    };
+  };
+}
systems/wakasu/system.nix
@@ -1,84 +1,51 @@
 {
-  config,
   globals,
   hostname,
-  lib,
   libx,
   pkgs,
   ...
 }:
 {
+  # The syncthing and wireguard modules are imported via mkSystemManager in lib/default.nix
+
   # Environment packages
   environment.systemPackages = with pkgs; [
     helix
     acpi
-    syncthing
-    wireguard-tools
   ];
 
-  # Syncthing service
-  systemd.services.syncthing = {
+  # Syncthing configuration using the nixpkgs module
+  services.syncthing = {
     enable = true;
-    description = "Syncthing - Open Source Continuous File Synchronization";
-    wants = [ "network-online.target" ];
-    after = [ "network-online.target" ];
-    wantedBy = [ "default.target" ];
+    user = "vincent";
+    group = "users";
+    dataDir = "/home/vincent/.local/share/syncthing";
+    configDir = "/home/vincent/.config/syncthing";
+    guiAddress = libx.syncthingGuiAddress globals.machines."${hostname}";
+    openDefaultPorts = false;
 
-    serviceConfig = {
-      Type = "simple";
-      Restart = "on-failure";
-      RestartSec = "10s";
-      ExecStart = "${pkgs.syncthing}/bin/syncthing serve --no-browser --gui-address=${
-        libx.syncthingGuiAddress globals.machines."${hostname}"
-      }";
-      # Run as the user
-      User = "vincent";
-      Group = "users";
-      # Security settings
-      PrivateTmp = true;
-      ProtectSystem = "strict";
-      ProtectHome = false; # Syncthing needs access to home
-      ReadWritePaths = [ "/home/vincent" ];
+    settings = {
+      options = {
+        urAccepted = -1; # Disable usage reporting
+      };
     };
   };
 
-  # Wireguard service
-  systemd.services.wireguard-wg0 = {
+  # WireGuard configuration using the custom wireguard wrapper module
+  services.wireguard = {
     enable = true;
-    description = "WireGuard Tunnel - wg0";
-    wants = [ "network-online.target" ];
-    after = [ "network-online.target" ];
-    wantedBy = [ "multi-user.target" ];
-
-    path = [ pkgs.wireguard-tools ];
-
-    serviceConfig = {
-      Type = "oneshot";
-      RemainAfterExit = true;
-    };
-
-    script = ''
-      # Check if private key exists
-      if [ ! -f /etc/wireguard/wg0.conf ]; then
-        echo "WireGuard configuration not found at /etc/wireguard/wg0.conf"
-        echo "Please run the wakasu apply.sh script to set up WireGuard"
-        exit 0
-      fi
-
-      # Bring up the WireGuard interface
-      ${pkgs.wireguard-tools}/bin/wg-quick up wg0 || true
-    '';
-
-    preStop = ''
-      ${pkgs.wireguard-tools}/bin/wg-quick down wg0 || true
-    '';
+    ips = [ "10.100.0.90/24" ];
+    allowedIPs = [ "10.100.0.0/24" ];
+    endpoint = "167.99.17.238";
+    endpointPort = 51820;
+    endpointPublicKey = "+H3fxErP9HoFUrPgU19ra9+GDLQw+VwvLWx3lMct7QI=";
   };
 
   # Configure /etc files
   environment.etc = {
     "syncthing-config-notice" = {
       text = ''
-        Syncthing is managed by system-manager.
+        Syncthing is managed by system-manager using the nixpkgs module.
         Configuration is stored in /home/vincent/.config/syncthing
 
         GUI Address: ${libx.syncthingGuiAddress globals.machines."${hostname}"}
systems/system-manager.nix
@@ -1,9 +1,5 @@
 {
-  config,
   hostname,
-  inputs,
-  lib,
-  outputs,
   ...
 }:
 {
@@ -14,24 +10,26 @@
   ];
 
   nixpkgs = {
-    overlays = [
-      # Our own flake exports (from overlays and pkgs dir)
-      outputs.overlays.additions
-      outputs.overlays.modifications
-      outputs.overlays.unstable-packages
-
-      # And from other flakes
-      inputs.emacs-overlay.overlay
-      inputs.chapeau-rouge.overlays.openshift
-      inputs.chick-group.overlays.default
-      inputs.agenix.overlays.default
-
-      # Migrate to "modifications"
-      (_: prev: {
-        inherit (inputs.buildkit-tekton.packages.${prev.system}) tkn-local;
-        inherit (inputs.dagger.packages.${prev.system}) dagger;
-      })
-    ];
+    # Note: Overlays cause infinite recursion in system-manager
+    # Disabling for now - packages will come from standard nixpkgs
+    # overlays = [
+    #   # Our own flake exports (from overlays and pkgs dir)
+    #   outputs.overlays.additions
+    #   outputs.overlays.modifications
+    #   outputs.overlays.unstable-packages
+    #
+    #   # And from other flakes
+    #   inputs.emacs-overlay.overlay
+    #   inputs.chapeau-rouge.overlays.openshift
+    #   inputs.chick-group.overlays.default
+    #   inputs.agenix.overlays.default
+    #
+    #   # Migrate to "modifications"
+    #   (_: prev: {
+    #     inherit (inputs.buildkit-tekton.packages.${prev.system}) tkn-local;
+    #     inherit (inputs.dagger.packages.${prev.system}) dagger;
+    #   })
+    # ];
     config = {
       allowUnfree = true;
     };
@@ -39,21 +37,23 @@
   nix = {
     # This will add each flake input as a registry
     # To make nix3 commands consistent with your flake
-    registry = lib.mkForce (lib.mapAttrs (_: value: { flake = value; }) inputs);
+    # Note: These options are not available in system-manager
+    # registry = lib.mkForce (lib.mapAttrs (_: value: { flake = value; }) inputs);
 
     # This will additionally add your inputs to the system's legacy channels
     # Making legacy nix commands consistent as well, awesome!
-    nixPath = lib.mkForce (
-      lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry
-    );
+    # nixPath = lib.mkForce (
+    #   lib.mapAttrsToList (key: value: "${key}=${value.to.path}") config.nix.registry
+    # );
 
-    optimise = {
-      automatic = true;
-      dates = [
-        "01:10"
-        "12:10"
-      ];
-    };
+    # Note: These options are not available in system-manager
+    # optimise = {
+    #   automatic = true;
+    #   dates = [
+    #     "01:10"
+    #     "12:10"
+    #   ];
+    # };
 
     settings = {
       auto-optimise-store = true;
@@ -99,7 +99,8 @@
 
     # On laptops at least, make the daemon and builders low priority
     # to have a responding system while building
-    daemonIOSchedClass = "idle";
-    daemonCPUSchedPolicy = "idle";
+    # Note: These options are not available in system-manager
+    # daemonIOSchedClass = "idle";
+    # daemonCPUSchedPolicy = "idle";
   };
 }