From da691f0b4ddb87795f786e68e6bc836d8e08c870 Mon Sep 17 00:00:00 2001 From: Hermes Date: Thu, 18 Jun 2026 17:17:03 -0400 Subject: [PATCH] feat: add agenix-rekey + remote-builder module for distributed builds --- flake.nix | 20 ++++--- modules/nixos/services/remote-builder.nix | 64 +++++++++++++++++++++++ 2 files changed, 78 insertions(+), 6 deletions(-) create mode 100644 modules/nixos/services/remote-builder.nix diff --git a/flake.nix b/flake.nix index 13edf25..712ab36 100644 --- a/flake.nix +++ b/flake.nix @@ -8,6 +8,10 @@ inputs.darwin.follows = ""; inputs.nixpkgs.follows = "nixpkgs"; }; + agenix-rekey = { + url = "github:oddlama/agenix-rekey"; + inputs.nixpkgs.follows = "nixpkgs"; + }; lix = { url = "git+https://git.lix.systems/lix-project/lix?ref=main"; inputs.nixpkgs.follows = "nixpkgs"; @@ -28,7 +32,7 @@ }; }; - outputs = { self, nixpkgs, agenix, lix + outputs = { self, nixpkgs, agenix, agenix-rekey, lix , nixpkgs-uconsole, nixos-uconsole, nixos-raspberrypi , home-manager , ... }@inputs: @@ -69,7 +73,6 @@ mesonFlags = (old.mesonFlags or []) ++ [ "-Dskip_gtk_tests=true" ]; }); hyprland = prev.hyprland.override { wrapRuntimeDeps = false; }; - # Boost MPI cannot cross-compile for aarch64 (no b2 alternatives) boost = prev.boost.override { useMpi = false; }; xdg-desktop-portal-hyprland = prev.xdg-desktop-portal-hyprland.overrideAttrs (old: { preConfigure = (old.preConfigure or "") + '' @@ -79,7 +82,6 @@ }); }; - # RPI-specific pipewire libcamera fix (separate nixpkgs instance) uconsoleRpiPipewireOverlay = final: prev: { pipewire = prev.pipewire.overrideAttrs (old: { buildInputs = builtins.filter @@ -91,7 +93,6 @@ }); }; - # Shared uConsole CM5 module set — used by both toplevel and SD image uconsoleBaseModules = [ { nixpkgs.buildPlatform = "x86_64-linux"; @@ -109,7 +110,6 @@ nixos-raspberrypi.lib.inject-overlays-global nixos-uconsole.nixosModules.uconsole-cm5 ./modules/nixos/hardware/uconsole-cm5-aio-v2.nix - # Cross-compiled Lix for uConsole ({ config, lib, pkgs, inputs, ... }: let lixCross = import inputs.nixpkgs-uconsole { localSystem = { system = "x86_64-linux"; }; @@ -119,8 +119,10 @@ in { nix.package = lixCross.lix; }) inputs.home-manager.nixosModules.home-manager agenix.nixosModules.default + agenix-rekey.nixosModules.default ./hosts/uconsole-cm5/configuration.nix ./hosts/uconsole-cm5/hardware-configuration.nix + ./modules/nixos/services/remote-builder.nix ./modules/nixos/services/wireguard-client.nix ./modules/nixos/security/ai-worker-restricted.nix ./users/gortium/gortium.nix @@ -138,7 +140,7 @@ nixpkgs.config.permittedInsecurePackages = [ "openclaw-2026.3.12" ]; nix.package = lix.packages.${system}.default; } - inputs.home-manager.nixosModules.home-manager + inputs.home-manager.nixosModules.home-manager agenix.nixosModules.default ./hosts/lazyworkhorse/configuration.nix ./hosts/lazyworkhorse/hardware-configuration.nix @@ -164,6 +166,7 @@ } ./hosts/cyt-pi/configuration.nix ./hosts/cyt-pi/hardware-configuration.nix + ./modules/nixos/services/remote-builder.nix ./modules/nixos/services/wireguard-client.nix ./users/gortium/gortium.nix ]; @@ -180,6 +183,11 @@ }; }; + agenix-rekey = agenix-rekey.configure { + userFlake = self; + nixosConfigurations = self.nixosConfigurations; + }; + devShells.${system}.default = devShell; packages.${system} = { diff --git a/modules/nixos/services/remote-builder.nix b/modules/nixos/services/remote-builder.nix new file mode 100644 index 0000000..34fe5fc --- /dev/null +++ b/modules/nixos/services/remote-builder.nix @@ -0,0 +1,64 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.remoteBuilder; +in { + options.services.remoteBuilder = { + enable = lib.mkEnableOption "remote Nix build machine (lazyworkhorse server)"; + + buildMachine = { + host = lib.mkOption { + type = lib.types.str; + default = "lazyworkhorse.net"; + description = "Hostname or IP of the remote build machine."; + }; + sshUser = lib.mkOption { + type = lib.types.str; + default = "ai-worker"; + description = "SSH user on the remote build machine."; + }; + port = lib.mkOption { + type = lib.types.port; + default = 2424; + description = "SSH port on the remote build machine."; + }; + systems = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ "aarch64-linux" "x86_64-linux" ]; + description = "System types the remote builder can build for."; + }; + maxJobs = lib.mkOption { + type = lib.types.int; + default = 16; + description = "Max parallel jobs on the remote builder."; + }; + supportedFeatures = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ "big-parallel" "nixos-test" "benchmark" ]; + description = "Features the remote builder supports."; + }; + }; + + fallbackLocal = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Fall back to local build when remote builder is unreachable."; + }; + }; + + config = lib.mkIf cfg.enable { + nix.distributedBuilds = true; + nix.buildMachines = [{ + hostName = cfg.buildMachine.host; + sshUser = cfg.buildMachine.sshUser; + sshPort = cfg.buildMachine.port; + systems = cfg.buildMachine.systems; + maxJobs = cfg.buildMachine.maxJobs; + supportedFeatures = cfg.buildMachine.supportedFeatures; + }]; + + nix.extraOptions = lib.optionalString cfg.fallbackLocal '' + builders-use-substitutes = true + fallback = true + ''; + }; +}