vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / system / nix-daemon.nix
blobadadce4f88d6d5f497cce6b41640072c9153f50f
1 /*
2   Declares what makes the nix-daemon work on systemd.
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, ... }:
10 with lib;
12 let
14   cfg = config.nix;
16   nixPackage = cfg.package.out;
18   isNixAtLeast = versionAtLeast (getVersion nixPackage);
20   makeNixBuildUser = nr: {
21     name = "nixbld${toString nr}";
22     value = {
23       description = "Nix build user ${toString nr}";
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   };
37   nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
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   ];
48   ###### interface
50   options = {
52     nix = {
54       enable = mkOption {
55         type = types.bool;
56         default = true;
57         description = ''
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       };
63       package = mkOption {
64         type = types.package;
65         default = pkgs.nix;
66         defaultText = literalExpression "pkgs.nix";
67         description = ''
68           This option specifies the Nix package instance to use throughout the system.
69         '';
70       };
72       daemonCPUSchedPolicy = mkOption {
73         type = types.enum [ "other" "batch" "idle" ];
74         default = "other";
75         example = "batch";
76         description = ''
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.
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.
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.
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       };
102       daemonIOSchedClass = mkOption {
103         type = types.enum [ "best-effort" "idle" ];
104         default = "best-effort";
105         example = "idle";
106         description = ''
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.
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.
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       };
125       daemonIOSchedPriority = mkOption {
126         type = types.int;
127         default = 4;
128         example = 1;
129         description = ''
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       };
138       # Environment variables for running Nix.
139       envVars = mkOption {
140         type = types.attrs;
141         internal = true;
142         default = { };
143         description = "Environment variables used by Nix.";
144       };
146       nrBuildUsers = mkOption {
147         type = types.int;
148         description = ''
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   };
159   ###### implementation
161   config = mkIf cfg.enable {
162     environment.systemPackages =
163       [
164         nixPackage
165         pkgs.nix-info
166       ]
167       ++ optional (config.programs.bash.completion.enable) pkgs.nix-bash-completions;
169     systemd.packages = [ nixPackage ];
171     systemd.tmpfiles = mkMerge [
172       (mkIf (isNixAtLeast "2.8") {
173         packages = [ nixPackage ];
174       })
175       (mkIf (!isNixAtLeast "2.8") {
176         rules = [
177           "d /nix/var/nix/daemon-socket 0755 root root - -"
178         ];
179       })
180     ];
182     systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
184     systemd.services.nix-daemon =
185       {
186         path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
187           ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
189         environment = cfg.envVars
190           // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
191           // config.networking.proxy.envVars;
193         unitConfig.RequiresMountsFor = "/nix/store";
195         serviceConfig =
196           {
197             CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
198             IOSchedulingClass = cfg.daemonIOSchedClass;
199             IOSchedulingPriority = cfg.daemonIOSchedPriority;
200             LimitNOFILE = 1048576;
201             Delegate = "yes";
202           };
204         restartTriggers = [ config.environment.etc."nix/nix.conf".source ];
206         # `stopIfChanged = false` changes to switch behavior
207         # from   stop -> update units -> start
208         #   to   update units -> restart
209         #
210         # The `stopIfChanged` setting therefore controls a trade-off between a
211         # more predictable lifecycle, which runs the correct "version" of
212         # the `ExecStop` line, and on the other hand the availability of
213         # sockets during the switch, as the effectiveness of the stop operation
214         # depends on the socket being stopped as well.
215         #
216         # As `nix-daemon.service` does not make use of `ExecStop`, we prefer
217         # to keep the socket up and available. This is important for machines
218         # that run Nix-based services, such as automated build, test, and deploy
219         # services, that expect the daemon socket to be available at all times.
220         #
221         # Notably, the Nix client does not retry on failure to connect to the
222         # daemon socket, and the in-process RemoteStore instance will disable
223         # itself. This makes retries infeasible even for services that are
224         # aware of the issue. Failure to connect can affect not only new client
225         # processes, but also new RemoteStore instances in existing processes,
226         # as well as existing RemoteStore instances that have not saturated
227         # their connection pool.
228         #
229         # Also note that `stopIfChanged = true` does not kill existing
230         # connection handling daemons, as one might wish to happen before a
231         # breaking Nix upgrade (which is rare). The daemon forks that handle
232         # the individual connections split off into their own sessions, causing
233         # them not to be stopped by systemd.
234         # If a Nix upgrade does require all existing daemon processes to stop,
235         # nix-daemon must do so on its own accord, and only when the new version
236         # starts and detects that Nix's persistent state needs an upgrade.
237         stopIfChanged = false;
239       };
241     # Set up the environment variables for running Nix.
242     environment.sessionVariables = cfg.envVars;
244     nix.nrBuildUsers = mkDefault (
245       if cfg.settings.auto-allocate-uids or false then 0
246       else max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)
247     );
249     users.users = nixbldUsers;
251     services.displayManager.hiddenUsers = attrNames nixbldUsers;
253     # Legacy configuration conversion.
254     nix.settings = mkMerge [
255       (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
256     ];
258   };