diff options
author | Robert Hensing <robert@roberthensing.nl> | 2023-07-05 13:38:30 +0200 |
---|---|---|
committer | Robert Hensing <robert@roberthensing.nl> | 2023-07-05 14:54:27 +0200 |
commit | d6a68f05428c3ed7d76565917e9baca68c610164 (patch) | |
tree | 99ff3160d3cd61d71130b5bd8667876b3abf49c9 /nixos/modules/config/nix-remote-build.nix | |
parent | 4bbd44908c5d4d271daf91d71325ec5b6b2cf0c5 (diff) | |
download | nixpkgs-d6a68f05428c3ed7d76565917e9baca68c610164.tar nixpkgs-d6a68f05428c3ed7d76565917e9baca68c610164.tar.gz nixpkgs-d6a68f05428c3ed7d76565917e9baca68c610164.tar.bz2 nixpkgs-d6a68f05428c3ed7d76565917e9baca68c610164.tar.lz nixpkgs-d6a68f05428c3ed7d76565917e9baca68c610164.tar.xz nixpkgs-d6a68f05428c3ed7d76565917e9baca68c610164.tar.zst nixpkgs-d6a68f05428c3ed7d76565917e9baca68c610164.zip |
nixos/config/nix-remote-build: Factor out
Diffstat (limited to 'nixos/modules/config/nix-remote-build.nix')
-rw-r--r-- | nixos/modules/config/nix-remote-build.nix | 219 |
1 files changed, 219 insertions, 0 deletions
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 <varname>system</varname> or + <varname>systems</varname>) 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; }; + }; +} |