···1-# darwin.builder {#sec-darwin-builder}
23-`darwin.builder` provides a way to bootstrap a Linux builder on a macOS machine.
45This requires macOS version 12.4 or later.
67-This also requires that port 22 on your machine is free (since Nix does not
8-permit specifying a non-default SSH port for builders).
0910You will also need to be a trusted user for your Nix installation. In other
11words, your `/etc/nix/nix.conf` should have something like:
···17To launch the builder, run the following flake:
1819```ShellSession
20-$ nix run nixpkgs#darwin.builder
21```
2223That will prompt you to enter your `sudo` password:
···50```
51# - Replace ${ARCH} with either aarch64 or x86_64 to match your host machine
52# - Replace ${MAX_JOBS} with the maximum number of builds (pick 4 if you're not sure)
53-builders = ssh-ng://builder@localhost ${ARCH}-linux /etc/nix/builder_ed25519 ${MAX_JOBS} - - - c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUpCV2N4Yi9CbGFxdDFhdU90RStGOFFVV3JVb3RpQzVxQkorVXVFV2RWQ2Igcm9vdEBuaXhvcwo=
5455# Not strictly necessary, but this will reduce your disk utilization
56builders-use-substitutes = true
00000000057```
5859… and then restart your Nix daemon to apply the change:
···1+# darwin.linux-builder {#sec-darwin-builder}
23+`darwin.linux-builder` provides a way to bootstrap a Linux builder on a macOS machine.
45This requires macOS version 12.4 or later.
67+The builder runs on host port 31022 by default.
8+You can change it by overriding `virtualisation.darwin-builder.hostPort`.
9+See the [example](#sec-darwin-builder-example-flake).
1011You will also need to be a trusted user for your Nix installation. In other
12words, your `/etc/nix/nix.conf` should have something like:
···18To launch the builder, run the following flake:
1920```ShellSession
21+$ nix run nixpkgs#darwin.linux-builder
22```
2324That will prompt you to enter your `sudo` password:
···51```
52# - Replace ${ARCH} with either aarch64 or x86_64 to match your host machine
53# - Replace ${MAX_JOBS} with the maximum number of builds (pick 4 if you're not sure)
54+builders = ssh-ng://builder@linux-builder ${ARCH}-linux /etc/nix/builder_ed25519 ${MAX_JOBS} - - - c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUpCV2N4Yi9CbGFxdDFhdU90RStGOFFVV3JVb3RpQzVxQkorVXVFV2RWQ2Igcm9vdEBuaXhvcwo=
5556# Not strictly necessary, but this will reduce your disk utilization
57builders-use-substitutes = true
58+```
59+60+To allow Nix to connect to a builder not running on port 22, you will also need to create a new file at `/etc/ssh/ssh_config.d/100-linux-builder.conf`:
61+62+```
63+Host linux-builder
64+ Hostname localhost
65+ HostKeyAlias linux-builder
66+ Port 31022
67```
6869… and then restart your Nix daemon to apply the change:
···1+/*
2+ Manages the remote build configuration, /etc/nix/machines
3+4+ See also
5+ - ./nix.nix
6+ - nixos/modules/services/system/nix-daemon.nix
7+ */
8+{ config, lib, ... }:
9+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+ ;
25+26+ cfg = config.nix;
27+28+ nixPackage = cfg.package.out;
29+30+ isNixAtLeast = versionAtLeast (getVersion nixPackage);
31+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;
50+51+in
52+{
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 = lib.mdDoc ''
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 = lib.mdDoc ''
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.
73+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 = lib.mdDoc ''
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 = lib.mdDoc ''
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 = lib.mdDoc ''
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 = lib.mdDoc ''
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.
120+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 = lib.mdDoc ''
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 = lib.mdDoc ''
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 = lib.mdDoc ''
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 = lib.mdDoc ''
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 = lib.mdDoc ''
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 = lib.mdDoc ''
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+ };
185+186+ distributedBuilds = mkOption {
187+ type = types.bool;
188+ default = false;
189+ description = lib.mdDoc ''
190+ Whether to distribute builds to the machines listed in
191+ {option}`nix.buildMachines`.
192+ '';
193+ };
194+ };
195+ };
196+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+ ];
216+217+ # List of machines for distributed Nix builds
218+ environment.etc."nix/machines" =
219+ mkIf (cfg.buildMachines != [ ]) {
220+ text = buildMachinesText;
221+ };
222+223+ # Legacy configuration conversion.
224+ nix.settings = mkIf (!cfg.distributedBuilds) { builders = null; };
225+ };
226+}
···1+/*
2+ Manages /etc/nix.conf.
3+4+ See also
5+ - ./nix-channel.nix
6+ - ./nix-flakes.nix
7+ - ./nix-remote-build.nix
8+ - nixos/modules/services/system/nix-daemon.nix
9+ */
10+{ config, lib, pkgs, ... }:
11+12+let
13+ inherit (lib)
14+ concatStringsSep
15+ boolToString
16+ escape
17+ floatToString
18+ getVersion
19+ isBool
20+ isDerivation
21+ isFloat
22+ isInt
23+ isList
24+ isString
25+ literalExpression
26+ mapAttrsToList
27+ mkAfter
28+ mkDefault
29+ mkIf
30+ mkOption
31+ mkRenamedOptionModuleWith
32+ optionalString
33+ optionals
34+ strings
35+ systems
36+ toPretty
37+ types
38+ versionAtLeast
39+ ;
40+41+ cfg = config.nix;
42+43+ nixPackage = cfg.package.out;
44+45+ isNixAtLeast = versionAtLeast (getVersion nixPackage);
46+47+ legacyConfMappings = {
48+ useSandbox = "sandbox";
49+ buildCores = "cores";
50+ maxJobs = "max-jobs";
51+ sandboxPaths = "extra-sandbox-paths";
52+ binaryCaches = "substituters";
53+ trustedBinaryCaches = "trusted-substituters";
54+ binaryCachePublicKeys = "trusted-public-keys";
55+ autoOptimiseStore = "auto-optimise-store";
56+ requireSignedBinaryCaches = "require-sigs";
57+ trustedUsers = "trusted-users";
58+ allowedUsers = "allowed-users";
59+ systemFeatures = "system-features";
60+ };
61+62+ semanticConfType = with types;
63+ let
64+ confAtom = nullOr
65+ (oneOf [
66+ bool
67+ int
68+ float
69+ str
70+ path
71+ package
72+ ]) // {
73+ description = "Nix config atom (null, bool, int, float, str, path or package)";
74+ };
75+ in
76+ attrsOf (either confAtom (listOf confAtom));
77+78+ nixConf =
79+ assert isNixAtLeast "2.2";
80+ let
81+82+ mkValueString = v:
83+ if v == null then ""
84+ else if isInt v then toString v
85+ else if isBool v then boolToString v
86+ else if isFloat v then floatToString v
87+ else if isList v then toString v
88+ else if isDerivation v then toString v
89+ else if builtins.isPath v then toString v
90+ else if isString v then v
91+ else if strings.isConvertibleWithToString v then toString v
92+ else abort "The nix conf value: ${toPretty {} v} can not be encoded";
93+94+ mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
95+96+ mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
97+98+ in
99+ pkgs.writeTextFile {
100+ name = "nix.conf";
101+ text = ''
102+ # WARNING: this file is generated from the nix.* options in
103+ # your NixOS configuration, typically
104+ # /etc/nixos/configuration.nix. Do not edit it!
105+ ${mkKeyValuePairs cfg.settings}
106+ ${cfg.extraOptions}
107+ '';
108+ checkPhase = lib.optionalString cfg.checkConfig (
109+ if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
110+ echo "Ignoring validation for cross-compilation"
111+ ''
112+ else ''
113+ echo "Validating generated nix.conf"
114+ ln -s $out ./nix.conf
115+ set -e
116+ set +o pipefail
117+ NIX_CONF_DIR=$PWD \
118+ ${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
119+ ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
120+ |& sed -e 's/^warning:/error:/' \
121+ | (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
122+ set -o pipefail
123+ '');
124+ };
125+126+in
127+{
128+ imports = [
129+ (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; })
130+ (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; })
131+ ] ++
132+ mapAttrsToList
133+ (oldConf: newConf:
134+ mkRenamedOptionModuleWith {
135+ sinceRelease = 2205;
136+ from = [ "nix" oldConf ];
137+ to = [ "nix" "settings" newConf ];
138+ })
139+ legacyConfMappings;
140+141+ options = {
142+ nix = {
143+ checkConfig = mkOption {
144+ type = types.bool;
145+ default = true;
146+ description = lib.mdDoc ''
147+ If enabled, checks that Nix can parse the generated nix.conf.
148+ '';
149+ };
150+151+ checkAllErrors = mkOption {
152+ type = types.bool;
153+ default = true;
154+ description = lib.mdDoc ''
155+ If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings.
156+ '';
157+ };
158+159+ extraOptions = mkOption {
160+ type = types.lines;
161+ default = "";
162+ example = ''
163+ keep-outputs = true
164+ keep-derivations = true
165+ '';
166+ description = lib.mdDoc "Additional text appended to {file}`nix.conf`.";
167+ };
168+169+ settings = mkOption {
170+ type = types.submodule {
171+ freeformType = semanticConfType;
172+173+ options = {
174+ max-jobs = mkOption {
175+ type = types.either types.int (types.enum [ "auto" ]);
176+ default = "auto";
177+ example = 64;
178+ description = lib.mdDoc ''
179+ This option defines the maximum number of jobs that Nix will try to
180+ build in parallel. The default is auto, which means it will use all
181+ available logical cores. It is recommend to set it to the total
182+ number of logical cores in your system (e.g., 16 for two CPUs with 4
183+ cores each and hyper-threading).
184+ '';
185+ };
186+187+ auto-optimise-store = mkOption {
188+ type = types.bool;
189+ default = false;
190+ example = true;
191+ description = lib.mdDoc ''
192+ If set to true, Nix automatically detects files in the store that have
193+ identical contents, and replaces them with hard links to a single copy.
194+ This saves disk space. If set to false (the default), you can still run
195+ nix-store --optimise to get rid of duplicate files.
196+ '';
197+ };
198+199+ cores = mkOption {
200+ type = types.int;
201+ default = 0;
202+ example = 64;
203+ description = lib.mdDoc ''
204+ This option defines the maximum number of concurrent tasks during
205+ one build. It affects, e.g., -j option for make.
206+ The special value 0 means that the builder should use all
207+ available CPU cores in the system. Some builds may become
208+ non-deterministic with this option; use with care! Packages will
209+ only be affected if enableParallelBuilding is set for them.
210+ '';
211+ };
212+213+ sandbox = mkOption {
214+ type = types.either types.bool (types.enum [ "relaxed" ]);
215+ default = true;
216+ description = lib.mdDoc ''
217+ If set, Nix will perform builds in a sandboxed environment that it
218+ will set up automatically for each build. This prevents impurities
219+ in builds by disallowing access to dependencies outside of the Nix
220+ store by using network and mount namespaces in a chroot environment.
221+222+ This is enabled by default even though it has a possible performance
223+ impact due to the initial setup time of a sandbox for each build. It
224+ doesn't affect derivation hashes, so changing this option will not
225+ trigger a rebuild of packages.
226+227+ When set to "relaxed", this option permits derivations that set
228+ `__noChroot = true;` to run outside of the sandboxed environment.
229+ Exercise caution when using this mode of operation! It is intended to
230+ be a quick hack when building with packages that are not easily setup
231+ to be built reproducibly.
232+ '';
233+ };
234+235+ extra-sandbox-paths = mkOption {
236+ type = types.listOf types.str;
237+ default = [ ];
238+ example = [ "/dev" "/proc" ];
239+ description = lib.mdDoc ''
240+ Directories from the host filesystem to be included
241+ in the sandbox.
242+ '';
243+ };
244+245+ substituters = mkOption {
246+ type = types.listOf types.str;
247+ description = lib.mdDoc ''
248+ List of binary cache URLs used to obtain pre-built binaries
249+ of Nix packages.
250+251+ By default https://cache.nixos.org/ is added.
252+ '';
253+ };
254+255+ trusted-substituters = mkOption {
256+ type = types.listOf types.str;
257+ default = [ ];
258+ example = [ "https://hydra.nixos.org/" ];
259+ description = lib.mdDoc ''
260+ List of binary cache URLs that non-root users can use (in
261+ addition to those specified using
262+ {option}`nix.settings.substituters`) by passing
263+ `--option binary-caches` to Nix commands.
264+ '';
265+ };
266+267+ require-sigs = mkOption {
268+ type = types.bool;
269+ default = true;
270+ description = lib.mdDoc ''
271+ If enabled (the default), Nix will only download binaries from binary caches if
272+ they are cryptographically signed with any of the keys listed in
273+ {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither
274+ required nor checked, so it's strongly recommended that you use only
275+ trustworthy caches and https to prevent man-in-the-middle attacks.
276+ '';
277+ };
278+279+ trusted-public-keys = mkOption {
280+ type = types.listOf types.str;
281+ example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
282+ description = lib.mdDoc ''
283+ List of public keys used to sign binary caches. If
284+ {option}`nix.settings.trusted-public-keys` is enabled,
285+ then Nix will use a binary from a binary cache if and only
286+ if it is signed by *any* of the keys
287+ listed here. By default, only the key for
288+ `cache.nixos.org` is included.
289+ '';
290+ };
291+292+ trusted-users = mkOption {
293+ type = types.listOf types.str;
294+ default = [ "root" ];
295+ example = [ "root" "alice" "@wheel" ];
296+ description = lib.mdDoc ''
297+ A list of names of users that have additional rights when
298+ connecting to the Nix daemon, such as the ability to specify
299+ additional binary caches, or to import unsigned NARs. You
300+ can also specify groups by prefixing them with
301+ `@`; for instance,
302+ `@wheel` means all users in the wheel
303+ group.
304+ '';
305+ };
306+307+ system-features = mkOption {
308+ type = types.listOf types.str;
309+ example = [ "kvm" "big-parallel" "gccarch-skylake" ];
310+ description = lib.mdDoc ''
311+ The set of features supported by the machine. Derivations
312+ can express dependencies on system features through the
313+ `requiredSystemFeatures` attribute.
314+315+ By default, pseudo-features `nixos-test`, `benchmark`,
316+ and `big-parallel` used in Nixpkgs are set, `kvm`
317+ is also included if it is available.
318+ '';
319+ };
320+321+ allowed-users = mkOption {
322+ type = types.listOf types.str;
323+ default = [ "*" ];
324+ example = [ "@wheel" "@builders" "alice" "bob" ];
325+ description = lib.mdDoc ''
326+ A list of names of users (separated by whitespace) that are
327+ allowed to connect to the Nix daemon. As with
328+ {option}`nix.settings.trusted-users`, you can specify groups by
329+ prefixing them with `@`. Also, you can
330+ allow all users by specifying `*`. The
331+ default is `*`. Note that trusted users are
332+ always allowed to connect.
333+ '';
334+ };
335+ };
336+ };
337+ default = { };
338+ example = literalExpression ''
339+ {
340+ use-sandbox = true;
341+ show-trace = true;
342+343+ system-features = [ "big-parallel" "kvm" "recursive-nix" ];
344+ sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; };
345+ }
346+ '';
347+ description = lib.mdDoc ''
348+ Configuration for Nix, see
349+ <https://nixos.org/manual/nix/stable/command-ref/conf-file.html> or
350+ {manpage}`nix.conf(5)` for available options.
351+ The value declared here will be translated directly to the key-value pairs Nix expects.
352+353+ You can use {command}`nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings`
354+ to view the current value. By default it is empty.
355+356+ Nix configurations defined under {option}`nix.*` will be translated and applied to this
357+ option. In addition, configuration specified in {option}`nix.extraOptions` will be appended
358+ verbatim to the resulting config file.
359+ '';
360+ };
361+ };
362+ };
363+364+ config = mkIf cfg.enable {
365+ environment.etc."nix/nix.conf".source = nixConf;
366+ nix.settings = {
367+ trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
368+ substituters = mkAfter [ "https://cache.nixos.org/" ];
369+ system-features = mkDefault (
370+ [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
371+ optionals (pkgs.stdenv.hostPlatform ? gcc.arch) (
372+ # a builder can run code for `gcc.arch` and inferior architectures
373+ [ "gccarch-${pkgs.stdenv.hostPlatform.gcc.arch}" ] ++
374+ map (x: "gccarch-${x}") (systems.architectures.inferiors.${pkgs.stdenv.hostPlatform.gcc.arch} or [])
375+ )
376+ );
377+ };
378+ };
379+}
-7
nixos/modules/misc/version.nix
···140 '';
141 };
142143- defaultChannel = mkOption {
144- internal = true;
145- type = types.str;
146- default = "https://nixos.org/channels/nixos-unstable";
147- description = lib.mdDoc "Default NixOS channel to which the root user is subscribed.";
148- };
149-150 configurationRevision = mkOption {
151 type = types.nullOr types.str;
152 default = null;
···1-{ config, lib, pkgs, ... }:
23let
4 keysDirectory = "/var/keys";
···67 '';
68 };
69 hostPort = mkOption {
70- default = 22;
71 type = types.int;
72- example = 31022;
73 description = ''
74 The localhost host port to forward TCP to the guest port.
75 '';
···139140 hostPkgs = config.virtualisation.host.pkgs;
141142- script = hostPkgs.writeShellScriptBin "create-builder" (
143 # When running as non-interactively as part of a DarwinConfiguration the working directory
144 # must be set to a writeable directory.
145 (if cfg.workingDirectory != "." then ''
146 ${hostPkgs.coreutils}/bin/mkdir --parent "${cfg.workingDirectory}"
147 cd "${cfg.workingDirectory}"
148- '' else "") + ''
149 KEYS="''${KEYS:-./keys}"
150 ${hostPkgs.coreutils}/bin/mkdir --parent "''${KEYS}"
151 PRIVATE_KEY="''${KEYS}/${user}_${keyType}"
···157 if ! ${hostPkgs.diffutils}/bin/cmp "''${PUBLIC_KEY}" ${publicKey}; then
158 (set -x; sudo --reset-timestamp ${installCredentials} "''${KEYS}")
159 fi
160- KEYS="$(${hostPkgs.nix}/bin/nix-store --add "$KEYS")" ${config.system.build.vm}/bin/run-nixos-vm
161 '');
162163 in
···177 Please inspect the trace of the following command to figure out which module
178 has a dependency on stateVersion.
179180- nix-instantiate --attr darwin.builder --show-trace
181 '');
182 };
183···234 # This ensures that anything built on the guest isn't lost when the guest is
235 # restarted.
236 writableStoreUseTmpfs = false;
0000237 };
238 };
239}
···1+{ config, lib, ... }:
23let
4 keysDirectory = "/var/keys";
···67 '';
68 };
69 hostPort = mkOption {
70+ default = 31022;
71 type = types.int;
72+ example = 22;
73 description = ''
74 The localhost host port to forward TCP to the guest port.
75 '';
···139140 hostPkgs = config.virtualisation.host.pkgs;
141142+ script = hostPkgs.writeShellScriptBin "create-builder" (
143 # When running as non-interactively as part of a DarwinConfiguration the working directory
144 # must be set to a writeable directory.
145 (if cfg.workingDirectory != "." then ''
146 ${hostPkgs.coreutils}/bin/mkdir --parent "${cfg.workingDirectory}"
147 cd "${cfg.workingDirectory}"
148+ '' else "") + ''
149 KEYS="''${KEYS:-./keys}"
150 ${hostPkgs.coreutils}/bin/mkdir --parent "''${KEYS}"
151 PRIVATE_KEY="''${KEYS}/${user}_${keyType}"
···157 if ! ${hostPkgs.diffutils}/bin/cmp "''${PUBLIC_KEY}" ${publicKey}; then
158 (set -x; sudo --reset-timestamp ${installCredentials} "''${KEYS}")
159 fi
160+ KEYS="$(${hostPkgs.nix}/bin/nix-store --add "$KEYS")" ${lib.getExe config.system.build.vm}
161 '');
162163 in
···177 Please inspect the trace of the following command to figure out which module
178 has a dependency on stateVersion.
179180+ nix-instantiate --attr darwin.linux-builder --show-trace
181 '');
182 };
183···234 # This ensures that anything built on the guest isn't lost when the guest is
235 # restarted.
236 writableStoreUseTmpfs = false;
237+238+ # Pass certificates from host to the guest otherwise when custom CA certificates
239+ # are required we can't use the cached builder.
240+ useHostCerts = true;
241 };
242 };
243}
···1-{ config, lib, pkgs, ... }:
2-3-with lib;
4-5-let
6-7- cfg = config.nix;
8-9- nixPackage = cfg.package.out;
10-11- isNixAtLeast = versionAtLeast (getVersion nixPackage);
12-13- makeNixBuildUser = nr: {
14- name = "nixbld${toString nr}";
15- value = {
16- description = "Nix build user ${toString nr}";
17-18- /*
19- For consistency with the setgid(2), setuid(2), and setgroups(2)
20- calls in `libstore/build.cc', don't add any supplementary group
21- here except "nixbld".
22- */
23- uid = builtins.add config.ids.uids.nixbld nr;
24- isSystemUser = true;
25- group = "nixbld";
26- extraGroups = [ "nixbld" ];
27- };
28- };
29-30- nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
31-32- nixConf =
33- assert isNixAtLeast "2.2";
34- let
35-36- mkValueString = v:
37- if v == null then ""
38- else if isInt v then toString v
39- else if isBool v then boolToString v
40- else if isFloat v then floatToString v
41- else if isList v then toString v
42- else if isDerivation v then toString v
43- else if builtins.isPath v then toString v
44- else if isString v then v
45- else if strings.isConvertibleWithToString v then toString v
46- else abort "The nix conf value: ${toPretty {} v} can not be encoded";
47-48- mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
49-50- mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
51-52- in
53- pkgs.writeTextFile {
54- name = "nix.conf";
55- text = ''
56- # WARNING: this file is generated from the nix.* options in
57- # your NixOS configuration, typically
58- # /etc/nixos/configuration.nix. Do not edit it!
59- ${mkKeyValuePairs cfg.settings}
60- ${cfg.extraOptions}
61- '';
62- checkPhase = lib.optionalString cfg.checkConfig (
63- if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
64- echo "Ignoring validation for cross-compilation"
65- ''
66- else ''
67- echo "Validating generated nix.conf"
68- ln -s $out ./nix.conf
69- set -e
70- set +o pipefail
71- NIX_CONF_DIR=$PWD \
72- ${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
73- ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
74- |& sed -e 's/^warning:/error:/' \
75- | (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
76- set -o pipefail
77- '');
78- };
79-80- legacyConfMappings = {
81- useSandbox = "sandbox";
82- buildCores = "cores";
83- maxJobs = "max-jobs";
84- sandboxPaths = "extra-sandbox-paths";
85- binaryCaches = "substituters";
86- trustedBinaryCaches = "trusted-substituters";
87- binaryCachePublicKeys = "trusted-public-keys";
88- autoOptimiseStore = "auto-optimise-store";
89- requireSignedBinaryCaches = "require-sigs";
90- trustedUsers = "trusted-users";
91- allowedUsers = "allowed-users";
92- systemFeatures = "system-features";
93- };
94-95- semanticConfType = with types;
96- let
97- confAtom = nullOr
98- (oneOf [
99- bool
100- int
101- float
102- str
103- path
104- package
105- ]) // {
106- description = "Nix config atom (null, bool, int, float, str, path or package)";
107- };
108- in
109- attrsOf (either confAtom (listOf confAtom));
110-111-in
112-113-{
114- imports = [
115- (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; })
116- (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; })
117- (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; })
118- (mkRenamedOptionModuleWith { sinceRelease = 2211; from = [ "nix" "readOnlyStore" ]; to = [ "boot" "readOnlyNixStore" ]; })
119- (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
120- ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" oldConf ]; to = [ "nix" "settings" newConf ]; }) legacyConfMappings;
121-122- ###### interface
123-124- options = {
125-126- nix = {
127-128- enable = mkOption {
129- type = types.bool;
130- default = true;
131- description = lib.mdDoc ''
132- Whether to enable Nix.
133- Disabling Nix makes the system hard to modify and the Nix programs and configuration will not be made available by NixOS itself.
134- '';
135- };
136-137- package = mkOption {
138- type = types.package;
139- default = pkgs.nix;
140- defaultText = literalExpression "pkgs.nix";
141- description = lib.mdDoc ''
142- This option specifies the Nix package instance to use throughout the system.
143- '';
144- };
145-146- distributedBuilds = mkOption {
147- type = types.bool;
148- default = false;
149- description = lib.mdDoc ''
150- Whether to distribute builds to the machines listed in
151- {option}`nix.buildMachines`.
152- '';
153- };
154-155- daemonCPUSchedPolicy = mkOption {
156- type = types.enum [ "other" "batch" "idle" ];
157- default = "other";
158- example = "batch";
159- description = lib.mdDoc ''
160- Nix daemon process CPU scheduling policy. This policy propagates to
161- build processes. `other` is the default scheduling
162- policy for regular tasks. The `batch` policy is
163- similar to `other`, but optimised for
164- non-interactive tasks. `idle` is for extremely
165- low-priority tasks that should only be run when no other task
166- requires CPU time.
167-168- Please note that while using the `idle` policy may
169- greatly improve responsiveness of a system performing expensive
170- builds, it may also slow down and potentially starve crucial
171- configuration updates during load.
172-173- `idle` may therefore be a sensible policy for
174- systems that experience only intermittent phases of high CPU load,
175- such as desktop or portable computers used interactively. Other
176- systems should use the `other` or
177- `batch` policy instead.
178-179- For more fine-grained resource control, please refer to
180- {manpage}`systemd.resource-control(5)` and adjust
181- {option}`systemd.services.nix-daemon` directly.
182- '';
183- };
184-185- daemonIOSchedClass = mkOption {
186- type = types.enum [ "best-effort" "idle" ];
187- default = "best-effort";
188- example = "idle";
189- description = lib.mdDoc ''
190- Nix daemon process I/O scheduling class. This class propagates to
191- build processes. `best-effort` is the default
192- class for regular tasks. The `idle` class is for
193- extremely low-priority tasks that should only perform I/O when no
194- other task does.
195-196- Please note that while using the `idle` scheduling
197- class can improve responsiveness of a system performing expensive
198- builds, it might also slow down or starve crucial configuration
199- updates during load.
200-201- `idle` may therefore be a sensible class for
202- systems that experience only intermittent phases of high I/O load,
203- such as desktop or portable computers used interactively. Other
204- systems should use the `best-effort` class.
205- '';
206- };
207-208- daemonIOSchedPriority = mkOption {
209- type = types.int;
210- default = 4;
211- example = 1;
212- description = lib.mdDoc ''
213- Nix daemon process I/O scheduling priority. This priority propagates
214- to build processes. The supported priorities depend on the
215- scheduling policy: With idle, priorities are not used in scheduling
216- decisions. best-effort supports values in the range 0 (high) to 7
217- (low).
218- '';
219- };
220-221- buildMachines = mkOption {
222- type = types.listOf (types.submodule {
223- options = {
224- hostName = mkOption {
225- type = types.str;
226- example = "nixbuilder.example.org";
227- description = lib.mdDoc ''
228- The hostname of the build machine.
229- '';
230- };
231- protocol = mkOption {
232- type = types.enum [ null "ssh" "ssh-ng" ];
233- default = "ssh";
234- example = "ssh-ng";
235- description = lib.mdDoc ''
236- The protocol used for communicating with the build machine.
237- Use `ssh-ng` if your remote builder and your
238- local Nix version support that improved protocol.
239-240- Use `null` when trying to change the special localhost builder
241- without a protocol which is for example used by hydra.
242- '';
243- };
244- system = mkOption {
245- type = types.nullOr types.str;
246- default = null;
247- example = "x86_64-linux";
248- description = lib.mdDoc ''
249- The system type the build machine can execute derivations on.
250- Either this attribute or {var}`systems` must be
251- present, where {var}`system` takes precedence if
252- both are set.
253- '';
254- };
255- systems = mkOption {
256- type = types.listOf types.str;
257- default = [ ];
258- example = [ "x86_64-linux" "aarch64-linux" ];
259- description = lib.mdDoc ''
260- The system types the build machine can execute derivations on.
261- Either this attribute or {var}`system` must be
262- present, where {var}`system` takes precedence if
263- both are set.
264- '';
265- };
266- sshUser = mkOption {
267- type = types.nullOr types.str;
268- default = null;
269- example = "builder";
270- description = lib.mdDoc ''
271- The username to log in as on the remote host. This user must be
272- able to log in and run nix commands non-interactively. It must
273- also be privileged to build derivations, so must be included in
274- {option}`nix.settings.trusted-users`.
275- '';
276- };
277- sshKey = mkOption {
278- type = types.nullOr types.str;
279- default = null;
280- example = "/root/.ssh/id_buildhost_builduser";
281- description = lib.mdDoc ''
282- The path to the SSH private key with which to authenticate on
283- the build machine. The private key must not have a passphrase.
284- If null, the building user (root on NixOS machines) must have an
285- appropriate ssh configuration to log in non-interactively.
286-287- Note that for security reasons, this path must point to a file
288- in the local filesystem, *not* to the nix store.
289- '';
290- };
291- maxJobs = mkOption {
292- type = types.int;
293- default = 1;
294- description = lib.mdDoc ''
295- The number of concurrent jobs the build machine supports. The
296- build machine will enforce its own limits, but this allows hydra
297- to schedule better since there is no work-stealing between build
298- machines.
299- '';
300- };
301- speedFactor = mkOption {
302- type = types.int;
303- default = 1;
304- description = lib.mdDoc ''
305- The relative speed of this builder. This is an arbitrary integer
306- that indicates the speed of this builder, relative to other
307- builders. Higher is faster.
308- '';
309- };
310- mandatoryFeatures = mkOption {
311- type = types.listOf types.str;
312- default = [ ];
313- example = [ "big-parallel" ];
314- description = lib.mdDoc ''
315- A list of features mandatory for this builder. The builder will
316- be ignored for derivations that don't require all features in
317- this list. All mandatory features are automatically included in
318- {var}`supportedFeatures`.
319- '';
320- };
321- supportedFeatures = mkOption {
322- type = types.listOf types.str;
323- default = [ ];
324- example = [ "kvm" "big-parallel" ];
325- description = lib.mdDoc ''
326- A list of features supported by this builder. The builder will
327- be ignored for derivations that require features not in this
328- list.
329- '';
330- };
331- publicHostKey = mkOption {
332- type = types.nullOr types.str;
333- default = null;
334- description = lib.mdDoc ''
335- The (base64-encoded) public host key of this builder. The field
336- is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`.
337- If null, SSH will use its regular known-hosts file when connecting.
338- '';
339- };
340- };
341- });
342- default = [ ];
343- description = lib.mdDoc ''
344- This option lists the machines to be used if distributed builds are
345- enabled (see {option}`nix.distributedBuilds`).
346- Nix will perform derivations on those machines via SSH by copying the
347- inputs to the Nix store on the remote machine, starting the build,
348- then copying the output back to the local Nix store.
349- '';
350- };
351-352- # Environment variables for running Nix.
353- envVars = mkOption {
354- type = types.attrs;
355- internal = true;
356- default = { };
357- description = lib.mdDoc "Environment variables used by Nix.";
358- };
359-360- nrBuildUsers = mkOption {
361- type = types.int;
362- description = lib.mdDoc ''
363- Number of `nixbld` user accounts created to
364- perform secure concurrent builds. If you receive an error
365- message saying that “all build users are currently in use”,
366- you should increase this value.
367- '';
368- };
369-370- nixPath = mkOption {
371- type = types.listOf types.str;
372- default = [
373- "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
374- "nixos-config=/etc/nixos/configuration.nix"
375- "/nix/var/nix/profiles/per-user/root/channels"
376- ];
377- description = lib.mdDoc ''
378- The default Nix expression search path, used by the Nix
379- evaluator to look up paths enclosed in angle brackets
380- (e.g. `<nixpkgs>`).
381- '';
382- };
383-384- checkConfig = mkOption {
385- type = types.bool;
386- default = true;
387- description = lib.mdDoc ''
388- If enabled, checks that Nix can parse the generated nix.conf.
389- '';
390- };
391-392- checkAllErrors = mkOption {
393- type = types.bool;
394- default = true;
395- description = lib.mdDoc ''
396- If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings.
397- '';
398- };
399-400- registry = mkOption {
401- type = types.attrsOf (types.submodule (
402- let
403- referenceAttrs = with types; attrsOf (oneOf [
404- str
405- int
406- bool
407- path
408- package
409- ]);
410- in
411- { config, name, ... }:
412- {
413- options = {
414- from = mkOption {
415- type = referenceAttrs;
416- example = { type = "indirect"; id = "nixpkgs"; };
417- description = lib.mdDoc "The flake reference to be rewritten.";
418- };
419- to = mkOption {
420- type = referenceAttrs;
421- example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; };
422- description = lib.mdDoc "The flake reference {option}`from` is rewritten to.";
423- };
424- flake = mkOption {
425- type = types.nullOr types.attrs;
426- default = null;
427- example = literalExpression "nixpkgs";
428- description = lib.mdDoc ''
429- The flake input {option}`from` is rewritten to.
430- '';
431- };
432- exact = mkOption {
433- type = types.bool;
434- default = true;
435- description = lib.mdDoc ''
436- Whether the {option}`from` reference needs to match exactly. If set,
437- a {option}`from` reference like `nixpkgs` does not
438- match with a reference like `nixpkgs/nixos-20.03`.
439- '';
440- };
441- };
442- config = {
443- from = mkDefault { type = "indirect"; id = name; };
444- to = mkIf (config.flake != null) (mkDefault (
445- {
446- type = "path";
447- path = config.flake.outPath;
448- } // filterAttrs
449- (n: _: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash")
450- config.flake
451- ));
452- };
453- }
454- ));
455- default = { };
456- description = lib.mdDoc ''
457- A system-wide flake registry.
458- '';
459- };
460-461- extraOptions = mkOption {
462- type = types.lines;
463- default = "";
464- example = ''
465- keep-outputs = true
466- keep-derivations = true
467- '';
468- description = lib.mdDoc "Additional text appended to {file}`nix.conf`.";
469- };
470-471- settings = mkOption {
472- type = types.submodule {
473- freeformType = semanticConfType;
474-475- options = {
476- max-jobs = mkOption {
477- type = types.either types.int (types.enum [ "auto" ]);
478- default = "auto";
479- example = 64;
480- description = lib.mdDoc ''
481- This option defines the maximum number of jobs that Nix will try to
482- build in parallel. The default is auto, which means it will use all
483- available logical cores. It is recommend to set it to the total
484- number of logical cores in your system (e.g., 16 for two CPUs with 4
485- cores each and hyper-threading).
486- '';
487- };
488-489- auto-optimise-store = mkOption {
490- type = types.bool;
491- default = false;
492- example = true;
493- description = lib.mdDoc ''
494- If set to true, Nix automatically detects files in the store that have
495- identical contents, and replaces them with hard links to a single copy.
496- This saves disk space. If set to false (the default), you can still run
497- nix-store --optimise to get rid of duplicate files.
498- '';
499- };
500-501- cores = mkOption {
502- type = types.int;
503- default = 0;
504- example = 64;
505- description = lib.mdDoc ''
506- This option defines the maximum number of concurrent tasks during
507- one build. It affects, e.g., -j option for make.
508- The special value 0 means that the builder should use all
509- available CPU cores in the system. Some builds may become
510- non-deterministic with this option; use with care! Packages will
511- only be affected if enableParallelBuilding is set for them.
512- '';
513- };
514-515- sandbox = mkOption {
516- type = types.either types.bool (types.enum [ "relaxed" ]);
517- default = true;
518- description = lib.mdDoc ''
519- If set, Nix will perform builds in a sandboxed environment that it
520- will set up automatically for each build. This prevents impurities
521- in builds by disallowing access to dependencies outside of the Nix
522- store by using network and mount namespaces in a chroot environment.
523-524- This is enabled by default even though it has a possible performance
525- impact due to the initial setup time of a sandbox for each build. It
526- doesn't affect derivation hashes, so changing this option will not
527- trigger a rebuild of packages.
528-529- When set to "relaxed", this option permits derivations that set
530- `__noChroot = true;` to run outside of the sandboxed environment.
531- Exercise caution when using this mode of operation! It is intended to
532- be a quick hack when building with packages that are not easily setup
533- to be built reproducibly.
534- '';
535- };
536-537- extra-sandbox-paths = mkOption {
538- type = types.listOf types.str;
539- default = [ ];
540- example = [ "/dev" "/proc" ];
541- description = lib.mdDoc ''
542- Directories from the host filesystem to be included
543- in the sandbox.
544- '';
545- };
546-547- substituters = mkOption {
548- type = types.listOf types.str;
549- description = lib.mdDoc ''
550- List of binary cache URLs used to obtain pre-built binaries
551- of Nix packages.
552-553- By default https://cache.nixos.org/ is added.
554- '';
555- };
556-557- trusted-substituters = mkOption {
558- type = types.listOf types.str;
559- default = [ ];
560- example = [ "https://hydra.nixos.org/" ];
561- description = lib.mdDoc ''
562- List of binary cache URLs that non-root users can use (in
563- addition to those specified using
564- {option}`nix.settings.substituters`) by passing
565- `--option binary-caches` to Nix commands.
566- '';
567- };
568-569- require-sigs = mkOption {
570- type = types.bool;
571- default = true;
572- description = lib.mdDoc ''
573- If enabled (the default), Nix will only download binaries from binary caches if
574- they are cryptographically signed with any of the keys listed in
575- {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither
576- required nor checked, so it's strongly recommended that you use only
577- trustworthy caches and https to prevent man-in-the-middle attacks.
578- '';
579- };
580-581- trusted-public-keys = mkOption {
582- type = types.listOf types.str;
583- example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
584- description = lib.mdDoc ''
585- List of public keys used to sign binary caches. If
586- {option}`nix.settings.trusted-public-keys` is enabled,
587- then Nix will use a binary from a binary cache if and only
588- if it is signed by *any* of the keys
589- listed here. By default, only the key for
590- `cache.nixos.org` is included.
591- '';
592- };
593-594- trusted-users = mkOption {
595- type = types.listOf types.str;
596- default = [ "root" ];
597- example = [ "root" "alice" "@wheel" ];
598- description = lib.mdDoc ''
599- A list of names of users that have additional rights when
600- connecting to the Nix daemon, such as the ability to specify
601- additional binary caches, or to import unsigned NARs. You
602- can also specify groups by prefixing them with
603- `@`; for instance,
604- `@wheel` means all users in the wheel
605- group.
606- '';
607- };
608-609- system-features = mkOption {
610- type = types.listOf types.str;
611- example = [ "kvm" "big-parallel" "gccarch-skylake" ];
612- description = lib.mdDoc ''
613- The set of features supported by the machine. Derivations
614- can express dependencies on system features through the
615- `requiredSystemFeatures` attribute.
616-617- By default, pseudo-features `nixos-test`, `benchmark`,
618- and `big-parallel` used in Nixpkgs are set, `kvm`
619- is also included if it is available.
620- '';
621- };
622-623- allowed-users = mkOption {
624- type = types.listOf types.str;
625- default = [ "*" ];
626- example = [ "@wheel" "@builders" "alice" "bob" ];
627- description = lib.mdDoc ''
628- A list of names of users (separated by whitespace) that are
629- allowed to connect to the Nix daemon. As with
630- {option}`nix.settings.trusted-users`, you can specify groups by
631- prefixing them with `@`. Also, you can
632- allow all users by specifying `*`. The
633- default is `*`. Note that trusted users are
634- always allowed to connect.
635- '';
636- };
637- };
638- };
639- default = { };
640- example = literalExpression ''
641- {
642- use-sandbox = true;
643- show-trace = true;
644-645- system-features = [ "big-parallel" "kvm" "recursive-nix" ];
646- sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; };
647- }
648- '';
649- description = lib.mdDoc ''
650- Configuration for Nix, see
651- <https://nixos.org/manual/nix/stable/command-ref/conf-file.html> or
652- {manpage}`nix.conf(5)` for available options.
653- The value declared here will be translated directly to the key-value pairs Nix expects.
654-655- You can use {command}`nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings`
656- to view the current value. By default it is empty.
657-658- Nix configurations defined under {option}`nix.*` will be translated and applied to this
659- option. In addition, configuration specified in {option}`nix.extraOptions` will be appended
660- verbatim to the resulting config file.
661- '';
662- };
663- };
664- };
665-666-667- ###### implementation
668-669- config = mkIf cfg.enable {
670- environment.systemPackages =
671- [
672- nixPackage
673- pkgs.nix-info
674- ]
675- ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
676-677- environment.etc."nix/nix.conf".source = nixConf;
678-679- environment.etc."nix/registry.json".text = builtins.toJSON {
680- version = 2;
681- flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
682- };
683-684- # List of machines for distributed Nix builds in the format
685- # expected by build-remote.pl.
686- environment.etc."nix/machines" = mkIf (cfg.buildMachines != [ ]) {
687- text =
688- concatMapStrings
689- (machine:
690- (concatStringsSep " " ([
691- "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
692- (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
693- (if machine.sshKey != null then machine.sshKey else "-")
694- (toString machine.maxJobs)
695- (toString machine.speedFactor)
696- (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures);
697- in if (res == []) then "-" else (concatStringsSep "," res))
698- (let res = machine.mandatoryFeatures;
699- in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures))
700- ]
701- ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
702- + "\n"
703- )
704- cfg.buildMachines;
705- };
706-707- assertions =
708- let badMachine = m: m.system == null && m.systems == [ ];
709- in
710- [
711- {
712- assertion = !(any badMachine cfg.buildMachines);
713- message = ''
714- At least one system type (via <varname>system</varname> or
715- <varname>systems</varname>) must be set for every build machine.
716- Invalid machine specifications:
717- '' + " " +
718- (concatStringsSep "\n "
719- (map (m: m.hostName)
720- (filter (badMachine) cfg.buildMachines)));
721- }
722- ];
723-724- systemd.packages = [ nixPackage ];
725-726- # Will only work once https://github.com/NixOS/nix/pull/6285 is merged
727- # systemd.tmpfiles.packages = [ nixPackage ];
728-729- # Can be dropped for Nix > https://github.com/NixOS/nix/pull/6285
730- systemd.tmpfiles.rules = [
731- "d /nix/var/nix/daemon-socket 0755 root root - -"
732- ];
733-734- systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
735-736- systemd.services.nix-daemon =
737- {
738- path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
739- ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
740-741- environment = cfg.envVars
742- // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
743- // config.networking.proxy.envVars;
744-745- unitConfig.RequiresMountsFor = "/nix/store";
746-747- serviceConfig =
748- {
749- CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
750- IOSchedulingClass = cfg.daemonIOSchedClass;
751- IOSchedulingPriority = cfg.daemonIOSchedPriority;
752- LimitNOFILE = 1048576;
753- };
754-755- restartTriggers = [ nixConf ];
756-757- # `stopIfChanged = false` changes to switch behavior
758- # from stop -> update units -> start
759- # to update units -> restart
760- #
761- # The `stopIfChanged` setting therefore controls a trade-off between a
762- # more predictable lifecycle, which runs the correct "version" of
763- # the `ExecStop` line, and on the other hand the availability of
764- # sockets during the switch, as the effectiveness of the stop operation
765- # depends on the socket being stopped as well.
766- #
767- # As `nix-daemon.service` does not make use of `ExecStop`, we prefer
768- # to keep the socket up and available. This is important for machines
769- # that run Nix-based services, such as automated build, test, and deploy
770- # services, that expect the daemon socket to be available at all times.
771- #
772- # Notably, the Nix client does not retry on failure to connect to the
773- # daemon socket, and the in-process RemoteStore instance will disable
774- # itself. This makes retries infeasible even for services that are
775- # aware of the issue. Failure to connect can affect not only new client
776- # processes, but also new RemoteStore instances in existing processes,
777- # as well as existing RemoteStore instances that have not saturated
778- # their connection pool.
779- #
780- # Also note that `stopIfChanged = true` does not kill existing
781- # connection handling daemons, as one might wish to happen before a
782- # breaking Nix upgrade (which is rare). The daemon forks that handle
783- # the individual connections split off into their own sessions, causing
784- # them not to be stopped by systemd.
785- # If a Nix upgrade does require all existing daemon processes to stop,
786- # nix-daemon must do so on its own accord, and only when the new version
787- # starts and detects that Nix's persistent state needs an upgrade.
788- stopIfChanged = false;
789-790- };
791-792- # Set up the environment variables for running Nix.
793- environment.sessionVariables = cfg.envVars // { NIX_PATH = cfg.nixPath; };
794-795- environment.extraInit =
796- ''
797- if [ -e "$HOME/.nix-defexpr/channels" ]; then
798- export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
799- fi
800- '';
801-802- nix.nrBuildUsers = mkDefault (
803- if cfg.settings.auto-allocate-uids or false then 0
804- else max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)
805- );
806-807- users.users = nixbldUsers;
808-809- services.xserver.displayManager.hiddenUsers = attrNames nixbldUsers;
810-811- system.activationScripts.nix = stringAfter [ "etc" "users" ]
812- ''
813- install -m 0755 -d /nix/var/nix/{gcroots,profiles}/per-user
814-815- # Subscribe the root user to the NixOS channel by default.
816- if [ ! -e "/root/.nix-channels" ]; then
817- echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels"
818- fi
819- '';
820-821- # Legacy configuration conversion.
822- nix.settings = mkMerge [
823- {
824- trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
825- substituters = mkAfter [ "https://cache.nixos.org/" ];
826-827- system-features = mkDefault (
828- [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
829- optionals (pkgs.stdenv.hostPlatform ? gcc.arch) (
830- # a builder can run code for `gcc.arch` and inferior architectures
831- [ "gccarch-${pkgs.stdenv.hostPlatform.gcc.arch}" ] ++
832- map (x: "gccarch-${x}") (systems.architectures.inferiors.${pkgs.stdenv.hostPlatform.gcc.arch} or [])
833- )
834- );
835- }
836-837- (mkIf (!cfg.distributedBuilds) { builders = null; })
838-839- (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
840- ];
841-842- };
843-844-}
···1+/*
2+ Declares what makes the nix-daemon work on systemd.
3+4+ See also
5+ - nixos/modules/config/nix.nix: the nix.conf
6+ - nixos/modules/config/nix-remote-build.nix: the nix.conf
7+*/
8+{ config, lib, pkgs, ... }:
9+10+with lib;
11+12+let
13+14+ cfg = config.nix;
15+16+ nixPackage = cfg.package.out;
17+18+ isNixAtLeast = versionAtLeast (getVersion nixPackage);
19+20+ makeNixBuildUser = nr: {
21+ name = "nixbld${toString nr}";
22+ value = {
23+ description = "Nix build user ${toString nr}";
24+25+ /*
26+ For consistency with the setgid(2), setuid(2), and setgroups(2)
27+ calls in `libstore/build.cc', don't add any supplementary group
28+ here except "nixbld".
29+ */
30+ uid = builtins.add config.ids.uids.nixbld nr;
31+ isSystemUser = true;
32+ group = "nixbld";
33+ extraGroups = [ "nixbld" ];
34+ };
35+ };
36+37+ nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
38+39+in
40+41+{
42+ imports = [
43+ (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; })
44+ (mkRenamedOptionModuleWith { sinceRelease = 2211; from = [ "nix" "readOnlyStore" ]; to = [ "boot" "readOnlyNixStore" ]; })
45+ (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
46+ ];
47+48+ ###### interface
49+50+ options = {
51+52+ nix = {
53+54+ enable = mkOption {
55+ type = types.bool;
56+ default = true;
57+ description = lib.mdDoc ''
58+ Whether to enable Nix.
59+ Disabling Nix makes the system hard to modify and the Nix programs and configuration will not be made available by NixOS itself.
60+ '';
61+ };
62+63+ package = mkOption {
64+ type = types.package;
65+ default = pkgs.nix;
66+ defaultText = literalExpression "pkgs.nix";
67+ description = lib.mdDoc ''
68+ This option specifies the Nix package instance to use throughout the system.
69+ '';
70+ };
71+72+ daemonCPUSchedPolicy = mkOption {
73+ type = types.enum [ "other" "batch" "idle" ];
74+ default = "other";
75+ example = "batch";
76+ description = lib.mdDoc ''
77+ Nix daemon process CPU scheduling policy. This policy propagates to
78+ build processes. `other` is the default scheduling
79+ policy for regular tasks. The `batch` policy is
80+ similar to `other`, but optimised for
81+ non-interactive tasks. `idle` is for extremely
82+ low-priority tasks that should only be run when no other task
83+ requires CPU time.
84+85+ Please note that while using the `idle` policy may
86+ greatly improve responsiveness of a system performing expensive
87+ builds, it may also slow down and potentially starve crucial
88+ configuration updates during load.
89+90+ `idle` may therefore be a sensible policy for
91+ systems that experience only intermittent phases of high CPU load,
92+ such as desktop or portable computers used interactively. Other
93+ systems should use the `other` or
94+ `batch` policy instead.
95+96+ For more fine-grained resource control, please refer to
97+ {manpage}`systemd.resource-control(5)` and adjust
98+ {option}`systemd.services.nix-daemon` directly.
99+ '';
100+ };
101+102+ daemonIOSchedClass = mkOption {
103+ type = types.enum [ "best-effort" "idle" ];
104+ default = "best-effort";
105+ example = "idle";
106+ description = lib.mdDoc ''
107+ Nix daemon process I/O scheduling class. This class propagates to
108+ build processes. `best-effort` is the default
109+ class for regular tasks. The `idle` class is for
110+ extremely low-priority tasks that should only perform I/O when no
111+ other task does.
112+113+ Please note that while using the `idle` scheduling
114+ class can improve responsiveness of a system performing expensive
115+ builds, it might also slow down or starve crucial configuration
116+ updates during load.
117+118+ `idle` may therefore be a sensible class for
119+ systems that experience only intermittent phases of high I/O load,
120+ such as desktop or portable computers used interactively. Other
121+ systems should use the `best-effort` class.
122+ '';
123+ };
124+125+ daemonIOSchedPriority = mkOption {
126+ type = types.int;
127+ default = 4;
128+ example = 1;
129+ description = lib.mdDoc ''
130+ Nix daemon process I/O scheduling priority. This priority propagates
131+ to build processes. The supported priorities depend on the
132+ scheduling policy: With idle, priorities are not used in scheduling
133+ decisions. best-effort supports values in the range 0 (high) to 7
134+ (low).
135+ '';
136+ };
137+138+ # Environment variables for running Nix.
139+ envVars = mkOption {
140+ type = types.attrs;
141+ internal = true;
142+ default = { };
143+ description = lib.mdDoc "Environment variables used by Nix.";
144+ };
145+146+ nrBuildUsers = mkOption {
147+ type = types.int;
148+ description = lib.mdDoc ''
149+ Number of `nixbld` user accounts created to
150+ perform secure concurrent builds. If you receive an error
151+ message saying that “all build users are currently in use”,
152+ you should increase this value.
153+ '';
154+ };
155+ };
156+ };
157+158+159+ ###### implementation
160+161+ config = mkIf cfg.enable {
162+ environment.systemPackages =
163+ [
164+ nixPackage
165+ pkgs.nix-info
166+ ]
167+ ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
168+169+ systemd.packages = [ nixPackage ];
170+171+ # Will only work once https://github.com/NixOS/nix/pull/6285 is merged
172+ # systemd.tmpfiles.packages = [ nixPackage ];
173+174+ # Can be dropped for Nix > https://github.com/NixOS/nix/pull/6285
175+ systemd.tmpfiles.rules = [
176+ "d /nix/var/nix/daemon-socket 0755 root root - -"
177+ ];
178+179+ systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
180+181+ systemd.services.nix-daemon =
182+ {
183+ path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
184+ ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
185+186+ environment = cfg.envVars
187+ // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
188+ // config.networking.proxy.envVars;
189+190+ unitConfig.RequiresMountsFor = "/nix/store";
191+192+ serviceConfig =
193+ {
194+ CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
195+ IOSchedulingClass = cfg.daemonIOSchedClass;
196+ IOSchedulingPriority = cfg.daemonIOSchedPriority;
197+ LimitNOFILE = 1048576;
198+ };
199+200+ restartTriggers = [ config.environment.etc."nix/nix.conf".source ];
201+202+ # `stopIfChanged = false` changes to switch behavior
203+ # from stop -> update units -> start
204+ # to update units -> restart
205+ #
206+ # The `stopIfChanged` setting therefore controls a trade-off between a
207+ # more predictable lifecycle, which runs the correct "version" of
208+ # the `ExecStop` line, and on the other hand the availability of
209+ # sockets during the switch, as the effectiveness of the stop operation
210+ # depends on the socket being stopped as well.
211+ #
212+ # As `nix-daemon.service` does not make use of `ExecStop`, we prefer
213+ # to keep the socket up and available. This is important for machines
214+ # that run Nix-based services, such as automated build, test, and deploy
215+ # services, that expect the daemon socket to be available at all times.
216+ #
217+ # Notably, the Nix client does not retry on failure to connect to the
218+ # daemon socket, and the in-process RemoteStore instance will disable
219+ # itself. This makes retries infeasible even for services that are
220+ # aware of the issue. Failure to connect can affect not only new client
221+ # processes, but also new RemoteStore instances in existing processes,
222+ # as well as existing RemoteStore instances that have not saturated
223+ # their connection pool.
224+ #
225+ # Also note that `stopIfChanged = true` does not kill existing
226+ # connection handling daemons, as one might wish to happen before a
227+ # breaking Nix upgrade (which is rare). The daemon forks that handle
228+ # the individual connections split off into their own sessions, causing
229+ # them not to be stopped by systemd.
230+ # If a Nix upgrade does require all existing daemon processes to stop,
231+ # nix-daemon must do so on its own accord, and only when the new version
232+ # starts and detects that Nix's persistent state needs an upgrade.
233+ stopIfChanged = false;
234+235+ };
236+237+ # Set up the environment variables for running Nix.
238+ environment.sessionVariables = cfg.envVars;
239+240+ nix.nrBuildUsers = mkDefault (
241+ if cfg.settings.auto-allocate-uids or false then 0
242+ else max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)
243+ );
244+245+ users.users = nixbldUsers;
246+247+ services.xserver.displayManager.hiddenUsers = attrNames nixbldUsers;
248+249+ system.activationScripts.nix = stringAfter [ "etc" "users" ]
250+ ''
251+ install -m 0755 -d /nix/var/nix/{gcroots,profiles}/per-user
252+ '';
253+254+ # Legacy configuration conversion.
255+ nix.settings = mkMerge [
256+ (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
257+ ];
258+259+ };
260+261+}
+27-1
nixos/modules/virtualisation/qemu-vm.nix
···166 # Create a directory for exchanging data with the VM.
167 mkdir -p "$TMPDIR/xchg"
1680000000000169 ${lib.optionalString cfg.useEFIBoot
170 ''
171 # Expose EFI variables, it's useful even when we are not using a bootloader (!).
···877 '';
878 };
879880-881 virtualisation.bios =
882 mkOption {
883 type = types.nullOr types.package;
···887 An alternate BIOS (such as `qboot`) with which to start the VM.
888 Should contain a file named `bios.bin`.
889 If `null`, QEMU's builtin SeaBIOS will be used.
00000000000890 '';
891 };
892···1024 source = ''"''${SHARED_DIR:-$TMPDIR/xchg}"'';
1025 target = "/tmp/shared";
1026 };
00001027 };
0010281029 virtualisation.qemu.networkingOptions =
1030 let
···166 # Create a directory for exchanging data with the VM.
167 mkdir -p "$TMPDIR/xchg"
168169+ ${lib.optionalString cfg.useHostCerts
170+ ''
171+ mkdir -p "$TMPDIR/certs"
172+ if [ -e "$NIX_SSL_CERT_FILE" ]; then
173+ cp -L "$NIX_SSL_CERT_FILE" "$TMPDIR"/certs/ca-certificates.crt
174+ else
175+ echo \$NIX_SSL_CERT_FILE should point to a valid file if virtualisation.useHostCerts is enabled.
176+ fi
177+ ''}
178+179 ${lib.optionalString cfg.useEFIBoot
180 ''
181 # Expose EFI variables, it's useful even when we are not using a bootloader (!).
···887 '';
888 };
8890890 virtualisation.bios =
891 mkOption {
892 type = types.nullOr types.package;
···896 An alternate BIOS (such as `qboot`) with which to start the VM.
897 Should contain a file named `bios.bin`.
898 If `null`, QEMU's builtin SeaBIOS will be used.
899+ '';
900+ };
901+902+ virtualisation.useHostCerts =
903+ mkOption {
904+ type = types.bool;
905+ default = false;
906+ description =
907+ lib.mdDoc ''
908+ If enabled, when `NIX_SSL_CERT_FILE` is set on the host,
909+ pass the CA certificates from the host to the VM.
910 '';
911 };
912···1044 source = ''"''${SHARED_DIR:-$TMPDIR/xchg}"'';
1045 target = "/tmp/shared";
1046 };
1047+ certs = mkIf cfg.useHostCerts {
1048+ source = ''"$TMPDIR"/certs'';
1049+ target = "/etc/ssl/certs";
1050+ };
1051 };
1052+1053+ security.pki.installCACerts = mkIf cfg.useHostCerts false;
10541055 virtualisation.qemu.networkingOptions =
1056 let
···3, generateSplicesForMkScope, makeScopeWithSplicing
4, stdenv
5, preLibcCrossHeaders
6+, config
7}:
89let
···230 discrete-scroll = callPackage ../os-specific/darwin/discrete-scroll { };
231232 # See doc/builders/special/darwin-builder.section.md
233+ linux-builder = lib.makeOverridable ({ modules }:
234 let
235 toGuest = builtins.replaceStrings [ "darwin" ] [ "linux" ];
236···238 configuration = {
239 imports = [
240 ../../nixos/modules/profiles/macos-builder.nix
241+ ] ++ modules;
242243 virtualisation.host = { inherit pkgs; };
244 };
···247 };
248249 in
250+ nixos.config.system.build.macos-builder-installer) { modules = [ ]; };
251+252+} // lib.optionalAttrs config.allowAliases {
253+ builder = throw "'darwin.builder' has been changed and renamed to 'darwin.linux-builder'. The default ssh port is now 31022. Please update your configuration or override the port back to 22. See https://nixos.org/manual/nixpkgs/unstable/#sec-darwin-builder"; # added 2023-07-06
254})
+16-6
pkgs/top-level/php-packages.nix
···203 # This is a set of PHP extensions meant to be used in php.buildEnv
204 # or php.withExtensions to extend the functionality of the PHP
205 # interpreter.
206- extensions = {
0000000000000207 amqp = callPackage ../development/php-packages/amqp { };
208209 apcu = callPackage ../development/php-packages/apcu { };
···225 igbinary = callPackage ../development/php-packages/igbinary { };
226227 imagick = callPackage ../development/php-packages/imagick { };
228-229- inotify = callPackage ../development/php-packages/inotify { };
230231 mailparse = callPackage ../development/php-packages/mailparse { };
232···292293 yaml = callPackage ../development/php-packages/yaml { };
294 } // (
0295 let
296 # This list contains build instructions for different modules that one may
297 # want to build.
···637 # Produce the final attribute set of all extensions defined.
638 in
639 builtins.listToAttrs namedExtensions
640- ) // lib.optionalAttrs (!(lib.versionAtLeast php.version "8.3")) {
641- blackfire = callPackage ../development/tools/misc/blackfire/php-probe.nix { inherit php; };
642- };
643})
···203 # This is a set of PHP extensions meant to be used in php.buildEnv
204 # or php.withExtensions to extend the functionality of the PHP
205 # interpreter.
206+ # The extensions attributes is composed of three sections:
207+ # 1. The contrib conditional extensions, which are only available on specific versions or system
208+ # 2. The contrib extensions available
209+ # 3. The core extensions
210+ extensions =
211+ # Contrib conditional extensions
212+ lib.optionalAttrs (!(lib.versionAtLeast php.version "8.3")) {
213+ blackfire = callPackage ../development/tools/misc/blackfire/php-probe.nix { inherit php; };
214+ } // lib.optionalAttrs (!stdenv.isDarwin) {
215+ # Only available on Linux: https://www.php.net/manual/en/inotify.requirements.php
216+ inotify = callPackage ../development/php-packages/inotify { };
217+ } //
218+ # Contrib extensions
219+ {
220 amqp = callPackage ../development/php-packages/amqp { };
221222 apcu = callPackage ../development/php-packages/apcu { };
···238 igbinary = callPackage ../development/php-packages/igbinary { };
239240 imagick = callPackage ../development/php-packages/imagick { };
00241242 mailparse = callPackage ../development/php-packages/mailparse { };
243···303304 yaml = callPackage ../development/php-packages/yaml { };
305 } // (
306+ # Core extensions
307 let
308 # This list contains build instructions for different modules that one may
309 # want to build.
···649 # Produce the final attribute set of all extensions defined.
650 in
651 builtins.listToAttrs namedExtensions
652+ );
00653})