diff --git a/nixos/modules/config/nix-remote-build.nix b/nixos/modules/config/nix-remote-build.nix
new file mode 100644
index 00000000000..2a30bbdc746
--- /dev/null
+++ b/nixos/modules/config/nix-remote-build.nix
@@ -0,0 +1,219 @@
+{ config, lib, ... }:
+
+let
+ inherit (lib)
+ any
+ concatMapStrings
+ concatStringsSep
+ filter
+ getVersion
+ mkIf
+ mkMerge
+ mkOption
+ optional
+ optionalString
+ types
+ versionAtLeast
+ ;
+
+ cfg = config.nix;
+
+ nixPackage = cfg.package.out;
+
+ isNixAtLeast = versionAtLeast (getVersion nixPackage);
+
+ buildMachinesText =
+ concatMapStrings
+ (machine:
+ (concatStringsSep " " ([
+ "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
+ (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
+ (if machine.sshKey != null then machine.sshKey else "-")
+ (toString machine.maxJobs)
+ (toString machine.speedFactor)
+ (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures);
+ in if (res == []) then "-" else (concatStringsSep "," res))
+ (let res = machine.mandatoryFeatures;
+ in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures))
+ ]
+ ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
+ + "\n"
+ )
+ cfg.buildMachines;
+
+in
+{
+ options = {
+ nix = {
+ buildMachines = mkOption {
+ type = types.listOf (types.submodule {
+ options = {
+ hostName = mkOption {
+ type = types.str;
+ example = "nixbuilder.example.org";
+ description = lib.mdDoc ''
+ The hostname of the build machine.
+ '';
+ };
+ protocol = mkOption {
+ type = types.enum [ null "ssh" "ssh-ng" ];
+ default = "ssh";
+ example = "ssh-ng";
+ description = lib.mdDoc ''
+ The protocol used for communicating with the build machine.
+ Use `ssh-ng` if your remote builder and your
+ local Nix version support that improved protocol.
+
+ Use `null` when trying to change the special localhost builder
+ without a protocol which is for example used by hydra.
+ '';
+ };
+ system = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "x86_64-linux";
+ description = lib.mdDoc ''
+ The system type the build machine can execute derivations on.
+ Either this attribute or {var}`systems` must be
+ present, where {var}`system` takes precedence if
+ both are set.
+ '';
+ };
+ systems = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "x86_64-linux" "aarch64-linux" ];
+ description = lib.mdDoc ''
+ The system types the build machine can execute derivations on.
+ Either this attribute or {var}`system` must be
+ present, where {var}`system` takes precedence if
+ both are set.
+ '';
+ };
+ sshUser = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "builder";
+ description = lib.mdDoc ''
+ The username to log in as on the remote host. This user must be
+ able to log in and run nix commands non-interactively. It must
+ also be privileged to build derivations, so must be included in
+ {option}`nix.settings.trusted-users`.
+ '';
+ };
+ sshKey = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ example = "/root/.ssh/id_buildhost_builduser";
+ description = lib.mdDoc ''
+ The path to the SSH private key with which to authenticate on
+ the build machine. The private key must not have a passphrase.
+ If null, the building user (root on NixOS machines) must have an
+ appropriate ssh configuration to log in non-interactively.
+
+ Note that for security reasons, this path must point to a file
+ in the local filesystem, *not* to the nix store.
+ '';
+ };
+ maxJobs = mkOption {
+ type = types.int;
+ default = 1;
+ description = lib.mdDoc ''
+ The number of concurrent jobs the build machine supports. The
+ build machine will enforce its own limits, but this allows hydra
+ to schedule better since there is no work-stealing between build
+ machines.
+ '';
+ };
+ speedFactor = mkOption {
+ type = types.int;
+ default = 1;
+ description = lib.mdDoc ''
+ The relative speed of this builder. This is an arbitrary integer
+ that indicates the speed of this builder, relative to other
+ builders. Higher is faster.
+ '';
+ };
+ mandatoryFeatures = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "big-parallel" ];
+ description = lib.mdDoc ''
+ A list of features mandatory for this builder. The builder will
+ be ignored for derivations that don't require all features in
+ this list. All mandatory features are automatically included in
+ {var}`supportedFeatures`.
+ '';
+ };
+ supportedFeatures = mkOption {
+ type = types.listOf types.str;
+ default = [ ];
+ example = [ "kvm" "big-parallel" ];
+ description = lib.mdDoc ''
+ A list of features supported by this builder. The builder will
+ be ignored for derivations that require features not in this
+ list.
+ '';
+ };
+ publicHostKey = mkOption {
+ type = types.nullOr types.str;
+ default = null;
+ description = lib.mdDoc ''
+ The (base64-encoded) public host key of this builder. The field
+ is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`.
+ If null, SSH will use its regular known-hosts file when connecting.
+ '';
+ };
+ };
+ });
+ default = [ ];
+ description = lib.mdDoc ''
+ This option lists the machines to be used if distributed builds are
+ enabled (see {option}`nix.distributedBuilds`).
+ Nix will perform derivations on those machines via SSH by copying the
+ inputs to the Nix store on the remote machine, starting the build,
+ then copying the output back to the local Nix store.
+ '';
+ };
+
+ distributedBuilds = mkOption {
+ type = types.bool;
+ default = false;
+ description = lib.mdDoc ''
+ Whether to distribute builds to the machines listed in
+ {option}`nix.buildMachines`.
+ '';
+ };
+ };
+ };
+
+ # distributedBuilds does *not* inhibit /etc/machines generation; caller may
+ # override that nix option.
+ config = mkIf cfg.enable {
+ assertions =
+ let badMachine = m: m.system == null && m.systems == [ ];
+ in
+ [
+ {
+ assertion = !(any badMachine cfg.buildMachines);
+ message = ''
+ At least one system type (via system or
+ systems) must be set for every build machine.
+ Invalid machine specifications:
+ '' + " " +
+ (concatStringsSep "\n "
+ (map (m: m.hostName)
+ (filter (badMachine) cfg.buildMachines)));
+ }
+ ];
+
+ # List of machines for distributed Nix builds
+ environment.etc."nix/machines" =
+ mkIf (cfg.buildMachines != [ ]) {
+ text = buildMachinesText;
+ };
+
+ # Legacy configuration conversion.
+ nix.settings = mkIf (!cfg.distributedBuilds) { builders = null; };
+ };
+}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index b6e500442c6..f54e14c5879 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -17,6 +17,7 @@
./config/mysql.nix
./config/networking.nix
./config/nix.nix
+ ./config/nix-remote-build.nix
./config/no-x-libs.nix
./config/nsswitch.nix
./config/power-management.nix
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index e5afffab21d..4368cdd63eb 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -62,15 +62,6 @@ in
'';
};
- distributedBuilds = mkOption {
- type = types.bool;
- default = false;
- description = lib.mdDoc ''
- Whether to distribute builds to the machines listed in
- {option}`nix.buildMachines`.
- '';
- };
-
daemonCPUSchedPolicy = mkOption {
type = types.enum [ "other" "batch" "idle" ];
default = "other";
@@ -137,137 +128,6 @@ in
'';
};
- buildMachines = mkOption {
- type = types.listOf (types.submodule {
- options = {
- hostName = mkOption {
- type = types.str;
- example = "nixbuilder.example.org";
- description = lib.mdDoc ''
- The hostname of the build machine.
- '';
- };
- protocol = mkOption {
- type = types.enum [ null "ssh" "ssh-ng" ];
- default = "ssh";
- example = "ssh-ng";
- description = lib.mdDoc ''
- The protocol used for communicating with the build machine.
- Use `ssh-ng` if your remote builder and your
- local Nix version support that improved protocol.
-
- Use `null` when trying to change the special localhost builder
- without a protocol which is for example used by hydra.
- '';
- };
- system = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "x86_64-linux";
- description = lib.mdDoc ''
- The system type the build machine can execute derivations on.
- Either this attribute or {var}`systems` must be
- present, where {var}`system` takes precedence if
- both are set.
- '';
- };
- systems = mkOption {
- type = types.listOf types.str;
- default = [ ];
- example = [ "x86_64-linux" "aarch64-linux" ];
- description = lib.mdDoc ''
- The system types the build machine can execute derivations on.
- Either this attribute or {var}`system` must be
- present, where {var}`system` takes precedence if
- both are set.
- '';
- };
- sshUser = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "builder";
- description = lib.mdDoc ''
- The username to log in as on the remote host. This user must be
- able to log in and run nix commands non-interactively. It must
- also be privileged to build derivations, so must be included in
- {option}`nix.settings.trusted-users`.
- '';
- };
- sshKey = mkOption {
- type = types.nullOr types.str;
- default = null;
- example = "/root/.ssh/id_buildhost_builduser";
- description = lib.mdDoc ''
- The path to the SSH private key with which to authenticate on
- the build machine. The private key must not have a passphrase.
- If null, the building user (root on NixOS machines) must have an
- appropriate ssh configuration to log in non-interactively.
-
- Note that for security reasons, this path must point to a file
- in the local filesystem, *not* to the nix store.
- '';
- };
- maxJobs = mkOption {
- type = types.int;
- default = 1;
- description = lib.mdDoc ''
- The number of concurrent jobs the build machine supports. The
- build machine will enforce its own limits, but this allows hydra
- to schedule better since there is no work-stealing between build
- machines.
- '';
- };
- speedFactor = mkOption {
- type = types.int;
- default = 1;
- description = lib.mdDoc ''
- The relative speed of this builder. This is an arbitrary integer
- that indicates the speed of this builder, relative to other
- builders. Higher is faster.
- '';
- };
- mandatoryFeatures = mkOption {
- type = types.listOf types.str;
- default = [ ];
- example = [ "big-parallel" ];
- description = lib.mdDoc ''
- A list of features mandatory for this builder. The builder will
- be ignored for derivations that don't require all features in
- this list. All mandatory features are automatically included in
- {var}`supportedFeatures`.
- '';
- };
- supportedFeatures = mkOption {
- type = types.listOf types.str;
- default = [ ];
- example = [ "kvm" "big-parallel" ];
- description = lib.mdDoc ''
- A list of features supported by this builder. The builder will
- be ignored for derivations that require features not in this
- list.
- '';
- };
- publicHostKey = mkOption {
- type = types.nullOr types.str;
- default = null;
- description = lib.mdDoc ''
- The (base64-encoded) public host key of this builder. The field
- is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`.
- If null, SSH will use its regular known-hosts file when connecting.
- '';
- };
- };
- });
- default = [ ];
- description = lib.mdDoc ''
- This option lists the machines to be used if distributed builds are
- enabled (see {option}`nix.distributedBuilds`).
- Nix will perform derivations on those machines via SSH by copying the
- inputs to the Nix store on the remote machine, starting the build,
- then copying the output back to the local Nix store.
- '';
- };
-
# Environment variables for running Nix.
envVars = mkOption {
type = types.attrs;
@@ -379,46 +239,6 @@ in
flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
};
- # List of machines for distributed Nix builds in the format
- # expected by build-remote.pl.
- environment.etc."nix/machines" = mkIf (cfg.buildMachines != [ ]) {
- text =
- concatMapStrings
- (machine:
- (concatStringsSep " " ([
- "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
- (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
- (if machine.sshKey != null then machine.sshKey else "-")
- (toString machine.maxJobs)
- (toString machine.speedFactor)
- (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures);
- in if (res == []) then "-" else (concatStringsSep "," res))
- (let res = machine.mandatoryFeatures;
- in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures))
- ]
- ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
- + "\n"
- )
- cfg.buildMachines;
- };
-
- assertions =
- let badMachine = m: m.system == null && m.systems == [ ];
- in
- [
- {
- assertion = !(any badMachine cfg.buildMachines);
- message = ''
- At least one system type (via system or
- systems) must be set for every build machine.
- Invalid machine specifications:
- '' + " " +
- (concatStringsSep "\n "
- (map (m: m.hostName)
- (filter (badMachine) cfg.buildMachines)));
- }
- ];
-
systemd.packages = [ nixPackage ];
# Will only work once https://github.com/NixOS/nix/pull/6285 is merged
@@ -518,8 +338,6 @@ in
# Legacy configuration conversion.
nix.settings = mkMerge [
- (mkIf (!cfg.distributedBuilds) { builders = null; })
-
(mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
];