python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / misc / nix-daemon.nix
blob26e7cbfca733fd13aeae3f17dedb0c898a8a61bd
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
7   cfg = config.nix;
9   nixPackage = cfg.package.out;
11   isNixAtLeast = versionAtLeast (getVersion nixPackage);
13   makeNixBuildUser = nr: {
14     name = "nixbld${toString nr}";
15     value = {
16       description = "Nix build user ${toString nr}";
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   };
30   nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
32   nixConf =
33     assert isNixAtLeast "2.2";
34     let
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 isCoercibleToString v then toString v
46         else abort "The nix conf value: ${toPretty {} v} can not be encoded";
48       mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
50       mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
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     };
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   };
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));
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     (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
119   ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" oldConf ]; to = [ "nix" "settings" newConf ]; }) legacyConfMappings;
121   ###### interface
123   options = {
125     nix = {
127       enable = mkOption {
128         type = types.bool;
129         default = true;
130         description = lib.mdDoc ''
131           Whether to enable Nix.
132           Disabling Nix makes the system hard to modify and the Nix programs and configuration will not be made available by NixOS itself.
133         '';
134       };
136       package = mkOption {
137         type = types.package;
138         default = pkgs.nix;
139         defaultText = literalExpression "pkgs.nix";
140         description = lib.mdDoc ''
141           This option specifies the Nix package instance to use throughout the system.
142         '';
143       };
145       distributedBuilds = mkOption {
146         type = types.bool;
147         default = false;
148         description = lib.mdDoc ''
149           Whether to distribute builds to the machines listed in
150           {option}`nix.buildMachines`.
151         '';
152       };
154       daemonCPUSchedPolicy = mkOption {
155         type = types.enum [ "other" "batch" "idle" ];
156         default = "other";
157         example = "batch";
158         description = lib.mdDoc ''
159           Nix daemon process CPU scheduling policy. This policy propagates to
160           build processes. `other` is the default scheduling
161           policy for regular tasks. The `batch` policy is
162           similar to `other`, but optimised for
163           non-interactive tasks. `idle` is for extremely
164           low-priority tasks that should only be run when no other task
165           requires CPU time.
167           Please note that while using the `idle` policy may
168           greatly improve responsiveness of a system performing expensive
169           builds, it may also slow down and potentially starve crucial
170           configuration updates during load.
172           `idle` may therefore be a sensible policy for
173           systems that experience only intermittent phases of high CPU load,
174           such as desktop or portable computers used interactively. Other
175           systems should use the `other` or
176           `batch` policy instead.
178           For more fine-grained resource control, please refer to
179           {manpage}`systemd.resource-control(5)` and adjust
180           {option}`systemd.services.nix-daemon` directly.
181       '';
182       };
184       daemonIOSchedClass = mkOption {
185         type = types.enum [ "best-effort" "idle" ];
186         default = "best-effort";
187         example = "idle";
188         description = lib.mdDoc ''
189           Nix daemon process I/O scheduling class. This class propagates to
190           build processes. `best-effort` is the default
191           class for regular tasks. The `idle` class is for
192           extremely low-priority tasks that should only perform I/O when no
193           other task does.
195           Please note that while using the `idle` scheduling
196           class can improve responsiveness of a system performing expensive
197           builds, it might also slow down or starve crucial configuration
198           updates during load.
200           `idle` may therefore be a sensible class for
201           systems that experience only intermittent phases of high I/O load,
202           such as desktop or portable computers used interactively. Other
203           systems should use the `best-effort` class.
204       '';
205       };
207       daemonIOSchedPriority = mkOption {
208         type = types.int;
209         default = 4;
210         example = 1;
211         description = lib.mdDoc ''
212           Nix daemon process I/O scheduling priority. This priority propagates
213           to build processes. The supported priorities depend on the
214           scheduling policy: With idle, priorities are not used in scheduling
215           decisions. best-effort supports values in the range 0 (high) to 7
216           (low).
217         '';
218       };
220       buildMachines = mkOption {
221         type = types.listOf (types.submodule {
222           options = {
223             hostName = mkOption {
224               type = types.str;
225               example = "nixbuilder.example.org";
226               description = lib.mdDoc ''
227                 The hostname of the build machine.
228               '';
229             };
230             protocol = mkOption {
231               type = types.enum [ null "ssh" "ssh-ng" ];
232               default = "ssh";
233               example = "ssh-ng";
234               description = lib.mdDoc ''
235                 The protocol used for communicating with the build machine.
236                 Use `ssh-ng` if your remote builder and your
237                 local Nix version support that improved protocol.
239                 Use `null` when trying to change the special localhost builder
240                 without a protocol which is for example used by hydra.
241               '';
242             };
243             system = mkOption {
244               type = types.nullOr types.str;
245               default = null;
246               example = "x86_64-linux";
247               description = lib.mdDoc ''
248                 The system type the build machine can execute derivations on.
249                 Either this attribute or {var}`systems` must be
250                 present, where {var}`system` takes precedence if
251                 both are set.
252               '';
253             };
254             systems = mkOption {
255               type = types.listOf types.str;
256               default = [ ];
257               example = [ "x86_64-linux" "aarch64-linux" ];
258               description = lib.mdDoc ''
259                 The system types the build machine can execute derivations on.
260                 Either this attribute or {var}`system` must be
261                 present, where {var}`system` takes precedence if
262                 both are set.
263               '';
264             };
265             sshUser = mkOption {
266               type = types.nullOr types.str;
267               default = null;
268               example = "builder";
269               description = lib.mdDoc ''
270                 The username to log in as on the remote host. This user must be
271                 able to log in and run nix commands non-interactively. It must
272                 also be privileged to build derivations, so must be included in
273                 {option}`nix.settings.trusted-users`.
274               '';
275             };
276             sshKey = mkOption {
277               type = types.nullOr types.str;
278               default = null;
279               example = "/root/.ssh/id_buildhost_builduser";
280               description = lib.mdDoc ''
281                 The path to the SSH private key with which to authenticate on
282                 the build machine. The private key must not have a passphrase.
283                 If null, the building user (root on NixOS machines) must have an
284                 appropriate ssh configuration to log in non-interactively.
286                 Note that for security reasons, this path must point to a file
287                 in the local filesystem, *not* to the nix store.
288               '';
289             };
290             maxJobs = mkOption {
291               type = types.int;
292               default = 1;
293               description = lib.mdDoc ''
294                 The number of concurrent jobs the build machine supports. The
295                 build machine will enforce its own limits, but this allows hydra
296                 to schedule better since there is no work-stealing between build
297                 machines.
298               '';
299             };
300             speedFactor = mkOption {
301               type = types.int;
302               default = 1;
303               description = lib.mdDoc ''
304                 The relative speed of this builder. This is an arbitrary integer
305                 that indicates the speed of this builder, relative to other
306                 builders. Higher is faster.
307               '';
308             };
309             mandatoryFeatures = mkOption {
310               type = types.listOf types.str;
311               default = [ ];
312               example = [ "big-parallel" ];
313               description = lib.mdDoc ''
314                 A list of features mandatory for this builder. The builder will
315                 be ignored for derivations that don't require all features in
316                 this list. All mandatory features are automatically included in
317                 {var}`supportedFeatures`.
318               '';
319             };
320             supportedFeatures = mkOption {
321               type = types.listOf types.str;
322               default = [ ];
323               example = [ "kvm" "big-parallel" ];
324               description = lib.mdDoc ''
325                 A list of features supported by this builder. The builder will
326                 be ignored for derivations that require features not in this
327                 list.
328               '';
329             };
330             publicHostKey = mkOption {
331               type = types.nullOr types.str;
332               default = null;
333               description = lib.mdDoc ''
334                 The (base64-encoded) public host key of this builder. The field
335                 is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`.
336                 If null, SSH will use its regular known-hosts file when connecting.
337               '';
338             };
339           };
340         });
341         default = [ ];
342         description = lib.mdDoc ''
343           This option lists the machines to be used if distributed builds are
344           enabled (see {option}`nix.distributedBuilds`).
345           Nix will perform derivations on those machines via SSH by copying the
346           inputs to the Nix store on the remote machine, starting the build,
347           then copying the output back to the local Nix store.
348         '';
349       };
351       # Environment variables for running Nix.
352       envVars = mkOption {
353         type = types.attrs;
354         internal = true;
355         default = { };
356         description = lib.mdDoc "Environment variables used by Nix.";
357       };
359       nrBuildUsers = mkOption {
360         type = types.int;
361         description = lib.mdDoc ''
362           Number of `nixbld` user accounts created to
363           perform secure concurrent builds.  If you receive an error
364           message saying that “all build users are currently in use”,
365           you should increase this value.
366         '';
367       };
369       readOnlyStore = mkOption {
370         type = types.bool;
371         default = true;
372         description = lib.mdDoc ''
373           If set, NixOS will enforce the immutability of the Nix store
374           by making {file}`/nix/store` a read-only bind
375           mount.  Nix will automatically make the store writable when
376           needed.
377         '';
378       };
380       nixPath = mkOption {
381         type = types.listOf types.str;
382         default = [
383           "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
384           "nixos-config=/etc/nixos/configuration.nix"
385           "/nix/var/nix/profiles/per-user/root/channels"
386         ];
387         description = lib.mdDoc ''
388           The default Nix expression search path, used by the Nix
389           evaluator to look up paths enclosed in angle brackets
390           (e.g. `<nixpkgs>`).
391         '';
392       };
394       checkConfig = mkOption {
395         type = types.bool;
396         default = true;
397         description = lib.mdDoc ''
398           If enabled, checks that Nix can parse the generated nix.conf.
399         '';
400       };
402       checkAllErrors = mkOption {
403         type = types.bool;
404         default = true;
405         description = lib.mdDoc ''
406           If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings.
407         '';
408       };
410       registry = mkOption {
411         type = types.attrsOf (types.submodule (
412           let
413             referenceAttrs = with types; attrsOf (oneOf [
414               str
415               int
416               bool
417               package
418             ]);
419           in
420           { config, name, ... }:
421           {
422             options = {
423               from = mkOption {
424                 type = referenceAttrs;
425                 example = { type = "indirect"; id = "nixpkgs"; };
426                 description = lib.mdDoc "The flake reference to be rewritten.";
427               };
428               to = mkOption {
429                 type = referenceAttrs;
430                 example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; };
431                 description = lib.mdDoc "The flake reference {option}`from` is rewritten to.";
432               };
433               flake = mkOption {
434                 type = types.nullOr types.attrs;
435                 default = null;
436                 example = literalExpression "nixpkgs";
437                 description = lib.mdDoc ''
438                   The flake input {option}`from` is rewritten to.
439                 '';
440               };
441               exact = mkOption {
442                 type = types.bool;
443                 default = true;
444                 description = lib.mdDoc ''
445                   Whether the {option}`from` reference needs to match exactly. If set,
446                   a {option}`from` reference like `nixpkgs` does not
447                   match with a reference like `nixpkgs/nixos-20.03`.
448                 '';
449               };
450             };
451             config = {
452               from = mkDefault { type = "indirect"; id = name; };
453               to = mkIf (config.flake != null) (mkDefault (
454                 {
455                   type = "path";
456                   path = config.flake.outPath;
457                 } // filterAttrs
458                   (n: _: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash")
459                   config.flake
460               ));
461             };
462           }
463         ));
464         default = { };
465         description = lib.mdDoc ''
466           A system-wide flake registry.
467         '';
468       };
470       extraOptions = mkOption {
471         type = types.lines;
472         default = "";
473         example = ''
474           keep-outputs = true
475           keep-derivations = true
476         '';
477         description = lib.mdDoc "Additional text appended to {file}`nix.conf`.";
478       };
480       settings = mkOption {
481         type = types.submodule {
482           freeformType = semanticConfType;
484           options = {
485             max-jobs = mkOption {
486               type = types.either types.int (types.enum [ "auto" ]);
487               default = "auto";
488               example = 64;
489               description = lib.mdDoc ''
490                 This option defines the maximum number of jobs that Nix will try to
491                 build in parallel. The default is auto, which means it will use all
492                 available logical cores. It is recommend to set it to the total
493                 number of logical cores in your system (e.g., 16 for two CPUs with 4
494                 cores each and hyper-threading).
495               '';
496             };
498             auto-optimise-store = mkOption {
499               type = types.bool;
500               default = false;
501               example = true;
502               description = lib.mdDoc ''
503                 If set to true, Nix automatically detects files in the store that have
504                 identical contents, and replaces them with hard links to a single copy.
505                 This saves disk space. If set to false (the default), you can still run
506                 nix-store --optimise to get rid of duplicate files.
507               '';
508             };
510             cores = mkOption {
511               type = types.int;
512               default = 0;
513               example = 64;
514               description = lib.mdDoc ''
515                 This option defines the maximum number of concurrent tasks during
516                 one build. It affects, e.g., -j option for make.
517                 The special value 0 means that the builder should use all
518                 available CPU cores in the system. Some builds may become
519                 non-deterministic with this option; use with care! Packages will
520                 only be affected if enableParallelBuilding is set for them.
521               '';
522             };
524             sandbox = mkOption {
525               type = types.either types.bool (types.enum [ "relaxed" ]);
526               default = true;
527               description = lib.mdDoc ''
528                 If set, Nix will perform builds in a sandboxed environment that it
529                 will set up automatically for each build. This prevents impurities
530                 in builds by disallowing access to dependencies outside of the Nix
531                 store by using network and mount namespaces in a chroot environment.
532                 This is enabled by default even though it has a possible performance
533                 impact due to the initial setup time of a sandbox for each build. It
534                 doesn't affect derivation hashes, so changing this option will not
535                 trigger a rebuild of packages.
536               '';
537             };
539             extra-sandbox-paths = mkOption {
540               type = types.listOf types.str;
541               default = [ ];
542               example = [ "/dev" "/proc" ];
543               description = lib.mdDoc ''
544                 Directories from the host filesystem to be included
545                 in the sandbox.
546               '';
547             };
549             substituters = mkOption {
550               type = types.listOf types.str;
551               description = lib.mdDoc ''
552                 List of binary cache URLs used to obtain pre-built binaries
553                 of Nix packages.
555                 By default https://cache.nixos.org/ is added.
556               '';
557             };
559             trusted-substituters = mkOption {
560               type = types.listOf types.str;
561               default = [ ];
562               example = [ "https://hydra.nixos.org/" ];
563               description = lib.mdDoc ''
564                 List of binary cache URLs that non-root users can use (in
565                 addition to those specified using
566                 {option}`nix.settings.substituters`) by passing
567                 `--option binary-caches` to Nix commands.
568               '';
569             };
571             require-sigs = mkOption {
572               type = types.bool;
573               default = true;
574               description = lib.mdDoc ''
575                 If enabled (the default), Nix will only download binaries from binary caches if
576                 they are cryptographically signed with any of the keys listed in
577                 {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither
578                 required nor checked, so it's strongly recommended that you use only
579                 trustworthy caches and https to prevent man-in-the-middle attacks.
580               '';
581             };
583             trusted-public-keys = mkOption {
584               type = types.listOf types.str;
585               example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
586               description = lib.mdDoc ''
587                 List of public keys used to sign binary caches. If
588                 {option}`nix.settings.trusted-public-keys` is enabled,
589                 then Nix will use a binary from a binary cache if and only
590                 if it is signed by *any* of the keys
591                 listed here. By default, only the key for
592                 `cache.nixos.org` is included.
593               '';
594             };
596             trusted-users = mkOption {
597               type = types.listOf types.str;
598               default = [ "root" ];
599               example = [ "root" "alice" "@wheel" ];
600               description = lib.mdDoc ''
601                 A list of names of users that have additional rights when
602                 connecting to the Nix daemon, such as the ability to specify
603                 additional binary caches, or to import unsigned NARs. You
604                 can also specify groups by prefixing them with
605                 `@`; for instance,
606                 `@wheel` means all users in the wheel
607                 group.
608               '';
609             };
611             system-features = mkOption {
612               type = types.listOf types.str;
613               example = [ "kvm" "big-parallel" "gccarch-skylake" ];
614               description = lib.mdDoc ''
615                 The set of features supported by the machine. Derivations
616                 can express dependencies on system features through the
617                 `requiredSystemFeatures` attribute.
619                 By default, pseudo-features `nixos-test`, `benchmark`,
620                 and `big-parallel` used in Nixpkgs are set, `kvm`
621                 is also included in it is avaliable.
622               '';
623             };
625             allowed-users = mkOption {
626               type = types.listOf types.str;
627               default = [ "*" ];
628               example = [ "@wheel" "@builders" "alice" "bob" ];
629               description = lib.mdDoc ''
630                 A list of names of users (separated by whitespace) that are
631                 allowed to connect to the Nix daemon. As with
632                 {option}`nix.settings.trusted-users`, you can specify groups by
633                 prefixing them with `@`. Also, you can
634                 allow all users by specifying `*`. The
635                 default is `*`. Note that trusted users are
636                 always allowed to connect.
637               '';
638             };
639           };
640         };
641         default = { };
642         example = literalExpression ''
643           {
644             use-sandbox = true;
645             show-trace = true;
647             system-features = [ "big-parallel" "kvm" "recursive-nix" ];
648             sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; };
649           }
650         '';
651         description = lib.mdDoc ''
652           Configuration for Nix, see
653           <https://nixos.org/manual/nix/stable/#sec-conf-file> or
654           {manpage}`nix.conf(5)` for avalaible options.
655           The value declared here will be translated directly to the key-value pairs Nix expects.
657           You can use {command}`nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings`
658           to view the current value. By default it is empty.
660           Nix configurations defined under {option}`nix.*` will be translated and applied to this
661           option. In addition, configuration specified in {option}`nix.extraOptions` which will be appended
662           verbatim to the resulting config file.
663         '';
664       };
665     };
666   };
669   ###### implementation
671   config = mkIf cfg.enable {
672     environment.systemPackages =
673       [
674         nixPackage
675         pkgs.nix-info
676       ]
677       ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
679     environment.etc."nix/nix.conf".source = nixConf;
681     environment.etc."nix/registry.json".text = builtins.toJSON {
682       version = 2;
683       flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
684     };
686     # List of machines for distributed Nix builds in the format
687     # expected by build-remote.pl.
688     environment.etc."nix/machines" = mkIf (cfg.buildMachines != [ ]) {
689       text =
690         concatMapStrings
691           (machine:
692             (concatStringsSep " " ([
693               "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
694               (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
695               (if machine.sshKey != null then machine.sshKey else "-")
696               (toString machine.maxJobs)
697               (toString machine.speedFactor)
698               (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures);
699                in if (res == []) then "-" else (concatStringsSep "," res))
700               (let res = machine.mandatoryFeatures;
701                in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures))
702             ]
703             ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
704             + "\n"
705           )
706           cfg.buildMachines;
707     };
709     assertions =
710       let badMachine = m: m.system == null && m.systems == [ ];
711       in
712       [
713         {
714           assertion = !(any badMachine cfg.buildMachines);
715           message = ''
716             At least one system type (via <varname>system</varname> or
717               <varname>systems</varname>) must be set for every build machine.
718               Invalid machine specifications:
719           '' + "      " +
720           (concatStringsSep "\n      "
721             (map (m: m.hostName)
722               (filter (badMachine) cfg.buildMachines)));
723         }
724       ];
726     systemd.packages = [ nixPackage ];
728     # Will only work once https://github.com/NixOS/nix/pull/6285 is merged
729     # systemd.tmpfiles.packages = [ nixPackage ];
731     # Can be dropped for Nix > https://github.com/NixOS/nix/pull/6285
732     systemd.tmpfiles.rules = [
733       "d /nix/var/nix/daemon-socket 0755 root root - -"
734     ];
736     systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
738     systemd.services.nix-daemon =
739       {
740         path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
741           ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
743         environment = cfg.envVars
744           // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
745           // config.networking.proxy.envVars;
747         unitConfig.RequiresMountsFor = "/nix/store";
749         serviceConfig =
750           {
751             CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
752             IOSchedulingClass = cfg.daemonIOSchedClass;
753             IOSchedulingPriority = cfg.daemonIOSchedPriority;
754             LimitNOFILE = 1048576;
755           };
757         restartTriggers = [ nixConf ];
759         # `stopIfChanged = false` changes to switch behavior
760         # from   stop -> update units -> start
761         #   to   update units -> restart
762         #
763         # The `stopIfChanged` setting therefore controls a trade-off between a
764         # more predictable lifecycle, which runs the correct "version" of
765         # the `ExecStop` line, and on the other hand the availability of
766         # sockets during the switch, as the effectiveness of the stop operation
767         # depends on the socket being stopped as well.
768         #
769         # As `nix-daemon.service` does not make use of `ExecStop`, we prefer
770         # to keep the socket up and available. This is important for machines
771         # that run Nix-based services, such as automated build, test, and deploy
772         # services, that expect the daemon socket to be available at all times.
773         #
774         # Notably, the Nix client does not retry on failure to connect to the
775         # daemon socket, and the in-process RemoteStore instance will disable
776         # itself. This makes retries infeasible even for services that are
777         # aware of the issue. Failure to connect can affect not only new client
778         # processes, but also new RemoteStore instances in existing processes,
779         # as well as existing RemoteStore instances that have not saturated
780         # their connection pool.
781         #
782         # Also note that `stopIfChanged = true` does not kill existing
783         # connection handling daemons, as one might wish to happen before a
784         # breaking Nix upgrade (which is rare). The daemon forks that handle
785         # the individual connections split off into their own sessions, causing
786         # them not to be stopped by systemd.
787         # If a Nix upgrade does require all existing daemon processes to stop,
788         # nix-daemon must do so on its own accord, and only when the new version
789         # starts and detects that Nix's persistent state needs an upgrade.
790         stopIfChanged = false;
792       };
794     # Set up the environment variables for running Nix.
795     environment.sessionVariables = cfg.envVars // { NIX_PATH = cfg.nixPath; };
797     environment.extraInit =
798       ''
799         if [ -e "$HOME/.nix-defexpr/channels" ]; then
800           export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
801         fi
802       '';
804     nix.nrBuildUsers = mkDefault (max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs));
806     users.users = nixbldUsers;
808     services.xserver.displayManager.hiddenUsers = attrNames nixbldUsers;
810     system.activationScripts.nix = stringAfter [ "etc" "users" ]
811       ''
812         install -m 0755 -d /nix/var/nix/{gcroots,profiles}/per-user
814         # Subscribe the root user to the NixOS channel by default.
815         if [ ! -e "/root/.nix-channels" ]; then
816             echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels"
817         fi
818       '';
820     # Legacy configuration conversion.
821     nix.settings = mkMerge [
822       {
823         trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
824         substituters = mkAfter [ "https://cache.nixos.org/" ];
826         system-features = mkDefault (
827           [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
828           optionals (pkgs.hostPlatform ? gcc.arch) (
829             # a builder can run code for `gcc.arch` and inferior architectures
830             [ "gccarch-${pkgs.hostPlatform.gcc.arch}" ] ++
831             map (x: "gccarch-${x}") systems.architectures.inferiors.${pkgs.hostPlatform.gcc.arch}
832           )
833         );
834       }
836       (mkIf (!cfg.distributedBuilds) { builders = null; })
838       (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
839     ];
841   };