···11+/*
22+ Manages the things that are needed for a traditional nix-channel based
33+ configuration to work.
44+55+ See also
66+ - ./nix.nix
77+ - ./nix-flakes.nix
88+ */
99+{ config, lib, ... }:
1010+let
1111+ inherit (lib)
1212+ mkIf
1313+ mkOption
1414+ stringAfter
1515+ types
1616+ ;
1717+1818+ cfg = config.nix;
1919+2020+in
2121+{
2222+ options = {
2323+ nix = {
2424+ nixPath = mkOption {
2525+ type = types.listOf types.str;
2626+ default = [
2727+ "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
2828+ "nixos-config=/etc/nixos/configuration.nix"
2929+ "/nix/var/nix/profiles/per-user/root/channels"
3030+ ];
3131+ description = lib.mdDoc ''
3232+ The default Nix expression search path, used by the Nix
3333+ evaluator to look up paths enclosed in angle brackets
3434+ (e.g. `<nixpkgs>`).
3535+ '';
3636+ };
3737+ };
3838+3939+ system = {
4040+ defaultChannel = mkOption {
4141+ internal = true;
4242+ type = types.str;
4343+ default = "https://nixos.org/channels/nixos-unstable";
4444+ description = lib.mdDoc "Default NixOS channel to which the root user is subscribed.";
4545+ };
4646+ };
4747+ };
4848+4949+ config = mkIf cfg.enable {
5050+5151+ environment.extraInit =
5252+ ''
5353+ if [ -e "$HOME/.nix-defexpr/channels" ]; then
5454+ export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
5555+ fi
5656+ '';
5757+5858+ environment.sessionVariables = {
5959+ NIX_PATH = cfg.nixPath;
6060+ };
6161+6262+ system.activationScripts.nix-channel = stringAfter [ "etc" "users" ]
6363+ ''
6464+ # Subscribe the root user to the NixOS channel by default.
6565+ if [ ! -e "/root/.nix-channels" ]; then
6666+ echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels"
6767+ fi
6868+ '';
6969+ };
7070+}
+95
nixos/modules/config/nix-flakes.nix
···11+/*
22+ Manages the flake registry.
33+44+ See also
55+ - ./nix.nix
66+ - ./nix-channel.nix
77+ */
88+{ config, lib, ... }:
99+let
1010+ inherit (lib)
1111+ filterAttrs
1212+ literalExpression
1313+ mapAttrsToList
1414+ mkDefault
1515+ mkIf
1616+ mkOption
1717+ types
1818+ ;
1919+2020+ cfg = config.nix;
2121+2222+in
2323+{
2424+ options = {
2525+ nix = {
2626+ registry = mkOption {
2727+ type = types.attrsOf (types.submodule (
2828+ let
2929+ referenceAttrs = with types; attrsOf (oneOf [
3030+ str
3131+ int
3232+ bool
3333+ path
3434+ package
3535+ ]);
3636+ in
3737+ { config, name, ... }:
3838+ {
3939+ options = {
4040+ from = mkOption {
4141+ type = referenceAttrs;
4242+ example = { type = "indirect"; id = "nixpkgs"; };
4343+ description = lib.mdDoc "The flake reference to be rewritten.";
4444+ };
4545+ to = mkOption {
4646+ type = referenceAttrs;
4747+ example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; };
4848+ description = lib.mdDoc "The flake reference {option}`from` is rewritten to.";
4949+ };
5050+ flake = mkOption {
5151+ type = types.nullOr types.attrs;
5252+ default = null;
5353+ example = literalExpression "nixpkgs";
5454+ description = lib.mdDoc ''
5555+ The flake input {option}`from` is rewritten to.
5656+ '';
5757+ };
5858+ exact = mkOption {
5959+ type = types.bool;
6060+ default = true;
6161+ description = lib.mdDoc ''
6262+ Whether the {option}`from` reference needs to match exactly. If set,
6363+ a {option}`from` reference like `nixpkgs` does not
6464+ match with a reference like `nixpkgs/nixos-20.03`.
6565+ '';
6666+ };
6767+ };
6868+ config = {
6969+ from = mkDefault { type = "indirect"; id = name; };
7070+ to = mkIf (config.flake != null) (mkDefault (
7171+ {
7272+ type = "path";
7373+ path = config.flake.outPath;
7474+ } // filterAttrs
7575+ (n: _: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash")
7676+ config.flake
7777+ ));
7878+ };
7979+ }
8080+ ));
8181+ default = { };
8282+ description = lib.mdDoc ''
8383+ A system-wide flake registry.
8484+ '';
8585+ };
8686+ };
8787+ };
8888+8989+ config = mkIf cfg.enable {
9090+ environment.etc."nix/registry.json".text = builtins.toJSON {
9191+ version = 2;
9292+ flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
9393+ };
9494+ };
9595+}
+230
nixos/modules/config/nix-remote-build.nix
···11+/*
22+ Manages the remote build configuration, /etc/nix/machines
33+44+ See also
55+ - ./nix.nix
66+ - nixos/modules/services/system/nix-daemon.nix
77+ */
88+{ config, lib, ... }:
99+1010+let
1111+ inherit (lib)
1212+ any
1313+ concatMapStrings
1414+ concatStringsSep
1515+ filter
1616+ getVersion
1717+ mkIf
1818+ mkMerge
1919+ mkOption
2020+ optional
2121+ optionalString
2222+ types
2323+ versionAtLeast
2424+ ;
2525+2626+ cfg = config.nix;
2727+2828+ nixPackage = cfg.package.out;
2929+3030+ isNixAtLeast = versionAtLeast (getVersion nixPackage);
3131+3232+ buildMachinesText =
3333+ concatMapStrings
3434+ (machine:
3535+ (concatStringsSep " " ([
3636+ "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
3737+ (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
3838+ (if machine.sshKey != null then machine.sshKey else "-")
3939+ (toString machine.maxJobs)
4040+ (toString machine.speedFactor)
4141+ (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures);
4242+ in if (res == []) then "-" else (concatStringsSep "," res))
4343+ (let res = machine.mandatoryFeatures;
4444+ in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures))
4545+ ]
4646+ ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
4747+ + "\n"
4848+ )
4949+ cfg.buildMachines;
5050+5151+in
5252+{
5353+ imports = [
5454+ ./nix.nix
5555+ ];
5656+5757+ options = {
5858+ nix = {
5959+ buildMachines = mkOption {
6060+ type = types.listOf (types.submodule {
6161+ options = {
6262+ hostName = mkOption {
6363+ type = types.str;
6464+ example = "nixbuilder.example.org";
6565+ description = lib.mdDoc ''
6666+ The hostname of the build machine.
6767+ '';
6868+ };
6969+ protocol = mkOption {
7070+ type = types.enum [ null "ssh" "ssh-ng" ];
7171+ default = "ssh";
7272+ example = "ssh-ng";
7373+ description = lib.mdDoc ''
7474+ The protocol used for communicating with the build machine.
7575+ Use `ssh-ng` if your remote builder and your
7676+ local Nix version support that improved protocol.
7777+7878+ Use `null` when trying to change the special localhost builder
7979+ without a protocol which is for example used by hydra.
8080+ '';
8181+ };
8282+ system = mkOption {
8383+ type = types.nullOr types.str;
8484+ default = null;
8585+ example = "x86_64-linux";
8686+ description = lib.mdDoc ''
8787+ The system type the build machine can execute derivations on.
8888+ Either this attribute or {var}`systems` must be
8989+ present, where {var}`system` takes precedence if
9090+ both are set.
9191+ '';
9292+ };
9393+ systems = mkOption {
9494+ type = types.listOf types.str;
9595+ default = [ ];
9696+ example = [ "x86_64-linux" "aarch64-linux" ];
9797+ description = lib.mdDoc ''
9898+ The system types the build machine can execute derivations on.
9999+ Either this attribute or {var}`system` must be
100100+ present, where {var}`system` takes precedence if
101101+ both are set.
102102+ '';
103103+ };
104104+ sshUser = mkOption {
105105+ type = types.nullOr types.str;
106106+ default = null;
107107+ example = "builder";
108108+ description = lib.mdDoc ''
109109+ The username to log in as on the remote host. This user must be
110110+ able to log in and run nix commands non-interactively. It must
111111+ also be privileged to build derivations, so must be included in
112112+ {option}`nix.settings.trusted-users`.
113113+ '';
114114+ };
115115+ sshKey = mkOption {
116116+ type = types.nullOr types.str;
117117+ default = null;
118118+ example = "/root/.ssh/id_buildhost_builduser";
119119+ description = lib.mdDoc ''
120120+ The path to the SSH private key with which to authenticate on
121121+ the build machine. The private key must not have a passphrase.
122122+ If null, the building user (root on NixOS machines) must have an
123123+ appropriate ssh configuration to log in non-interactively.
124124+125125+ Note that for security reasons, this path must point to a file
126126+ in the local filesystem, *not* to the nix store.
127127+ '';
128128+ };
129129+ maxJobs = mkOption {
130130+ type = types.int;
131131+ default = 1;
132132+ description = lib.mdDoc ''
133133+ The number of concurrent jobs the build machine supports. The
134134+ build machine will enforce its own limits, but this allows hydra
135135+ to schedule better since there is no work-stealing between build
136136+ machines.
137137+ '';
138138+ };
139139+ speedFactor = mkOption {
140140+ type = types.int;
141141+ default = 1;
142142+ description = lib.mdDoc ''
143143+ The relative speed of this builder. This is an arbitrary integer
144144+ that indicates the speed of this builder, relative to other
145145+ builders. Higher is faster.
146146+ '';
147147+ };
148148+ mandatoryFeatures = mkOption {
149149+ type = types.listOf types.str;
150150+ default = [ ];
151151+ example = [ "big-parallel" ];
152152+ description = lib.mdDoc ''
153153+ A list of features mandatory for this builder. The builder will
154154+ be ignored for derivations that don't require all features in
155155+ this list. All mandatory features are automatically included in
156156+ {var}`supportedFeatures`.
157157+ '';
158158+ };
159159+ supportedFeatures = mkOption {
160160+ type = types.listOf types.str;
161161+ default = [ ];
162162+ example = [ "kvm" "big-parallel" ];
163163+ description = lib.mdDoc ''
164164+ A list of features supported by this builder. The builder will
165165+ be ignored for derivations that require features not in this
166166+ list.
167167+ '';
168168+ };
169169+ publicHostKey = mkOption {
170170+ type = types.nullOr types.str;
171171+ default = null;
172172+ description = lib.mdDoc ''
173173+ The (base64-encoded) public host key of this builder. The field
174174+ is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`.
175175+ If null, SSH will use its regular known-hosts file when connecting.
176176+ '';
177177+ };
178178+ };
179179+ });
180180+ default = [ ];
181181+ description = lib.mdDoc ''
182182+ This option lists the machines to be used if distributed builds are
183183+ enabled (see {option}`nix.distributedBuilds`).
184184+ Nix will perform derivations on those machines via SSH by copying the
185185+ inputs to the Nix store on the remote machine, starting the build,
186186+ then copying the output back to the local Nix store.
187187+ '';
188188+ };
189189+190190+ distributedBuilds = mkOption {
191191+ type = types.bool;
192192+ default = false;
193193+ description = lib.mdDoc ''
194194+ Whether to distribute builds to the machines listed in
195195+ {option}`nix.buildMachines`.
196196+ '';
197197+ };
198198+ };
199199+ };
200200+201201+ # distributedBuilds does *not* inhibit /etc/machines generation; caller may
202202+ # override that nix option.
203203+ config = mkIf cfg.enable {
204204+ assertions =
205205+ let badMachine = m: m.system == null && m.systems == [ ];
206206+ in
207207+ [
208208+ {
209209+ assertion = !(any badMachine cfg.buildMachines);
210210+ message = ''
211211+ At least one system type (via <varname>system</varname> or
212212+ <varname>systems</varname>) must be set for every build machine.
213213+ Invalid machine specifications:
214214+ '' + " " +
215215+ (concatStringsSep "\n "
216216+ (map (m: m.hostName)
217217+ (filter (badMachine) cfg.buildMachines)));
218218+ }
219219+ ];
220220+221221+ # List of machines for distributed Nix builds
222222+ environment.etc."nix/machines" =
223223+ mkIf (cfg.buildMachines != [ ]) {
224224+ text = buildMachinesText;
225225+ };
226226+227227+ # Legacy configuration conversion.
228228+ nix.settings = mkIf (!cfg.distributedBuilds) { builders = null; };
229229+ };
230230+}
+379
nixos/modules/config/nix.nix
···11+/*
22+ Manages /etc/nix.conf.
33+44+ See also
55+ - ./nix-channel.nix
66+ - ./nix-flakes.nix
77+ - ./nix-remote-build.nix
88+ - nixos/modules/services/system/nix-daemon.nix
99+ */
1010+{ config, lib, pkgs, ... }:
1111+1212+let
1313+ inherit (lib)
1414+ concatStringsSep
1515+ boolToString
1616+ escape
1717+ floatToString
1818+ getVersion
1919+ isBool
2020+ isDerivation
2121+ isFloat
2222+ isInt
2323+ isList
2424+ isString
2525+ literalExpression
2626+ mapAttrsToList
2727+ mkAfter
2828+ mkDefault
2929+ mkIf
3030+ mkOption
3131+ mkRenamedOptionModuleWith
3232+ optionalString
3333+ optionals
3434+ strings
3535+ systems
3636+ toPretty
3737+ types
3838+ versionAtLeast
3939+ ;
4040+4141+ cfg = config.nix;
4242+4343+ nixPackage = cfg.package.out;
4444+4545+ isNixAtLeast = versionAtLeast (getVersion nixPackage);
4646+4747+ legacyConfMappings = {
4848+ useSandbox = "sandbox";
4949+ buildCores = "cores";
5050+ maxJobs = "max-jobs";
5151+ sandboxPaths = "extra-sandbox-paths";
5252+ binaryCaches = "substituters";
5353+ trustedBinaryCaches = "trusted-substituters";
5454+ binaryCachePublicKeys = "trusted-public-keys";
5555+ autoOptimiseStore = "auto-optimise-store";
5656+ requireSignedBinaryCaches = "require-sigs";
5757+ trustedUsers = "trusted-users";
5858+ allowedUsers = "allowed-users";
5959+ systemFeatures = "system-features";
6060+ };
6161+6262+ semanticConfType = with types;
6363+ let
6464+ confAtom = nullOr
6565+ (oneOf [
6666+ bool
6767+ int
6868+ float
6969+ str
7070+ path
7171+ package
7272+ ]) // {
7373+ description = "Nix config atom (null, bool, int, float, str, path or package)";
7474+ };
7575+ in
7676+ attrsOf (either confAtom (listOf confAtom));
7777+7878+ nixConf =
7979+ assert isNixAtLeast "2.2";
8080+ let
8181+8282+ mkValueString = v:
8383+ if v == null then ""
8484+ else if isInt v then toString v
8585+ else if isBool v then boolToString v
8686+ else if isFloat v then floatToString v
8787+ else if isList v then toString v
8888+ else if isDerivation v then toString v
8989+ else if builtins.isPath v then toString v
9090+ else if isString v then v
9191+ else if strings.isConvertibleWithToString v then toString v
9292+ else abort "The nix conf value: ${toPretty {} v} can not be encoded";
9393+9494+ mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
9595+9696+ mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
9797+9898+ in
9999+ pkgs.writeTextFile {
100100+ name = "nix.conf";
101101+ text = ''
102102+ # WARNING: this file is generated from the nix.* options in
103103+ # your NixOS configuration, typically
104104+ # /etc/nixos/configuration.nix. Do not edit it!
105105+ ${mkKeyValuePairs cfg.settings}
106106+ ${cfg.extraOptions}
107107+ '';
108108+ checkPhase = lib.optionalString cfg.checkConfig (
109109+ if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
110110+ echo "Ignoring validation for cross-compilation"
111111+ ''
112112+ else ''
113113+ echo "Validating generated nix.conf"
114114+ ln -s $out ./nix.conf
115115+ set -e
116116+ set +o pipefail
117117+ NIX_CONF_DIR=$PWD \
118118+ ${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
119119+ ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
120120+ |& sed -e 's/^warning:/error:/' \
121121+ | (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
122122+ set -o pipefail
123123+ '');
124124+ };
125125+126126+in
127127+{
128128+ imports = [
129129+ (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; })
130130+ (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; })
131131+ ] ++
132132+ mapAttrsToList
133133+ (oldConf: newConf:
134134+ mkRenamedOptionModuleWith {
135135+ sinceRelease = 2205;
136136+ from = [ "nix" oldConf ];
137137+ to = [ "nix" "settings" newConf ];
138138+ })
139139+ legacyConfMappings;
140140+141141+ options = {
142142+ nix = {
143143+ checkConfig = mkOption {
144144+ type = types.bool;
145145+ default = true;
146146+ description = lib.mdDoc ''
147147+ If enabled, checks that Nix can parse the generated nix.conf.
148148+ '';
149149+ };
150150+151151+ checkAllErrors = mkOption {
152152+ type = types.bool;
153153+ default = true;
154154+ description = lib.mdDoc ''
155155+ If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings.
156156+ '';
157157+ };
158158+159159+ extraOptions = mkOption {
160160+ type = types.lines;
161161+ default = "";
162162+ example = ''
163163+ keep-outputs = true
164164+ keep-derivations = true
165165+ '';
166166+ description = lib.mdDoc "Additional text appended to {file}`nix.conf`.";
167167+ };
168168+169169+ settings = mkOption {
170170+ type = types.submodule {
171171+ freeformType = semanticConfType;
172172+173173+ options = {
174174+ max-jobs = mkOption {
175175+ type = types.either types.int (types.enum [ "auto" ]);
176176+ default = "auto";
177177+ example = 64;
178178+ description = lib.mdDoc ''
179179+ This option defines the maximum number of jobs that Nix will try to
180180+ build in parallel. The default is auto, which means it will use all
181181+ available logical cores. It is recommend to set it to the total
182182+ number of logical cores in your system (e.g., 16 for two CPUs with 4
183183+ cores each and hyper-threading).
184184+ '';
185185+ };
186186+187187+ auto-optimise-store = mkOption {
188188+ type = types.bool;
189189+ default = false;
190190+ example = true;
191191+ description = lib.mdDoc ''
192192+ If set to true, Nix automatically detects files in the store that have
193193+ identical contents, and replaces them with hard links to a single copy.
194194+ This saves disk space. If set to false (the default), you can still run
195195+ nix-store --optimise to get rid of duplicate files.
196196+ '';
197197+ };
198198+199199+ cores = mkOption {
200200+ type = types.int;
201201+ default = 0;
202202+ example = 64;
203203+ description = lib.mdDoc ''
204204+ This option defines the maximum number of concurrent tasks during
205205+ one build. It affects, e.g., -j option for make.
206206+ The special value 0 means that the builder should use all
207207+ available CPU cores in the system. Some builds may become
208208+ non-deterministic with this option; use with care! Packages will
209209+ only be affected if enableParallelBuilding is set for them.
210210+ '';
211211+ };
212212+213213+ sandbox = mkOption {
214214+ type = types.either types.bool (types.enum [ "relaxed" ]);
215215+ default = true;
216216+ description = lib.mdDoc ''
217217+ If set, Nix will perform builds in a sandboxed environment that it
218218+ will set up automatically for each build. This prevents impurities
219219+ in builds by disallowing access to dependencies outside of the Nix
220220+ store by using network and mount namespaces in a chroot environment.
221221+222222+ This is enabled by default even though it has a possible performance
223223+ impact due to the initial setup time of a sandbox for each build. It
224224+ doesn't affect derivation hashes, so changing this option will not
225225+ trigger a rebuild of packages.
226226+227227+ When set to "relaxed", this option permits derivations that set
228228+ `__noChroot = true;` to run outside of the sandboxed environment.
229229+ Exercise caution when using this mode of operation! It is intended to
230230+ be a quick hack when building with packages that are not easily setup
231231+ to be built reproducibly.
232232+ '';
233233+ };
234234+235235+ extra-sandbox-paths = mkOption {
236236+ type = types.listOf types.str;
237237+ default = [ ];
238238+ example = [ "/dev" "/proc" ];
239239+ description = lib.mdDoc ''
240240+ Directories from the host filesystem to be included
241241+ in the sandbox.
242242+ '';
243243+ };
244244+245245+ substituters = mkOption {
246246+ type = types.listOf types.str;
247247+ description = lib.mdDoc ''
248248+ List of binary cache URLs used to obtain pre-built binaries
249249+ of Nix packages.
250250+251251+ By default https://cache.nixos.org/ is added.
252252+ '';
253253+ };
254254+255255+ trusted-substituters = mkOption {
256256+ type = types.listOf types.str;
257257+ default = [ ];
258258+ example = [ "https://hydra.nixos.org/" ];
259259+ description = lib.mdDoc ''
260260+ List of binary cache URLs that non-root users can use (in
261261+ addition to those specified using
262262+ {option}`nix.settings.substituters`) by passing
263263+ `--option binary-caches` to Nix commands.
264264+ '';
265265+ };
266266+267267+ require-sigs = mkOption {
268268+ type = types.bool;
269269+ default = true;
270270+ description = lib.mdDoc ''
271271+ If enabled (the default), Nix will only download binaries from binary caches if
272272+ they are cryptographically signed with any of the keys listed in
273273+ {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither
274274+ required nor checked, so it's strongly recommended that you use only
275275+ trustworthy caches and https to prevent man-in-the-middle attacks.
276276+ '';
277277+ };
278278+279279+ trusted-public-keys = mkOption {
280280+ type = types.listOf types.str;
281281+ example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
282282+ description = lib.mdDoc ''
283283+ List of public keys used to sign binary caches. If
284284+ {option}`nix.settings.trusted-public-keys` is enabled,
285285+ then Nix will use a binary from a binary cache if and only
286286+ if it is signed by *any* of the keys
287287+ listed here. By default, only the key for
288288+ `cache.nixos.org` is included.
289289+ '';
290290+ };
291291+292292+ trusted-users = mkOption {
293293+ type = types.listOf types.str;
294294+ default = [ "root" ];
295295+ example = [ "root" "alice" "@wheel" ];
296296+ description = lib.mdDoc ''
297297+ A list of names of users that have additional rights when
298298+ connecting to the Nix daemon, such as the ability to specify
299299+ additional binary caches, or to import unsigned NARs. You
300300+ can also specify groups by prefixing them with
301301+ `@`; for instance,
302302+ `@wheel` means all users in the wheel
303303+ group.
304304+ '';
305305+ };
306306+307307+ system-features = mkOption {
308308+ type = types.listOf types.str;
309309+ example = [ "kvm" "big-parallel" "gccarch-skylake" ];
310310+ description = lib.mdDoc ''
311311+ The set of features supported by the machine. Derivations
312312+ can express dependencies on system features through the
313313+ `requiredSystemFeatures` attribute.
314314+315315+ By default, pseudo-features `nixos-test`, `benchmark`,
316316+ and `big-parallel` used in Nixpkgs are set, `kvm`
317317+ is also included if it is available.
318318+ '';
319319+ };
320320+321321+ allowed-users = mkOption {
322322+ type = types.listOf types.str;
323323+ default = [ "*" ];
324324+ example = [ "@wheel" "@builders" "alice" "bob" ];
325325+ description = lib.mdDoc ''
326326+ A list of names of users (separated by whitespace) that are
327327+ allowed to connect to the Nix daemon. As with
328328+ {option}`nix.settings.trusted-users`, you can specify groups by
329329+ prefixing them with `@`. Also, you can
330330+ allow all users by specifying `*`. The
331331+ default is `*`. Note that trusted users are
332332+ always allowed to connect.
333333+ '';
334334+ };
335335+ };
336336+ };
337337+ default = { };
338338+ example = literalExpression ''
339339+ {
340340+ use-sandbox = true;
341341+ show-trace = true;
342342+343343+ system-features = [ "big-parallel" "kvm" "recursive-nix" ];
344344+ sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; };
345345+ }
346346+ '';
347347+ description = lib.mdDoc ''
348348+ Configuration for Nix, see
349349+ <https://nixos.org/manual/nix/stable/command-ref/conf-file.html> or
350350+ {manpage}`nix.conf(5)` for available options.
351351+ The value declared here will be translated directly to the key-value pairs Nix expects.
352352+353353+ You can use {command}`nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings`
354354+ to view the current value. By default it is empty.
355355+356356+ Nix configurations defined under {option}`nix.*` will be translated and applied to this
357357+ option. In addition, configuration specified in {option}`nix.extraOptions` will be appended
358358+ verbatim to the resulting config file.
359359+ '';
360360+ };
361361+ };
362362+ };
363363+364364+ config = mkIf cfg.enable {
365365+ environment.etc."nix/nix.conf".source = nixConf;
366366+ nix.settings = {
367367+ trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
368368+ substituters = mkAfter [ "https://cache.nixos.org/" ];
369369+ system-features = mkDefault (
370370+ [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
371371+ optionals (pkgs.stdenv.hostPlatform ? gcc.arch) (
372372+ # a builder can run code for `gcc.arch` and inferior architectures
373373+ [ "gccarch-${pkgs.stdenv.hostPlatform.gcc.arch}" ] ++
374374+ map (x: "gccarch-${x}") (systems.architectures.inferiors.${pkgs.stdenv.hostPlatform.gcc.arch} or [])
375375+ )
376376+ );
377377+ };
378378+ };
379379+}
-7
nixos/modules/misc/version.nix
···140140 '';
141141 };
142142143143- defaultChannel = mkOption {
144144- internal = true;
145145- type = types.str;
146146- default = "https://nixos.org/channels/nixos-unstable";
147147- description = lib.mdDoc "Default NixOS channel to which the root user is subscribed.";
148148- };
149149-150143 configurationRevision = mkOption {
151144 type = types.nullOr types.str;
152145 default = null;
···11-{ config, lib, pkgs, ... }:
22-33-with lib;
44-55-let
66-77- cfg = config.nix;
88-99- nixPackage = cfg.package.out;
1010-1111- isNixAtLeast = versionAtLeast (getVersion nixPackage);
1212-1313- makeNixBuildUser = nr: {
1414- name = "nixbld${toString nr}";
1515- value = {
1616- description = "Nix build user ${toString nr}";
1717-1818- /*
1919- For consistency with the setgid(2), setuid(2), and setgroups(2)
2020- calls in `libstore/build.cc', don't add any supplementary group
2121- here except "nixbld".
2222- */
2323- uid = builtins.add config.ids.uids.nixbld nr;
2424- isSystemUser = true;
2525- group = "nixbld";
2626- extraGroups = [ "nixbld" ];
2727- };
2828- };
2929-3030- nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
3131-3232- nixConf =
3333- assert isNixAtLeast "2.2";
3434- let
3535-3636- mkValueString = v:
3737- if v == null then ""
3838- else if isInt v then toString v
3939- else if isBool v then boolToString v
4040- else if isFloat v then floatToString v
4141- else if isList v then toString v
4242- else if isDerivation v then toString v
4343- else if builtins.isPath v then toString v
4444- else if isString v then v
4545- else if strings.isConvertibleWithToString v then toString v
4646- else abort "The nix conf value: ${toPretty {} v} can not be encoded";
4747-4848- mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
4949-5050- mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
5151-5252- in
5353- pkgs.writeTextFile {
5454- name = "nix.conf";
5555- text = ''
5656- # WARNING: this file is generated from the nix.* options in
5757- # your NixOS configuration, typically
5858- # /etc/nixos/configuration.nix. Do not edit it!
5959- ${mkKeyValuePairs cfg.settings}
6060- ${cfg.extraOptions}
6161- '';
6262- checkPhase = lib.optionalString cfg.checkConfig (
6363- if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
6464- echo "Ignoring validation for cross-compilation"
6565- ''
6666- else ''
6767- echo "Validating generated nix.conf"
6868- ln -s $out ./nix.conf
6969- set -e
7070- set +o pipefail
7171- NIX_CONF_DIR=$PWD \
7272- ${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
7373- ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
7474- |& sed -e 's/^warning:/error:/' \
7575- | (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
7676- set -o pipefail
7777- '');
7878- };
7979-8080- legacyConfMappings = {
8181- useSandbox = "sandbox";
8282- buildCores = "cores";
8383- maxJobs = "max-jobs";
8484- sandboxPaths = "extra-sandbox-paths";
8585- binaryCaches = "substituters";
8686- trustedBinaryCaches = "trusted-substituters";
8787- binaryCachePublicKeys = "trusted-public-keys";
8888- autoOptimiseStore = "auto-optimise-store";
8989- requireSignedBinaryCaches = "require-sigs";
9090- trustedUsers = "trusted-users";
9191- allowedUsers = "allowed-users";
9292- systemFeatures = "system-features";
9393- };
9494-9595- semanticConfType = with types;
9696- let
9797- confAtom = nullOr
9898- (oneOf [
9999- bool
100100- int
101101- float
102102- str
103103- path
104104- package
105105- ]) // {
106106- description = "Nix config atom (null, bool, int, float, str, path or package)";
107107- };
108108- in
109109- attrsOf (either confAtom (listOf confAtom));
110110-111111-in
112112-113113-{
114114- imports = [
115115- (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; })
116116- (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; })
117117- (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; })
118118- (mkRenamedOptionModuleWith { sinceRelease = 2211; from = [ "nix" "readOnlyStore" ]; to = [ "boot" "readOnlyNixStore" ]; })
119119- (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
120120- ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" oldConf ]; to = [ "nix" "settings" newConf ]; }) legacyConfMappings;
121121-122122- ###### interface
123123-124124- options = {
125125-126126- nix = {
127127-128128- enable = mkOption {
129129- type = types.bool;
130130- default = true;
131131- description = lib.mdDoc ''
132132- Whether to enable Nix.
133133- Disabling Nix makes the system hard to modify and the Nix programs and configuration will not be made available by NixOS itself.
134134- '';
135135- };
136136-137137- package = mkOption {
138138- type = types.package;
139139- default = pkgs.nix;
140140- defaultText = literalExpression "pkgs.nix";
141141- description = lib.mdDoc ''
142142- This option specifies the Nix package instance to use throughout the system.
143143- '';
144144- };
145145-146146- distributedBuilds = mkOption {
147147- type = types.bool;
148148- default = false;
149149- description = lib.mdDoc ''
150150- Whether to distribute builds to the machines listed in
151151- {option}`nix.buildMachines`.
152152- '';
153153- };
154154-155155- daemonCPUSchedPolicy = mkOption {
156156- type = types.enum [ "other" "batch" "idle" ];
157157- default = "other";
158158- example = "batch";
159159- description = lib.mdDoc ''
160160- Nix daemon process CPU scheduling policy. This policy propagates to
161161- build processes. `other` is the default scheduling
162162- policy for regular tasks. The `batch` policy is
163163- similar to `other`, but optimised for
164164- non-interactive tasks. `idle` is for extremely
165165- low-priority tasks that should only be run when no other task
166166- requires CPU time.
167167-168168- Please note that while using the `idle` policy may
169169- greatly improve responsiveness of a system performing expensive
170170- builds, it may also slow down and potentially starve crucial
171171- configuration updates during load.
172172-173173- `idle` may therefore be a sensible policy for
174174- systems that experience only intermittent phases of high CPU load,
175175- such as desktop or portable computers used interactively. Other
176176- systems should use the `other` or
177177- `batch` policy instead.
178178-179179- For more fine-grained resource control, please refer to
180180- {manpage}`systemd.resource-control(5)` and adjust
181181- {option}`systemd.services.nix-daemon` directly.
182182- '';
183183- };
184184-185185- daemonIOSchedClass = mkOption {
186186- type = types.enum [ "best-effort" "idle" ];
187187- default = "best-effort";
188188- example = "idle";
189189- description = lib.mdDoc ''
190190- Nix daemon process I/O scheduling class. This class propagates to
191191- build processes. `best-effort` is the default
192192- class for regular tasks. The `idle` class is for
193193- extremely low-priority tasks that should only perform I/O when no
194194- other task does.
195195-196196- Please note that while using the `idle` scheduling
197197- class can improve responsiveness of a system performing expensive
198198- builds, it might also slow down or starve crucial configuration
199199- updates during load.
200200-201201- `idle` may therefore be a sensible class for
202202- systems that experience only intermittent phases of high I/O load,
203203- such as desktop or portable computers used interactively. Other
204204- systems should use the `best-effort` class.
205205- '';
206206- };
207207-208208- daemonIOSchedPriority = mkOption {
209209- type = types.int;
210210- default = 4;
211211- example = 1;
212212- description = lib.mdDoc ''
213213- Nix daemon process I/O scheduling priority. This priority propagates
214214- to build processes. The supported priorities depend on the
215215- scheduling policy: With idle, priorities are not used in scheduling
216216- decisions. best-effort supports values in the range 0 (high) to 7
217217- (low).
218218- '';
219219- };
220220-221221- buildMachines = mkOption {
222222- type = types.listOf (types.submodule {
223223- options = {
224224- hostName = mkOption {
225225- type = types.str;
226226- example = "nixbuilder.example.org";
227227- description = lib.mdDoc ''
228228- The hostname of the build machine.
229229- '';
230230- };
231231- protocol = mkOption {
232232- type = types.enum [ null "ssh" "ssh-ng" ];
233233- default = "ssh";
234234- example = "ssh-ng";
235235- description = lib.mdDoc ''
236236- The protocol used for communicating with the build machine.
237237- Use `ssh-ng` if your remote builder and your
238238- local Nix version support that improved protocol.
239239-240240- Use `null` when trying to change the special localhost builder
241241- without a protocol which is for example used by hydra.
242242- '';
243243- };
244244- system = mkOption {
245245- type = types.nullOr types.str;
246246- default = null;
247247- example = "x86_64-linux";
248248- description = lib.mdDoc ''
249249- The system type the build machine can execute derivations on.
250250- Either this attribute or {var}`systems` must be
251251- present, where {var}`system` takes precedence if
252252- both are set.
253253- '';
254254- };
255255- systems = mkOption {
256256- type = types.listOf types.str;
257257- default = [ ];
258258- example = [ "x86_64-linux" "aarch64-linux" ];
259259- description = lib.mdDoc ''
260260- The system types the build machine can execute derivations on.
261261- Either this attribute or {var}`system` must be
262262- present, where {var}`system` takes precedence if
263263- both are set.
264264- '';
265265- };
266266- sshUser = mkOption {
267267- type = types.nullOr types.str;
268268- default = null;
269269- example = "builder";
270270- description = lib.mdDoc ''
271271- The username to log in as on the remote host. This user must be
272272- able to log in and run nix commands non-interactively. It must
273273- also be privileged to build derivations, so must be included in
274274- {option}`nix.settings.trusted-users`.
275275- '';
276276- };
277277- sshKey = mkOption {
278278- type = types.nullOr types.str;
279279- default = null;
280280- example = "/root/.ssh/id_buildhost_builduser";
281281- description = lib.mdDoc ''
282282- The path to the SSH private key with which to authenticate on
283283- the build machine. The private key must not have a passphrase.
284284- If null, the building user (root on NixOS machines) must have an
285285- appropriate ssh configuration to log in non-interactively.
286286-287287- Note that for security reasons, this path must point to a file
288288- in the local filesystem, *not* to the nix store.
289289- '';
290290- };
291291- maxJobs = mkOption {
292292- type = types.int;
293293- default = 1;
294294- description = lib.mdDoc ''
295295- The number of concurrent jobs the build machine supports. The
296296- build machine will enforce its own limits, but this allows hydra
297297- to schedule better since there is no work-stealing between build
298298- machines.
299299- '';
300300- };
301301- speedFactor = mkOption {
302302- type = types.int;
303303- default = 1;
304304- description = lib.mdDoc ''
305305- The relative speed of this builder. This is an arbitrary integer
306306- that indicates the speed of this builder, relative to other
307307- builders. Higher is faster.
308308- '';
309309- };
310310- mandatoryFeatures = mkOption {
311311- type = types.listOf types.str;
312312- default = [ ];
313313- example = [ "big-parallel" ];
314314- description = lib.mdDoc ''
315315- A list of features mandatory for this builder. The builder will
316316- be ignored for derivations that don't require all features in
317317- this list. All mandatory features are automatically included in
318318- {var}`supportedFeatures`.
319319- '';
320320- };
321321- supportedFeatures = mkOption {
322322- type = types.listOf types.str;
323323- default = [ ];
324324- example = [ "kvm" "big-parallel" ];
325325- description = lib.mdDoc ''
326326- A list of features supported by this builder. The builder will
327327- be ignored for derivations that require features not in this
328328- list.
329329- '';
330330- };
331331- publicHostKey = mkOption {
332332- type = types.nullOr types.str;
333333- default = null;
334334- description = lib.mdDoc ''
335335- The (base64-encoded) public host key of this builder. The field
336336- is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`.
337337- If null, SSH will use its regular known-hosts file when connecting.
338338- '';
339339- };
340340- };
341341- });
342342- default = [ ];
343343- description = lib.mdDoc ''
344344- This option lists the machines to be used if distributed builds are
345345- enabled (see {option}`nix.distributedBuilds`).
346346- Nix will perform derivations on those machines via SSH by copying the
347347- inputs to the Nix store on the remote machine, starting the build,
348348- then copying the output back to the local Nix store.
349349- '';
350350- };
351351-352352- # Environment variables for running Nix.
353353- envVars = mkOption {
354354- type = types.attrs;
355355- internal = true;
356356- default = { };
357357- description = lib.mdDoc "Environment variables used by Nix.";
358358- };
359359-360360- nrBuildUsers = mkOption {
361361- type = types.int;
362362- description = lib.mdDoc ''
363363- Number of `nixbld` user accounts created to
364364- perform secure concurrent builds. If you receive an error
365365- message saying that “all build users are currently in use”,
366366- you should increase this value.
367367- '';
368368- };
369369-370370- nixPath = mkOption {
371371- type = types.listOf types.str;
372372- default = [
373373- "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
374374- "nixos-config=/etc/nixos/configuration.nix"
375375- "/nix/var/nix/profiles/per-user/root/channels"
376376- ];
377377- description = lib.mdDoc ''
378378- The default Nix expression search path, used by the Nix
379379- evaluator to look up paths enclosed in angle brackets
380380- (e.g. `<nixpkgs>`).
381381- '';
382382- };
383383-384384- checkConfig = mkOption {
385385- type = types.bool;
386386- default = true;
387387- description = lib.mdDoc ''
388388- If enabled, checks that Nix can parse the generated nix.conf.
389389- '';
390390- };
391391-392392- checkAllErrors = mkOption {
393393- type = types.bool;
394394- default = true;
395395- description = lib.mdDoc ''
396396- If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings.
397397- '';
398398- };
399399-400400- registry = mkOption {
401401- type = types.attrsOf (types.submodule (
402402- let
403403- referenceAttrs = with types; attrsOf (oneOf [
404404- str
405405- int
406406- bool
407407- path
408408- package
409409- ]);
410410- in
411411- { config, name, ... }:
412412- {
413413- options = {
414414- from = mkOption {
415415- type = referenceAttrs;
416416- example = { type = "indirect"; id = "nixpkgs"; };
417417- description = lib.mdDoc "The flake reference to be rewritten.";
418418- };
419419- to = mkOption {
420420- type = referenceAttrs;
421421- example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; };
422422- description = lib.mdDoc "The flake reference {option}`from` is rewritten to.";
423423- };
424424- flake = mkOption {
425425- type = types.nullOr types.attrs;
426426- default = null;
427427- example = literalExpression "nixpkgs";
428428- description = lib.mdDoc ''
429429- The flake input {option}`from` is rewritten to.
430430- '';
431431- };
432432- exact = mkOption {
433433- type = types.bool;
434434- default = true;
435435- description = lib.mdDoc ''
436436- Whether the {option}`from` reference needs to match exactly. If set,
437437- a {option}`from` reference like `nixpkgs` does not
438438- match with a reference like `nixpkgs/nixos-20.03`.
439439- '';
440440- };
441441- };
442442- config = {
443443- from = mkDefault { type = "indirect"; id = name; };
444444- to = mkIf (config.flake != null) (mkDefault (
445445- {
446446- type = "path";
447447- path = config.flake.outPath;
448448- } // filterAttrs
449449- (n: _: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash")
450450- config.flake
451451- ));
452452- };
453453- }
454454- ));
455455- default = { };
456456- description = lib.mdDoc ''
457457- A system-wide flake registry.
458458- '';
459459- };
460460-461461- extraOptions = mkOption {
462462- type = types.lines;
463463- default = "";
464464- example = ''
465465- keep-outputs = true
466466- keep-derivations = true
467467- '';
468468- description = lib.mdDoc "Additional text appended to {file}`nix.conf`.";
469469- };
470470-471471- settings = mkOption {
472472- type = types.submodule {
473473- freeformType = semanticConfType;
474474-475475- options = {
476476- max-jobs = mkOption {
477477- type = types.either types.int (types.enum [ "auto" ]);
478478- default = "auto";
479479- example = 64;
480480- description = lib.mdDoc ''
481481- This option defines the maximum number of jobs that Nix will try to
482482- build in parallel. The default is auto, which means it will use all
483483- available logical cores. It is recommend to set it to the total
484484- number of logical cores in your system (e.g., 16 for two CPUs with 4
485485- cores each and hyper-threading).
486486- '';
487487- };
488488-489489- auto-optimise-store = mkOption {
490490- type = types.bool;
491491- default = false;
492492- example = true;
493493- description = lib.mdDoc ''
494494- If set to true, Nix automatically detects files in the store that have
495495- identical contents, and replaces them with hard links to a single copy.
496496- This saves disk space. If set to false (the default), you can still run
497497- nix-store --optimise to get rid of duplicate files.
498498- '';
499499- };
500500-501501- cores = mkOption {
502502- type = types.int;
503503- default = 0;
504504- example = 64;
505505- description = lib.mdDoc ''
506506- This option defines the maximum number of concurrent tasks during
507507- one build. It affects, e.g., -j option for make.
508508- The special value 0 means that the builder should use all
509509- available CPU cores in the system. Some builds may become
510510- non-deterministic with this option; use with care! Packages will
511511- only be affected if enableParallelBuilding is set for them.
512512- '';
513513- };
514514-515515- sandbox = mkOption {
516516- type = types.either types.bool (types.enum [ "relaxed" ]);
517517- default = true;
518518- description = lib.mdDoc ''
519519- If set, Nix will perform builds in a sandboxed environment that it
520520- will set up automatically for each build. This prevents impurities
521521- in builds by disallowing access to dependencies outside of the Nix
522522- store by using network and mount namespaces in a chroot environment.
523523-524524- This is enabled by default even though it has a possible performance
525525- impact due to the initial setup time of a sandbox for each build. It
526526- doesn't affect derivation hashes, so changing this option will not
527527- trigger a rebuild of packages.
528528-529529- When set to "relaxed", this option permits derivations that set
530530- `__noChroot = true;` to run outside of the sandboxed environment.
531531- Exercise caution when using this mode of operation! It is intended to
532532- be a quick hack when building with packages that are not easily setup
533533- to be built reproducibly.
534534- '';
535535- };
536536-537537- extra-sandbox-paths = mkOption {
538538- type = types.listOf types.str;
539539- default = [ ];
540540- example = [ "/dev" "/proc" ];
541541- description = lib.mdDoc ''
542542- Directories from the host filesystem to be included
543543- in the sandbox.
544544- '';
545545- };
546546-547547- substituters = mkOption {
548548- type = types.listOf types.str;
549549- description = lib.mdDoc ''
550550- List of binary cache URLs used to obtain pre-built binaries
551551- of Nix packages.
552552-553553- By default https://cache.nixos.org/ is added.
554554- '';
555555- };
556556-557557- trusted-substituters = mkOption {
558558- type = types.listOf types.str;
559559- default = [ ];
560560- example = [ "https://hydra.nixos.org/" ];
561561- description = lib.mdDoc ''
562562- List of binary cache URLs that non-root users can use (in
563563- addition to those specified using
564564- {option}`nix.settings.substituters`) by passing
565565- `--option binary-caches` to Nix commands.
566566- '';
567567- };
568568-569569- require-sigs = mkOption {
570570- type = types.bool;
571571- default = true;
572572- description = lib.mdDoc ''
573573- If enabled (the default), Nix will only download binaries from binary caches if
574574- they are cryptographically signed with any of the keys listed in
575575- {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither
576576- required nor checked, so it's strongly recommended that you use only
577577- trustworthy caches and https to prevent man-in-the-middle attacks.
578578- '';
579579- };
580580-581581- trusted-public-keys = mkOption {
582582- type = types.listOf types.str;
583583- example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
584584- description = lib.mdDoc ''
585585- List of public keys used to sign binary caches. If
586586- {option}`nix.settings.trusted-public-keys` is enabled,
587587- then Nix will use a binary from a binary cache if and only
588588- if it is signed by *any* of the keys
589589- listed here. By default, only the key for
590590- `cache.nixos.org` is included.
591591- '';
592592- };
593593-594594- trusted-users = mkOption {
595595- type = types.listOf types.str;
596596- default = [ "root" ];
597597- example = [ "root" "alice" "@wheel" ];
598598- description = lib.mdDoc ''
599599- A list of names of users that have additional rights when
600600- connecting to the Nix daemon, such as the ability to specify
601601- additional binary caches, or to import unsigned NARs. You
602602- can also specify groups by prefixing them with
603603- `@`; for instance,
604604- `@wheel` means all users in the wheel
605605- group.
606606- '';
607607- };
608608-609609- system-features = mkOption {
610610- type = types.listOf types.str;
611611- example = [ "kvm" "big-parallel" "gccarch-skylake" ];
612612- description = lib.mdDoc ''
613613- The set of features supported by the machine. Derivations
614614- can express dependencies on system features through the
615615- `requiredSystemFeatures` attribute.
616616-617617- By default, pseudo-features `nixos-test`, `benchmark`,
618618- and `big-parallel` used in Nixpkgs are set, `kvm`
619619- is also included if it is available.
620620- '';
621621- };
622622-623623- allowed-users = mkOption {
624624- type = types.listOf types.str;
625625- default = [ "*" ];
626626- example = [ "@wheel" "@builders" "alice" "bob" ];
627627- description = lib.mdDoc ''
628628- A list of names of users (separated by whitespace) that are
629629- allowed to connect to the Nix daemon. As with
630630- {option}`nix.settings.trusted-users`, you can specify groups by
631631- prefixing them with `@`. Also, you can
632632- allow all users by specifying `*`. The
633633- default is `*`. Note that trusted users are
634634- always allowed to connect.
635635- '';
636636- };
637637- };
638638- };
639639- default = { };
640640- example = literalExpression ''
641641- {
642642- use-sandbox = true;
643643- show-trace = true;
644644-645645- system-features = [ "big-parallel" "kvm" "recursive-nix" ];
646646- sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; };
647647- }
648648- '';
649649- description = lib.mdDoc ''
650650- Configuration for Nix, see
651651- <https://nixos.org/manual/nix/stable/command-ref/conf-file.html> or
652652- {manpage}`nix.conf(5)` for available options.
653653- The value declared here will be translated directly to the key-value pairs Nix expects.
654654-655655- You can use {command}`nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings`
656656- to view the current value. By default it is empty.
657657-658658- Nix configurations defined under {option}`nix.*` will be translated and applied to this
659659- option. In addition, configuration specified in {option}`nix.extraOptions` will be appended
660660- verbatim to the resulting config file.
661661- '';
662662- };
663663- };
664664- };
665665-666666-667667- ###### implementation
668668-669669- config = mkIf cfg.enable {
670670- environment.systemPackages =
671671- [
672672- nixPackage
673673- pkgs.nix-info
674674- ]
675675- ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
676676-677677- environment.etc."nix/nix.conf".source = nixConf;
678678-679679- environment.etc."nix/registry.json".text = builtins.toJSON {
680680- version = 2;
681681- flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
682682- };
683683-684684- # List of machines for distributed Nix builds in the format
685685- # expected by build-remote.pl.
686686- environment.etc."nix/machines" = mkIf (cfg.buildMachines != [ ]) {
687687- text =
688688- concatMapStrings
689689- (machine:
690690- (concatStringsSep " " ([
691691- "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
692692- (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
693693- (if machine.sshKey != null then machine.sshKey else "-")
694694- (toString machine.maxJobs)
695695- (toString machine.speedFactor)
696696- (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures);
697697- in if (res == []) then "-" else (concatStringsSep "," res))
698698- (let res = machine.mandatoryFeatures;
699699- in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures))
700700- ]
701701- ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
702702- + "\n"
703703- )
704704- cfg.buildMachines;
705705- };
706706-707707- assertions =
708708- let badMachine = m: m.system == null && m.systems == [ ];
709709- in
710710- [
711711- {
712712- assertion = !(any badMachine cfg.buildMachines);
713713- message = ''
714714- At least one system type (via <varname>system</varname> or
715715- <varname>systems</varname>) must be set for every build machine.
716716- Invalid machine specifications:
717717- '' + " " +
718718- (concatStringsSep "\n "
719719- (map (m: m.hostName)
720720- (filter (badMachine) cfg.buildMachines)));
721721- }
722722- ];
723723-724724- systemd.packages = [ nixPackage ];
725725-726726- # Will only work once https://github.com/NixOS/nix/pull/6285 is merged
727727- # systemd.tmpfiles.packages = [ nixPackage ];
728728-729729- # Can be dropped for Nix > https://github.com/NixOS/nix/pull/6285
730730- systemd.tmpfiles.rules = [
731731- "d /nix/var/nix/daemon-socket 0755 root root - -"
732732- ];
733733-734734- systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
735735-736736- systemd.services.nix-daemon =
737737- {
738738- path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
739739- ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
740740-741741- environment = cfg.envVars
742742- // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
743743- // config.networking.proxy.envVars;
744744-745745- unitConfig.RequiresMountsFor = "/nix/store";
746746-747747- serviceConfig =
748748- {
749749- CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
750750- IOSchedulingClass = cfg.daemonIOSchedClass;
751751- IOSchedulingPriority = cfg.daemonIOSchedPriority;
752752- LimitNOFILE = 1048576;
753753- };
754754-755755- restartTriggers = [ nixConf ];
756756-757757- # `stopIfChanged = false` changes to switch behavior
758758- # from stop -> update units -> start
759759- # to update units -> restart
760760- #
761761- # The `stopIfChanged` setting therefore controls a trade-off between a
762762- # more predictable lifecycle, which runs the correct "version" of
763763- # the `ExecStop` line, and on the other hand the availability of
764764- # sockets during the switch, as the effectiveness of the stop operation
765765- # depends on the socket being stopped as well.
766766- #
767767- # As `nix-daemon.service` does not make use of `ExecStop`, we prefer
768768- # to keep the socket up and available. This is important for machines
769769- # that run Nix-based services, such as automated build, test, and deploy
770770- # services, that expect the daemon socket to be available at all times.
771771- #
772772- # Notably, the Nix client does not retry on failure to connect to the
773773- # daemon socket, and the in-process RemoteStore instance will disable
774774- # itself. This makes retries infeasible even for services that are
775775- # aware of the issue. Failure to connect can affect not only new client
776776- # processes, but also new RemoteStore instances in existing processes,
777777- # as well as existing RemoteStore instances that have not saturated
778778- # their connection pool.
779779- #
780780- # Also note that `stopIfChanged = true` does not kill existing
781781- # connection handling daemons, as one might wish to happen before a
782782- # breaking Nix upgrade (which is rare). The daemon forks that handle
783783- # the individual connections split off into their own sessions, causing
784784- # them not to be stopped by systemd.
785785- # If a Nix upgrade does require all existing daemon processes to stop,
786786- # nix-daemon must do so on its own accord, and only when the new version
787787- # starts and detects that Nix's persistent state needs an upgrade.
788788- stopIfChanged = false;
789789-790790- };
791791-792792- # Set up the environment variables for running Nix.
793793- environment.sessionVariables = cfg.envVars // { NIX_PATH = cfg.nixPath; };
794794-795795- environment.extraInit =
796796- ''
797797- if [ -e "$HOME/.nix-defexpr/channels" ]; then
798798- export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}"
799799- fi
800800- '';
801801-802802- nix.nrBuildUsers = mkDefault (
803803- if cfg.settings.auto-allocate-uids or false then 0
804804- else max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)
805805- );
806806-807807- users.users = nixbldUsers;
808808-809809- services.xserver.displayManager.hiddenUsers = attrNames nixbldUsers;
810810-811811- system.activationScripts.nix = stringAfter [ "etc" "users" ]
812812- ''
813813- install -m 0755 -d /nix/var/nix/{gcroots,profiles}/per-user
814814-815815- # Subscribe the root user to the NixOS channel by default.
816816- if [ ! -e "/root/.nix-channels" ]; then
817817- echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels"
818818- fi
819819- '';
820820-821821- # Legacy configuration conversion.
822822- nix.settings = mkMerge [
823823- {
824824- trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
825825- substituters = mkAfter [ "https://cache.nixos.org/" ];
826826-827827- system-features = mkDefault (
828828- [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
829829- optionals (pkgs.stdenv.hostPlatform ? gcc.arch) (
830830- # a builder can run code for `gcc.arch` and inferior architectures
831831- [ "gccarch-${pkgs.stdenv.hostPlatform.gcc.arch}" ] ++
832832- map (x: "gccarch-${x}") (systems.architectures.inferiors.${pkgs.stdenv.hostPlatform.gcc.arch} or [])
833833- )
834834- );
835835- }
836836-837837- (mkIf (!cfg.distributedBuilds) { builders = null; })
838838-839839- (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
840840- ];
841841-842842- };
843843-844844-}
+263
nixos/modules/services/system/nix-daemon.nix
···11+/*
22+ Declares what makes the nix-daemon work on systemd.
33+44+ See also
55+ - nixos/modules/config/nix.nix: the nix.conf
66+ - nixos/modules/config/nix-remote-build.nix: the nix.conf
77+*/
88+{ config, lib, pkgs, ... }:
99+1010+with lib;
1111+1212+let
1313+1414+ cfg = config.nix;
1515+1616+ nixPackage = cfg.package.out;
1717+1818+ isNixAtLeast = versionAtLeast (getVersion nixPackage);
1919+2020+ makeNixBuildUser = nr: {
2121+ name = "nixbld${toString nr}";
2222+ value = {
2323+ description = "Nix build user ${toString nr}";
2424+2525+ /*
2626+ For consistency with the setgid(2), setuid(2), and setgroups(2)
2727+ calls in `libstore/build.cc', don't add any supplementary group
2828+ here except "nixbld".
2929+ */
3030+ uid = builtins.add config.ids.uids.nixbld nr;
3131+ isSystemUser = true;
3232+ group = "nixbld";
3333+ extraGroups = [ "nixbld" ];
3434+ };
3535+ };
3636+3737+ nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
3838+3939+in
4040+4141+{
4242+ imports = [
4343+ ../../config/nix.nix
4444+4545+ (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; })
4646+ (mkRenamedOptionModuleWith { sinceRelease = 2211; from = [ "nix" "readOnlyStore" ]; to = [ "boot" "readOnlyNixStore" ]; })
4747+ (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
4848+ ];
4949+5050+ ###### interface
5151+5252+ options = {
5353+5454+ nix = {
5555+5656+ enable = mkOption {
5757+ type = types.bool;
5858+ default = true;
5959+ description = lib.mdDoc ''
6060+ Whether to enable Nix.
6161+ Disabling Nix makes the system hard to modify and the Nix programs and configuration will not be made available by NixOS itself.
6262+ '';
6363+ };
6464+6565+ package = mkOption {
6666+ type = types.package;
6767+ default = pkgs.nix;
6868+ defaultText = literalExpression "pkgs.nix";
6969+ description = lib.mdDoc ''
7070+ This option specifies the Nix package instance to use throughout the system.
7171+ '';
7272+ };
7373+7474+ daemonCPUSchedPolicy = mkOption {
7575+ type = types.enum [ "other" "batch" "idle" ];
7676+ default = "other";
7777+ example = "batch";
7878+ description = lib.mdDoc ''
7979+ Nix daemon process CPU scheduling policy. This policy propagates to
8080+ build processes. `other` is the default scheduling
8181+ policy for regular tasks. The `batch` policy is
8282+ similar to `other`, but optimised for
8383+ non-interactive tasks. `idle` is for extremely
8484+ low-priority tasks that should only be run when no other task
8585+ requires CPU time.
8686+8787+ Please note that while using the `idle` policy may
8888+ greatly improve responsiveness of a system performing expensive
8989+ builds, it may also slow down and potentially starve crucial
9090+ configuration updates during load.
9191+9292+ `idle` may therefore be a sensible policy for
9393+ systems that experience only intermittent phases of high CPU load,
9494+ such as desktop or portable computers used interactively. Other
9595+ systems should use the `other` or
9696+ `batch` policy instead.
9797+9898+ For more fine-grained resource control, please refer to
9999+ {manpage}`systemd.resource-control(5)` and adjust
100100+ {option}`systemd.services.nix-daemon` directly.
101101+ '';
102102+ };
103103+104104+ daemonIOSchedClass = mkOption {
105105+ type = types.enum [ "best-effort" "idle" ];
106106+ default = "best-effort";
107107+ example = "idle";
108108+ description = lib.mdDoc ''
109109+ Nix daemon process I/O scheduling class. This class propagates to
110110+ build processes. `best-effort` is the default
111111+ class for regular tasks. The `idle` class is for
112112+ extremely low-priority tasks that should only perform I/O when no
113113+ other task does.
114114+115115+ Please note that while using the `idle` scheduling
116116+ class can improve responsiveness of a system performing expensive
117117+ builds, it might also slow down or starve crucial configuration
118118+ updates during load.
119119+120120+ `idle` may therefore be a sensible class for
121121+ systems that experience only intermittent phases of high I/O load,
122122+ such as desktop or portable computers used interactively. Other
123123+ systems should use the `best-effort` class.
124124+ '';
125125+ };
126126+127127+ daemonIOSchedPriority = mkOption {
128128+ type = types.int;
129129+ default = 4;
130130+ example = 1;
131131+ description = lib.mdDoc ''
132132+ Nix daemon process I/O scheduling priority. This priority propagates
133133+ to build processes. The supported priorities depend on the
134134+ scheduling policy: With idle, priorities are not used in scheduling
135135+ decisions. best-effort supports values in the range 0 (high) to 7
136136+ (low).
137137+ '';
138138+ };
139139+140140+ # Environment variables for running Nix.
141141+ envVars = mkOption {
142142+ type = types.attrs;
143143+ internal = true;
144144+ default = { };
145145+ description = lib.mdDoc "Environment variables used by Nix.";
146146+ };
147147+148148+ nrBuildUsers = mkOption {
149149+ type = types.int;
150150+ description = lib.mdDoc ''
151151+ Number of `nixbld` user accounts created to
152152+ perform secure concurrent builds. If you receive an error
153153+ message saying that “all build users are currently in use”,
154154+ you should increase this value.
155155+ '';
156156+ };
157157+ };
158158+ };
159159+160160+161161+ ###### implementation
162162+163163+ config = mkIf cfg.enable {
164164+ environment.systemPackages =
165165+ [
166166+ nixPackage
167167+ pkgs.nix-info
168168+ ]
169169+ ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
170170+171171+ systemd.packages = [ nixPackage ];
172172+173173+ # Will only work once https://github.com/NixOS/nix/pull/6285 is merged
174174+ # systemd.tmpfiles.packages = [ nixPackage ];
175175+176176+ # Can be dropped for Nix > https://github.com/NixOS/nix/pull/6285
177177+ systemd.tmpfiles.rules = [
178178+ "d /nix/var/nix/daemon-socket 0755 root root - -"
179179+ ];
180180+181181+ systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
182182+183183+ systemd.services.nix-daemon =
184184+ {
185185+ path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
186186+ ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
187187+188188+ environment = cfg.envVars
189189+ // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; }
190190+ // config.networking.proxy.envVars;
191191+192192+ unitConfig.RequiresMountsFor = "/nix/store";
193193+194194+ serviceConfig =
195195+ {
196196+ CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
197197+ IOSchedulingClass = cfg.daemonIOSchedClass;
198198+ IOSchedulingPriority = cfg.daemonIOSchedPriority;
199199+ LimitNOFILE = 1048576;
200200+ };
201201+202202+ restartTriggers = [ config.environment.etc."nix/nix.conf".source ];
203203+204204+ # `stopIfChanged = false` changes to switch behavior
205205+ # from stop -> update units -> start
206206+ # to update units -> restart
207207+ #
208208+ # The `stopIfChanged` setting therefore controls a trade-off between a
209209+ # more predictable lifecycle, which runs the correct "version" of
210210+ # the `ExecStop` line, and on the other hand the availability of
211211+ # sockets during the switch, as the effectiveness of the stop operation
212212+ # depends on the socket being stopped as well.
213213+ #
214214+ # As `nix-daemon.service` does not make use of `ExecStop`, we prefer
215215+ # to keep the socket up and available. This is important for machines
216216+ # that run Nix-based services, such as automated build, test, and deploy
217217+ # services, that expect the daemon socket to be available at all times.
218218+ #
219219+ # Notably, the Nix client does not retry on failure to connect to the
220220+ # daemon socket, and the in-process RemoteStore instance will disable
221221+ # itself. This makes retries infeasible even for services that are
222222+ # aware of the issue. Failure to connect can affect not only new client
223223+ # processes, but also new RemoteStore instances in existing processes,
224224+ # as well as existing RemoteStore instances that have not saturated
225225+ # their connection pool.
226226+ #
227227+ # Also note that `stopIfChanged = true` does not kill existing
228228+ # connection handling daemons, as one might wish to happen before a
229229+ # breaking Nix upgrade (which is rare). The daemon forks that handle
230230+ # the individual connections split off into their own sessions, causing
231231+ # them not to be stopped by systemd.
232232+ # If a Nix upgrade does require all existing daemon processes to stop,
233233+ # nix-daemon must do so on its own accord, and only when the new version
234234+ # starts and detects that Nix's persistent state needs an upgrade.
235235+ stopIfChanged = false;
236236+237237+ };
238238+239239+ # Set up the environment variables for running Nix.
240240+ environment.sessionVariables = cfg.envVars;
241241+242242+ nix.nrBuildUsers = mkDefault (
243243+ if cfg.settings.auto-allocate-uids or false then 0
244244+ else max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)
245245+ );
246246+247247+ users.users = nixbldUsers;
248248+249249+ services.xserver.displayManager.hiddenUsers = attrNames nixbldUsers;
250250+251251+ system.activationScripts.nix = stringAfter [ "etc" "users" ]
252252+ ''
253253+ install -m 0755 -d /nix/var/nix/{gcroots,profiles}/per-user
254254+ '';
255255+256256+ # Legacy configuration conversion.
257257+ nix.settings = mkMerge [
258258+ (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
259259+ ];
260260+261261+ };
262262+263263+}