vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / config / nix-remote-build.nix
blobe8aa438a262d014009b53e5db7752ba9d2c3064a
1 /*
2   Manages the remote build configuration, /etc/nix/machines
4   See also
5    - ./nix.nix
6    - nixos/modules/services/system/nix-daemon.nix
7  */
8 { config, lib, ... }:
10 let
11   inherit (lib)
12     any
13     concatMapStrings
14     concatStringsSep
15     filter
16     getVersion
17     mkIf
18     mkMerge
19     mkOption
20     optional
21     optionalString
22     types
23     versionAtLeast
24     ;
26   cfg = config.nix;
28   nixPackage = cfg.package.out;
30   isNixAtLeast = versionAtLeast (getVersion nixPackage);
32   buildMachinesText =
33     concatMapStrings
34       (machine:
35         (concatStringsSep " " ([
36           "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
37           (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
38           (if machine.sshKey != null then machine.sshKey else "-")
39           (toString machine.maxJobs)
40           (toString machine.speedFactor)
41           (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures);
42             in if (res == []) then "-" else (concatStringsSep "," res))
43           (let res = machine.mandatoryFeatures;
44             in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures))
45         ]
46         ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
47         + "\n"
48       )
49       cfg.buildMachines;
53   options = {
54     nix = {
55       buildMachines = mkOption {
56         type = types.listOf (types.submodule {
57           options = {
58             hostName = mkOption {
59               type = types.str;
60               example = "nixbuilder.example.org";
61               description = ''
62                 The hostname of the build machine.
63               '';
64             };
65             protocol = mkOption {
66               type = types.enum [ null "ssh" "ssh-ng" ];
67               default = "ssh";
68               example = "ssh-ng";
69               description = ''
70                 The protocol used for communicating with the build machine.
71                 Use `ssh-ng` if your remote builder and your
72                 local Nix version support that improved protocol.
74                 Use `null` when trying to change the special localhost builder
75                 without a protocol which is for example used by hydra.
76               '';
77             };
78             system = mkOption {
79               type = types.nullOr types.str;
80               default = null;
81               example = "x86_64-linux";
82               description = ''
83                 The system type the build machine can execute derivations on.
84                 Either this attribute or {var}`systems` must be
85                 present, where {var}`system` takes precedence if
86                 both are set.
87               '';
88             };
89             systems = mkOption {
90               type = types.listOf types.str;
91               default = [ ];
92               example = [ "x86_64-linux" "aarch64-linux" ];
93               description = ''
94                 The system types the build machine can execute derivations on.
95                 Either this attribute or {var}`system` must be
96                 present, where {var}`system` takes precedence if
97                 both are set.
98               '';
99             };
100             sshUser = mkOption {
101               type = types.nullOr types.str;
102               default = null;
103               example = "builder";
104               description = ''
105                 The username to log in as on the remote host. This user must be
106                 able to log in and run nix commands non-interactively. It must
107                 also be privileged to build derivations, so must be included in
108                 {option}`nix.settings.trusted-users`.
109               '';
110             };
111             sshKey = mkOption {
112               type = types.nullOr types.str;
113               default = null;
114               example = "/root/.ssh/id_buildhost_builduser";
115               description = ''
116                 The path to the SSH private key with which to authenticate on
117                 the build machine. The private key must not have a passphrase.
118                 If null, the building user (root on NixOS machines) must have an
119                 appropriate ssh configuration to log in non-interactively.
121                 Note that for security reasons, this path must point to a file
122                 in the local filesystem, *not* to the nix store.
123               '';
124             };
125             maxJobs = mkOption {
126               type = types.int;
127               default = 1;
128               description = ''
129                 The number of concurrent jobs the build machine supports. The
130                 build machine will enforce its own limits, but this allows hydra
131                 to schedule better since there is no work-stealing between build
132                 machines.
133               '';
134             };
135             speedFactor = mkOption {
136               type = types.int;
137               default = 1;
138               description = ''
139                 The relative speed of this builder. This is an arbitrary integer
140                 that indicates the speed of this builder, relative to other
141                 builders. Higher is faster.
142               '';
143             };
144             mandatoryFeatures = mkOption {
145               type = types.listOf types.str;
146               default = [ ];
147               example = [ "big-parallel" ];
148               description = ''
149                 A list of features mandatory for this builder. The builder will
150                 be ignored for derivations that don't require all features in
151                 this list. All mandatory features are automatically included in
152                 {var}`supportedFeatures`.
153               '';
154             };
155             supportedFeatures = mkOption {
156               type = types.listOf types.str;
157               default = [ ];
158               example = [ "kvm" "big-parallel" ];
159               description = ''
160                 A list of features supported by this builder. The builder will
161                 be ignored for derivations that require features not in this
162                 list.
163               '';
164             };
165             publicHostKey = mkOption {
166               type = types.nullOr types.str;
167               default = null;
168               description = ''
169                 The (base64-encoded) public host key of this builder. The field
170                 is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`.
171                 If null, SSH will use its regular known-hosts file when connecting.
172               '';
173             };
174           };
175         });
176         default = [ ];
177         description = ''
178           This option lists the machines to be used if distributed builds are
179           enabled (see {option}`nix.distributedBuilds`).
180           Nix will perform derivations on those machines via SSH by copying the
181           inputs to the Nix store on the remote machine, starting the build,
182           then copying the output back to the local Nix store.
183         '';
184       };
186       distributedBuilds = mkOption {
187         type = types.bool;
188         default = false;
189         description = ''
190           Whether to distribute builds to the machines listed in
191           {option}`nix.buildMachines`.
192         '';
193       };
194     };
195   };
197   # distributedBuilds does *not* inhibit /etc/machines generation; caller may
198   # override that nix option.
199   config = mkIf cfg.enable {
200     assertions =
201       let badMachine = m: m.system == null && m.systems == [ ];
202       in
203       [
204         {
205           assertion = !(any badMachine cfg.buildMachines);
206           message = ''
207             At least one system type (via <varname>system</varname> or
208               <varname>systems</varname>) must be set for every build machine.
209               Invalid machine specifications:
210           '' + "      " +
211           (concatStringsSep "\n      "
212             (map (m: m.hostName)
213               (filter (badMachine) cfg.buildMachines)));
214         }
215       ];
217     # List of machines for distributed Nix builds
218     environment.etc."nix/machines" =
219       mkIf (cfg.buildMachines != [ ]) {
220         text = buildMachinesText;
221       };
223     # Legacy configuration conversion.
224     nix.settings = mkIf (!cfg.distributedBuilds) { builders = null; };
225   };