grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / config / nix.nix
blob9505c60d4f6307322bd26937016573a3eeb4259b
1 /*
2   Manages /etc/nix/nix.conf.
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, ... }:
12 let
13   inherit (lib)
14     concatStringsSep
15     boolToString
16     escape
17     filterAttrs
18     floatToString
19     getVersion
20     hasPrefix
21     isBool
22     isDerivation
23     isFloat
24     isInt
25     isList
26     isString
27     literalExpression
28     mapAttrsToList
29     mkAfter
30     mkDefault
31     mkIf
32     mkOption
33     mkRenamedOptionModuleWith
34     optionalString
35     optionals
36     strings
37     systems
38     toPretty
39     types
40     versionAtLeast
41     ;
43   cfg = config.nix;
45   nixPackage = cfg.package.out;
47   isNixAtLeast = versionAtLeast (getVersion nixPackage);
49   legacyConfMappings = {
50     useSandbox = "sandbox";
51     buildCores = "cores";
52     maxJobs = "max-jobs";
53     sandboxPaths = "extra-sandbox-paths";
54     binaryCaches = "substituters";
55     trustedBinaryCaches = "trusted-substituters";
56     binaryCachePublicKeys = "trusted-public-keys";
57     autoOptimiseStore = "auto-optimise-store";
58     requireSignedBinaryCaches = "require-sigs";
59     trustedUsers = "trusted-users";
60     allowedUsers = "allowed-users";
61     systemFeatures = "system-features";
62   };
64   semanticConfType = with types;
65     let
66       confAtom = nullOr
67         (oneOf [
68           bool
69           int
70           float
71           str
72           path
73           package
74         ]) // {
75         description = "Nix config atom (null, bool, int, float, str, path or package)";
76       };
77     in
78     attrsOf (either confAtom (listOf confAtom));
80   nixConf =
81     assert isNixAtLeast "2.2";
82     let
84       mkValueString = v:
85         if v == null then ""
86         else if isInt v then toString v
87         else if isBool v then boolToString v
88         else if isFloat v then floatToString v
89         else if isList v then toString v
90         else if isDerivation v then toString v
91         else if builtins.isPath v then toString v
92         else if isString v then v
93         else if strings.isConvertibleWithToString v then toString v
94         else abort "The nix conf value: ${toPretty {} v} can not be encoded";
96       mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
98       mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
100       isExtra = key: hasPrefix "extra-" key;
102     in
103     pkgs.writeTextFile {
104       name = "nix.conf";
105       # workaround for https://github.com/NixOS/nix/issues/9487
106       # extra-* settings must come after their non-extra counterpart
107       text = ''
108         # WARNING: this file is generated from the nix.* options in
109         # your NixOS configuration, typically
110         # /etc/nixos/configuration.nix.  Do not edit it!
111         ${mkKeyValuePairs (filterAttrs (key: value: !(isExtra key)) cfg.settings)}
112         ${mkKeyValuePairs (filterAttrs (key: value: isExtra key) cfg.settings)}
113         ${cfg.extraOptions}
114       '';
115       checkPhase = lib.optionalString cfg.checkConfig (
116         if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
117           echo "Ignoring validation for cross-compilation"
118         ''
119         else
120         let
121           showCommand = if isNixAtLeast "2.20pre" then "config show" else "show-config";
122         in
123         ''
124           echo "Validating generated nix.conf"
125           ln -s $out ./nix.conf
126           set -e
127           set +o pipefail
128           NIX_CONF_DIR=$PWD \
129             ${cfg.package}/bin/nix ${showCommand} ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
130               ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
131             |& sed -e 's/^warning:/error:/' \
132             | (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
133           set -o pipefail
134         '');
135     };
139   imports = [
140     (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; })
141     (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; })
142   ] ++
143     mapAttrsToList
144       (oldConf: newConf:
145         mkRenamedOptionModuleWith {
146           sinceRelease = 2205;
147           from = [ "nix" oldConf ];
148           to = [ "nix" "settings" newConf ];
149       })
150       legacyConfMappings;
152   options = {
153     nix = {
154       checkConfig = mkOption {
155         type = types.bool;
156         default = true;
157         description = ''
158           If enabled, checks that Nix can parse the generated nix.conf.
159         '';
160       };
162       checkAllErrors = mkOption {
163         type = types.bool;
164         default = true;
165         description = ''
166           If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings.
167         '';
168       };
170       extraOptions = mkOption {
171         type = types.lines;
172         default = "";
173         example = ''
174           keep-outputs = true
175           keep-derivations = true
176         '';
177         description = "Additional text appended to {file}`nix.conf`.";
178       };
180       settings = mkOption {
181         type = types.submodule {
182           freeformType = semanticConfType;
184           options = {
185             max-jobs = mkOption {
186               type = types.either types.int (types.enum [ "auto" ]);
187               default = "auto";
188               example = 64;
189               description = ''
190                 This option defines the maximum number of jobs that Nix will try to
191                 build in parallel. The default is auto, which means it will use all
192                 available logical cores. It is recommend to set it to the total
193                 number of logical cores in your system (e.g., 16 for two CPUs with 4
194                 cores each and hyper-threading).
195               '';
196             };
198             auto-optimise-store = mkOption {
199               type = types.bool;
200               default = false;
201               example = true;
202               description = ''
203                 If set to true, Nix automatically detects files in the store that have
204                 identical contents, and replaces them with hard links to a single copy.
205                 This saves disk space. If set to false (the default), you can still run
206                 nix-store --optimise to get rid of duplicate files.
207               '';
208             };
210             cores = mkOption {
211               type = types.int;
212               default = 0;
213               example = 64;
214               description = ''
215                 This option defines the maximum number of concurrent tasks during
216                 one build. It affects, e.g., -j option for make.
217                 The special value 0 means that the builder should use all
218                 available CPU cores in the system. Some builds may become
219                 non-deterministic with this option; use with care! Packages will
220                 only be affected if enableParallelBuilding is set for them.
221               '';
222             };
224             sandbox = mkOption {
225               type = types.either types.bool (types.enum [ "relaxed" ]);
226               default = true;
227               description = ''
228                 If set, Nix will perform builds in a sandboxed environment that it
229                 will set up automatically for each build. This prevents impurities
230                 in builds by disallowing access to dependencies outside of the Nix
231                 store by using network and mount namespaces in a chroot environment.
233                 This is enabled by default even though it has a possible performance
234                 impact due to the initial setup time of a sandbox for each build. It
235                 doesn't affect derivation hashes, so changing this option will not
236                 trigger a rebuild of packages.
238                 When set to "relaxed", this option permits derivations that set
239                 `__noChroot = true;` to run outside of the sandboxed environment.
240                 Exercise caution when using this mode of operation! It is intended to
241                 be a quick hack when building with packages that are not easily setup
242                 to be built reproducibly.
243               '';
244             };
246             extra-sandbox-paths = mkOption {
247               type = types.listOf types.str;
248               default = [ ];
249               example = [ "/dev" "/proc" ];
250               description = ''
251                 Directories from the host filesystem to be included
252                 in the sandbox.
253               '';
254             };
256             substituters = mkOption {
257               type = types.listOf types.str;
258               description = ''
259                 List of binary cache URLs used to obtain pre-built binaries
260                 of Nix packages.
262                 By default https://cache.nixos.org/ is added.
263               '';
264             };
266             trusted-substituters = mkOption {
267               type = types.listOf types.str;
268               default = [ ];
269               example = [ "https://hydra.nixos.org/" ];
270               description = ''
271                 List of binary cache URLs that non-root users can use (in
272                 addition to those specified using
273                 {option}`nix.settings.substituters`) by passing
274                 `--option binary-caches` to Nix commands.
275               '';
276             };
278             require-sigs = mkOption {
279               type = types.bool;
280               default = true;
281               description = ''
282                 If enabled (the default), Nix will only download binaries from binary caches if
283                 they are cryptographically signed with any of the keys listed in
284                 {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither
285                 required nor checked, so it's strongly recommended that you use only
286                 trustworthy caches and https to prevent man-in-the-middle attacks.
287               '';
288             };
290             trusted-public-keys = mkOption {
291               type = types.listOf types.str;
292               example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
293               description = ''
294                 List of public keys used to sign binary caches. If
295                 {option}`nix.settings.trusted-public-keys` is enabled,
296                 then Nix will use a binary from a binary cache if and only
297                 if it is signed by *any* of the keys
298                 listed here. By default, only the key for
299                 `cache.nixos.org` is included.
300               '';
301             };
303             trusted-users = mkOption {
304               type = types.listOf types.str;
305               example = [ "root" "alice" "@wheel" ];
306               description = ''
307                 A list of names of users that have additional rights when
308                 connecting to the Nix daemon, such as the ability to specify
309                 additional binary caches, or to import unsigned NARs. You
310                 can also specify groups by prefixing them with
311                 `@`; for instance,
312                 `@wheel` means all users in the wheel
313                 group.
314               '';
315             };
317             system-features = mkOption {
318               type = types.listOf types.str;
319               example = [ "kvm" "big-parallel" "gccarch-skylake" ];
320               description = ''
321                 The set of features supported by the machine. Derivations
322                 can express dependencies on system features through the
323                 `requiredSystemFeatures` attribute.
325                 By default, pseudo-features `nixos-test`, `benchmark`,
326                 and `big-parallel` used in Nixpkgs are set, `kvm`
327                 is also included if it is available.
328               '';
329             };
331             allowed-users = mkOption {
332               type = types.listOf types.str;
333               default = [ "*" ];
334               example = [ "@wheel" "@builders" "alice" "bob" ];
335               description = ''
336                 A list of names of users (separated by whitespace) that are
337                 allowed to connect to the Nix daemon. As with
338                 {option}`nix.settings.trusted-users`, you can specify groups by
339                 prefixing them with `@`. Also, you can
340                 allow all users by specifying `*`. The
341                 default is `*`. Note that trusted users are
342                 always allowed to connect.
343               '';
344             };
345           };
346         };
347         default = { };
348         example = literalExpression ''
349           {
350             use-sandbox = true;
351             show-trace = true;
353             system-features = [ "big-parallel" "kvm" "recursive-nix" ];
354             sandbox-paths = [ "/bin/sh=''${pkgs.busybox-sandbox-shell.out}/bin/busybox" ];
355           }
356         '';
357         description = ''
358           Configuration for Nix, see
359           <https://nixos.org/manual/nix/stable/command-ref/conf-file.html> or
360           {manpage}`nix.conf(5)` for available options.
361           The value declared here will be translated directly to the key-value pairs Nix expects.
363           You can use {command}`nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings`
364           to view the current value. By default it is empty.
366           Nix configurations defined under {option}`nix.*` will be translated and applied to this
367           option. In addition, configuration specified in {option}`nix.extraOptions` will be appended
368           verbatim to the resulting config file.
369         '';
370       };
371     };
372   };
374   config = mkIf cfg.enable {
375     environment.etc."nix/nix.conf".source = nixConf;
376     nix.settings = {
377       trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
378       trusted-users = [ "root" ];
379       substituters = mkAfter [ "https://cache.nixos.org/" ];
380       system-features = mkDefault (
381         [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
382         optionals (pkgs.stdenv.hostPlatform ? gcc.arch) (
383           # a builder can run code for `gcc.arch` and inferior architectures
384           [ "gccarch-${pkgs.stdenv.hostPlatform.gcc.arch}" ] ++
385           map (x: "gccarch-${x}") (systems.architectures.inferiors.${pkgs.stdenv.hostPlatform.gcc.arch} or [])
386         )
387       );
388     };
389   };