Files
2025-11-19 19:41:34 -08:00

133 lines
3.7 KiB
Nix

{ lib, config, pkgs, ... }:
with lib;
let
cfg = config.roles.remote-build;
in
{
options.roles.remote-build = {
enableBuilder = mkOption {
type = types.bool;
default = false;
description = "Enable this machine as a remote build host for other machines";
};
builderUser = mkOption {
type = types.str;
default = "nix-builder";
description = "User account for remote builders to connect as";
};
builders = mkOption {
type = types.listOf (types.submodule {
options = {
hostName = mkOption {
type = types.str;
description = "Hostname or IP address of the build machine";
};
systems = mkOption {
type = types.listOf types.str;
default = [ "x86_64-linux" ];
description = "Supported systems";
};
maxJobs = mkOption {
type = types.int;
default = 8;
description = "Maximum number of parallel build jobs";
};
speedFactor = mkOption {
type = types.int;
default = 2;
description = "Speed factor compared to local building (higher = prefer remote)";
};
supportedFeatures = mkOption {
type = types.listOf types.str;
default = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
description = "Supported build features";
};
sshUser = mkOption {
type = types.str;
default = "nix-builder";
description = "SSH user for connecting to the builder";
};
sshKey = mkOption {
type = types.nullOr types.path;
default = null;
description = "Path to SSH private key for authentication";
};
};
});
default = [];
description = "List of remote build machines to use";
};
fallbackToLocalBuild = mkOption {
type = types.bool;
default = true;
description = "Fallback to local building if remote builders are unavailable";
};
};
config = mkMerge [
# Builder host configuration
(mkIf cfg.enableBuilder {
# Create dedicated builder user
users.users.${cfg.builderUser} = {
isSystemUser = true;
group = cfg.builderUser;
description = "Nix remote build user";
home = "/var/lib/${cfg.builderUser}";
createHome = true;
shell = pkgs.bashInteractive;
openssh.authorizedKeys.keyFiles = []; # Will be populated by client machines
};
users.groups.${cfg.builderUser} = {};
# Ensure home directory has correct permissions
systemd.tmpfiles.rules = [
"d /var/lib/${cfg.builderUser} 0700 ${cfg.builderUser} ${cfg.builderUser} -"
];
# Allow builder user to perform builds
nix.settings.trusted-users = [ cfg.builderUser ];
# Allow remote builds
services.openssh.enable = true;
# Ensure nix-daemon is accessible
nix.settings.allowed-users = [ "*" ];
})
# Client configuration (machines using remote builders)
(mkIf (cfg.builders != []) {
nix.buildMachines = map (builder: {
hostName = builder.hostName;
systems = builder.systems;
maxJobs = builder.maxJobs;
speedFactor = builder.speedFactor;
supportedFeatures = builder.supportedFeatures;
sshUser = builder.sshUser;
sshKey = builder.sshKey;
}) cfg.builders;
nix.distributedBuilds = true;
# Use substitutes from remote builders
nix.extraOptions = ''
builders-use-substitutes = true
'';
# Fallback to local build if remote unavailable
nix.settings.fallback = cfg.fallbackToLocalBuild;
})
];
}