···224225- Dashes in the package name _should_ be preserved in new variable names, rather than converted to underscores or camel cased — e.g., `http-parser` instead of `http_parser` or `httpParser`. The hyphenated style is preferred in all three package names.
226227-- If there are multiple versions of a package, this _should_ be reflected in the variable names in `all-packages.nix`, e.g. `json-c-0-9` and `json-c-0-11`. If there is an obvious “default” version, make an attribute like `json-c = json-c-0-9;`. See also [](#sec-versioning)
228229## File naming and organisation {#sec-organisation}
230
···224225- Dashes in the package name _should_ be preserved in new variable names, rather than converted to underscores or camel cased — e.g., `http-parser` instead of `http_parser` or `httpParser`. The hyphenated style is preferred in all three package names.
226227+- If there are multiple versions of a package, this _should_ be reflected in the variable names in `all-packages.nix`, e.g. `json-c_0_9` and `json-c_0_11`. If there is an obvious “default” version, make an attribute like `json-c = json-c_0_9;`. See also [](#sec-versioning)
228229## File naming and organisation {#sec-organisation}
230
-4
doc/stdenv/meta.chapter.md
···192193If set to `true`, the package is marked as "broken", meaning that it won’t show up in `nix-env -qa`, and cannot be built or installed. Such packages should be removed from Nixpkgs eventually unless they are fixed.
194195-### `updateWalker` {#var-meta-updateWalker}
196-197-If set to `true`, the package is tested to be updated correctly by the `update-walker.sh` script without additional settings. Such packages have `meta.version` set and their homepage (or the page specified by `meta.downloadPage`) contains a direct link to the package tarball.
198-199## Licenses {#sec-meta-license}
200201The `meta.license` attribute should preferably contain a value from `lib.licenses` defined in [`nixpkgs/lib/licenses.nix`](https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix), or in-place license description of the same format if the license is unlikely to be useful in another expression.
···192193If set to `true`, the package is marked as "broken", meaning that it won’t show up in `nix-env -qa`, and cannot be built or installed. Such packages should be removed from Nixpkgs eventually unless they are fixed.
1940000195## Licenses {#sec-meta-license}
196197The `meta.license` attribute should preferably contain a value from `lib.licenses` defined in [`nixpkgs/lib/licenses.nix`](https://github.com/NixOS/nixpkgs/blob/master/lib/licenses.nix), or in-place license description of the same format if the license is unlikely to be useful in another expression.
+1-5
flake.nix
···48 system.nixos.versionSuffix =
49 ".${final.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}";
50 system.nixos.revision = final.mkIf (self ? rev) self.rev;
51-52- # NOTE: This assumes that `nixpkgs.config` is _not_ used when
53- # nixpkgs.pkgs is set OR _module.args.pkgs is set.
54- nixpkgs.config.path = self.outPath;
55 }
56 ];
57 });
···66 }).nixos.manual.x86_64-linux;
67 };
6869- legacyPackages = forAllSystems (system: import ./. { inherit system; config.path = self.outPath; });
7071 nixosModules = {
72 notDetected = import ./nixos/modules/installer/scan/not-detected.nix;
···442 </listitem>
443 <listitem>
444 <para>
445- The interface that allows activation scripts to restart units
446- has been reworked. Restarting and reloading is now done by a
447- single file
448- <literal>/run/nixos/activation-restart-list</literal> that
449- honors <literal>restartIfChanged</literal> and
450- <literal>reloadIfChanged</literal> of the units.
451 </para>
000000000000000000000000000000000000000452 </listitem>
453 <listitem>
454 <para>
···533 </listitem>
534 <listitem>
535 <para>
00000000000000000000000536 The
537 <literal>writers.writePyPy2</literal>/<literal>writers.writePyPy3</literal>
538 and corresponding
539 <literal>writers.writePyPy2Bin</literal>/<literal>writers.writePyPy3Bin</literal>
540 convenience functions to create executable Python 2/3 scripts
541 using the PyPy interpreter were added.
0000000000000542 </para>
543 </listitem>
544 <listitem>
···442 </listitem>
443 <listitem>
444 <para>
445+ <literal>switch-to-configuration</literal> (the script that is
446+ run when running <literal>nixos-rebuild switch</literal> for
447+ example) has been reworked
000448 </para>
449+ <itemizedlist spacing="compact">
450+ <listitem>
451+ <para>
452+ The interface that allows activation scripts to restart
453+ units has been streamlined. Restarting and reloading is
454+ now done by a single file
455+ <literal>/run/nixos/activation-restart-list</literal> that
456+ honors <literal>restartIfChanged</literal> and
457+ <literal>reloadIfChanged</literal> of the units.
458+ </para>
459+ </listitem>
460+ <listitem>
461+ <para>
462+ The script now uses a proper ini-file parser to parse
463+ systemd units. Some values are now only searched in one
464+ section instead of in the entire unit. This is only
465+ relevant for units that don’t use the NixOS systemd moule.
466+ </para>
467+ <itemizedlist spacing="compact">
468+ <listitem>
469+ <para>
470+ <literal>RefuseManualStop</literal>,
471+ <literal>X-OnlyManualStart</literal>,
472+ <literal>X-StopOnRemoval</literal>,
473+ <literal>X-StopOnReconfiguration</literal> are only
474+ searched in the <literal>[Unit]</literal> section
475+ </para>
476+ </listitem>
477+ <listitem>
478+ <para>
479+ <literal>X-ReloadIfChanged</literal>,
480+ <literal>X-RestartIfChanged</literal>,
481+ <literal>X-StopIfChanged</literal> are only searched
482+ in the <literal>[Service]</literal> section
483+ </para>
484+ </listitem>
485+ </itemizedlist>
486+ </listitem>
487+ </itemizedlist>
488 </listitem>
489 <listitem>
490 <para>
···569 </listitem>
570 <listitem>
571 <para>
572+ The configuration portion of the <literal>nix-daemon</literal>
573+ module has been reworked and exposed as
574+ <link xlink:href="options.html#opt-nix-settings">nix.settings</link>:
575+ </para>
576+ <itemizedlist spacing="compact">
577+ <listitem>
578+ <para>
579+ Legacy options have been mapped to the corresponding
580+ options under under
581+ <link xlink:href="options.html#opt-nix.settings">nix.settings</link>
582+ but may be deprecated in the future.
583+ </para>
584+ </listitem>
585+ <listitem>
586+ <para>
587+ <link xlink:href="options.html#opt-nix.buildMachines.publicHostKey">nix.buildMachines.publicHostKey</link>
588+ has been added.
589+ </para>
590+ </listitem>
591+ </itemizedlist>
592+ </listitem>
593+ <listitem>
594+ <para>
595 The
596 <literal>writers.writePyPy2</literal>/<literal>writers.writePyPy3</literal>
597 and corresponding
598 <literal>writers.writePyPy2Bin</literal>/<literal>writers.writePyPy3Bin</literal>
599 convenience functions to create executable Python 2/3 scripts
600 using the PyPy interpreter were added.
601+ </para>
602+ </listitem>
603+ <listitem>
604+ <para>
605+ If you are using Wayland you can choose to use the Ozone
606+ Wayland support in Chrome and several Electron apps by setting
607+ the environment variable <literal>NIXOS_OZONE_WL=1</literal>
608+ (for example via
609+ <literal>environment.sessionVariables.NIXOS_OZONE_WL = "1"</literal>).
610+ This is not enabled by default because Ozone Wayland is still
611+ under heavy development and behavior is not always flawless.
612+ Furthermore, not all Electron apps use the latest Electron
613+ versions.
614 </para>
615 </listitem>
616 <listitem>
+1-1
nixos/doc/manual/man-nixos-rebuild.xml
···453 Allow ad-hoc remote builders for building the new system. This requires
454 the user executing <command>nixos-rebuild</command> (usually root) to be
455 configured as a trusted user in the Nix daemon. This can be achieved by
456- using the <literal>nix.trustedUsers</literal> NixOS option. Examples
457 values for that option are described in the <literal>Remote builds
458 chapter</literal> in the Nix manual, (i.e. <command>--builders
459 "ssh://bigbrother x86_64-linux"</command>). By specifying an empty string
···453 Allow ad-hoc remote builders for building the new system. This requires
454 the user executing <command>nixos-rebuild</command> (usually root) to be
455 configured as a trusted user in the Nix daemon. This can be achieved by
456+ using the <literal>nix.settings.trusted-users</literal> NixOS option. Examples
457 values for that option are described in the <literal>Remote builds
458 chapter</literal> in the Nix manual, (i.e. <command>--builders
459 "ssh://bigbrother x86_64-linux"</command>). By specifying an empty string
+22-5
nixos/doc/manual/release-notes/rl-2205.section.md
···60## Backward Incompatibilities {#sec-release-22.05-incompatibilities}
6162- `pkgs.ghc` now refers to `pkgs.targetPackages.haskellPackages.ghc`.
63- This *only* makes a difference if you are cross-compiling and will
64 ensure that `pkgs.ghc` always runs on the host platform and compiles
65 for the target platform (similar to `pkgs.gcc` for example).
66 `haskellPackages.ghc` still behaves as before, running on the build
···141 `pkgs.noto-fonts-cjk` is currently an alias of `pkgs.noto-fonts-cjk-sans` and
142 doesn't include serif fonts.
143144-- The interface that allows activation scripts to restart units has been reworked. Restarting and reloading is now done by a single file `/run/nixos/activation-restart-list` that honors `restartIfChanged` and `reloadIfChanged` of the units.
0000145146- The `services.bookstack.cacheDir` option has been removed, since the
147 cache directory is now handled by systemd.
···177 to allow users to make changes to the `nixos-rebuild build-vm` configuration
178 that do not apply to their normal system.
179180- The `config.system.build.vm` attribute now always exists and defaults to the
181 value from `vmVariant`. Configurations that import the `virtualisation/qemu-vm.nix`
182 module themselves will override this value, such that `vmVariant` is not used.
183184 Similarly [virtualisation.vmVariantWithBootloader](#opt-virtualisation.vmVariantWithBootLoader) was added.
0000185186- The `writers.writePyPy2`/`writers.writePyPy3` and corresponding `writers.writePyPy2Bin`/`writers.writePyPy3Bin` convenience functions to create executable Python 2/3 scripts using the PyPy interpreter were added.
18700000000188- The `influxdb2` package was split into `influxdb2-server` and
189 `influxdb2-cli`, matching the split that took place upstream. A
190 combined `influxdb2` package is still provided in this release for
···236 Plugins are automatically repackaged using autoPatchelf.
237238- The `zrepl` package has been updated from 0.4.0 to 0.5:
239- * The RPC protocol version was bumped; all zrepl daemons in a setup must be updated and restarted before replication can resume.
240- * A bug involving encrypt-on-receive has been fixed. Read the [zrepl documentation](https://zrepl.github.io/configuration/sendrecvoptions.html#job-recv-options-placeholder) and check the output of `zfs get -r encryption,zrepl:placeholder PATH_TO_ROOTFS` on the receiver.
0241242- Renamed option `services.openssh.challengeResponseAuthentication` to `services.openssh.kbdInteractiveAuthentication`.
243 Reason is that the old name has been deprecated upstream.
···60## Backward Incompatibilities {#sec-release-22.05-incompatibilities}
6162- `pkgs.ghc` now refers to `pkgs.targetPackages.haskellPackages.ghc`.
63+ This _only_ makes a difference if you are cross-compiling and will
64 ensure that `pkgs.ghc` always runs on the host platform and compiles
65 for the target platform (similar to `pkgs.gcc` for example).
66 `haskellPackages.ghc` still behaves as before, running on the build
···141 `pkgs.noto-fonts-cjk` is currently an alias of `pkgs.noto-fonts-cjk-sans` and
142 doesn't include serif fonts.
143144+- `switch-to-configuration` (the script that is run when running `nixos-rebuild switch` for example) has been reworked
145+ * The interface that allows activation scripts to restart units has been streamlined. Restarting and reloading is now done by a single file `/run/nixos/activation-restart-list` that honors `restartIfChanged` and `reloadIfChanged` of the units.
146+ * The script now uses a proper ini-file parser to parse systemd units. Some values are now only searched in one section instead of in the entire unit. This is only relevant for units that don't use the NixOS systemd moule.
147+ * `RefuseManualStop`, `X-OnlyManualStart`, `X-StopOnRemoval`, `X-StopOnReconfiguration` are only searched in the `[Unit]` section
148+ * `X-ReloadIfChanged`, `X-RestartIfChanged`, `X-StopIfChanged` are only searched in the `[Service]` section
149150- The `services.bookstack.cacheDir` option has been removed, since the
151 cache directory is now handled by systemd.
···181 to allow users to make changes to the `nixos-rebuild build-vm` configuration
182 that do not apply to their normal system.
183184+ The `config.system.build.vm` attribute now always exists and defaults to the
185 value from `vmVariant`. Configurations that import the `virtualisation/qemu-vm.nix`
186 module themselves will override this value, such that `vmVariant` is not used.
187188 Similarly [virtualisation.vmVariantWithBootloader](#opt-virtualisation.vmVariantWithBootLoader) was added.
189+190+- The configuration portion of the `nix-daemon` module has been reworked and exposed as [nix.settings](options.html#opt-nix-settings):
191+ * Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) but may be deprecated in the future.
192+ * [nix.buildMachines.publicHostKey](options.html#opt-nix.buildMachines.publicHostKey) has been added.
193194- The `writers.writePyPy2`/`writers.writePyPy3` and corresponding `writers.writePyPy2Bin`/`writers.writePyPy3Bin` convenience functions to create executable Python 2/3 scripts using the PyPy interpreter were added.
195196+- If you are using Wayland you can choose to use the Ozone Wayland support
197+ in Chrome and several Electron apps by setting the environment variable
198+ `NIXOS_OZONE_WL=1` (for example via
199+ `environment.sessionVariables.NIXOS_OZONE_WL = "1"`).
200+ This is not enabled by default because Ozone Wayland is
201+ still under heavy development and behavior is not always flawless.
202+ Furthermore, not all Electron apps use the latest Electron versions.
203+204- The `influxdb2` package was split into `influxdb2-server` and
205 `influxdb2-cli`, matching the split that took place upstream. A
206 combined `influxdb2` package is still provided in this release for
···252 Plugins are automatically repackaged using autoPatchelf.
253254- The `zrepl` package has been updated from 0.4.0 to 0.5:
255+256+ - The RPC protocol version was bumped; all zrepl daemons in a setup must be updated and restarted before replication can resume.
257+ - A bug involving encrypt-on-receive has been fixed. Read the [zrepl documentation](https://zrepl.github.io/configuration/sendrecvoptions.html#job-recv-options-placeholder) and check the output of `zfs get -r encryption,zrepl:placeholder PATH_TO_ROOTFS` on the receiver.
258259- Renamed option `services.openssh.challengeResponseAuthentication` to `services.openssh.kbdInteractiveAuthentication`.
260 Reason is that the old name has been deprecated upstream.
+1-1
nixos/lib/systemd-unit-options.nix
···9899 description = mkOption {
100 default = "";
101- type = types.str;
102 description = "Description of this unit used in systemd messages and progress indicators.";
103 };
104
···9899 description = mkOption {
100 default = "";
101+ type = types.singleLineStr;
102 description = "Description of this unit used in systemd messages and progress indicators.";
103 };
104
···2526 installer.cloneConfigExtra = ''
27 # Let demo build as a trusted user.
28- # nix.trustedUsers = [ "demo" ];
2930 # Mount a VirtualBox shared folder.
31 # This is configurable in the VirtualBox menu at
···2526 installer.cloneConfigExtra = ''
27 # Let demo build as a trusted user.
28+ # nix.settings.trusted-users = [ "demo" ];
2930 # Mount a VirtualBox shared folder.
31 # This is configurable in the VirtualBox menu at
+4-72
nixos/modules/misc/documentation.nix
···61 in scrubbedEval.options;
62 baseOptionsJSON =
63 let
64- filterIntoStore =
65 builtins.filterSource
66 (n: t:
67 (t == "directory" -> baseNameOf n != "tests")
68 && (t == "file" -> hasSuffix ".nix" n)
69 );
70-71- # Figure out if Nix runs in pure evaluation mode. May return true in
72- # impure mode, but this is highly unlikely.
73- # We need to know because of https://github.com/NixOS/nix/issues/1888
74- # and https://github.com/NixOS/nix/issues/5868
75- isPureEval = builtins.getEnv "PATH" == "" && builtins.getEnv "_" == "";
76-77- # Return a nixpkgs subpath with minimal copying.
78- #
79- # The sources for the base options json derivation can come in one of
80- # two forms:
81- # - single source: a store path with all of nixpkgs, postfix with
82- # subpaths to access various directories. This has the benefit of
83- # not creating copies of these subtrees in the Nix store, but
84- # can cause unnecessary rebuilds if you update the Nixpkgs `pkgs`
85- # tree often.
86- # - split sources: multiple store paths with subdirectories of
87- # nixpkgs that exclude the bulk of the pkgs directory.
88- # This requires more copying and hashing during evaluation but
89- # requires fewer files to be copied. This method produces fewer
90- # unnecessary rebuilds of the base options json.
91- #
92- # Flake
93- #
94- # Flakes always put a copy of the full nixpkgs sources in the store,
95- # so we can use the "single source" method. This method is ideal
96- # for using nixpkgs as a dependency, as the base options json will be
97- # substitutable from cache.nixos.org.
98- #
99- # This requires that the `self.outPath` is wired into `pkgs` correctly,
100- # which is done for you if `pkgs` comes from the `lib.nixosSystem` or
101- # `legacyPackages` flake attributes.
102- #
103- # Other Nixpkgs invocation
104- #
105- # If you do not use the known-correct flake attributes, but rather
106- # invoke Nixpkgs yourself, set `config.path` to the correct path value,
107- # e.g. `import nixpkgs { config.path = nixpkgs; }`.
108- #
109- # Choosing between single or split source paths
110- #
111- # We make assumptions based on the type and contents of `pkgs.path`.
112- # By passing a different `config.path` to Nixpkgs, you can influence
113- # how your documentation cache is evaluated and rebuilt.
114- #
115- # Single source
116- # - If pkgs.path is a string containing a store path, the code has no
117- # choice but to create this store path, if it hasn't already been.
118- # We assume that the "single source" method is most efficient.
119- # - If pkgs.path is a path value containing that is a store path,
120- # we try to convert it to a string with context without copying.
121- # This occurs for example when nixpkgs was fetched and using its
122- # default `config.path`, which is `./.`.
123- # Nix currently does not allow this conversion when evaluating in
124- # pure mode. If the conversion is not possible, we use the
125- # "split source" method.
126- #
127- # Split source
128- # - If pkgs.path is a path value that is not a store path, we assume
129- # that it's unlikely for all of nixpkgs to end up in the store for
130- # other reasons and try to keep both the copying and rebuilds low.
131- pull =
132- if builtins.typeOf pkgs.path == "string" && isStorePath pkgs.path then
133- dir: "${pkgs.path}/${dir}"
134- else if !isPureEval && isStorePath pkgs.path then
135- dir: "${builtins.storePath pkgs.path}/${dir}"
136- else
137- dir: filterIntoStore "${toString pkgs.path}/${dir}";
138 in
139 pkgs.runCommand "lazy-options.json" {
140- libPath = pull "lib";
141- pkgsLibPath = pull "pkgs/pkgs-lib";
142- nixosPath = pull "nixos";
143 modules = map (p: ''"${removePrefix "${modulesPath}/" (toString p)}"'') docModules.lazy;
144 } ''
145 export NIX_STORE_DIR=$TMPDIR/store
···59 inherit (cfg) config overlays localSystem crossSystem;
60 };
6162- # NOTE: flake.nix assumes that nixpkgs.config is only used with ../../..
63- # as nixpkgs.config.path should be equivalent to ../../..
64 finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs;
6566in
···59 inherit (cfg) config overlays localSystem crossSystem;
60 };
610062 finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs;
6364in
···147 concurrent = mkOption {
148 type = types.int;
149 default = 1;
150- example = literalExpression "config.nix.maxJobs";
151 description = ''
152 Limits how many jobs globally can be run concurrently.
153 The most upper limit of jobs using all defined runners.
···147 concurrent = mkOption {
148 type = types.int;
149 default = 1;
150+ example = literalExpression "config.nix.settings.max-jobs";
151 description = ''
152 Limits how many jobs globally can be run concurrently.
153 The most upper limit of jobs using all defined runners.
···67 cfg = config.nix;
89- nix = cfg.package.out;
10-11- nixVersion = getVersion nix;
1213- isNix23 = versionAtLeast nixVersion "2.3pre";
1415 makeNixBuildUser = nr: {
16- name = "nixbld${toString nr}";
17 value = {
18 description = "Nix build user ${toString nr}";
1920- /* For consistency with the setgid(2), setuid(2), and setgroups(2)
21- calls in `libstore/build.cc', don't add any supplementary group
22- here except "nixbld". */
0023 uid = builtins.add config.ids.uids.nixbld nr;
24 isSystemUser = true;
25 group = "nixbld";
···30 nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
3132 nixConf =
33- assert versionAtLeast nixVersion "2.2";
34- pkgs.runCommand "nix.conf" { preferLocalBuild = true; extraOptions = cfg.extraOptions; } (
35- ''
36- cat > $out <<END
000000000000000000037 # WARNING: this file is generated from the nix.* options in
38 # your NixOS configuration, typically
39 # /etc/nixos/configuration.nix. Do not edit it!
40- build-users-group = nixbld
41- max-jobs = ${toString (cfg.maxJobs)}
42- cores = ${toString (cfg.buildCores)}
43- sandbox = ${if (builtins.isBool cfg.useSandbox) then boolToString cfg.useSandbox else cfg.useSandbox}
44- extra-sandbox-paths = ${toString cfg.sandboxPaths}
45- substituters = ${toString cfg.binaryCaches}
46- trusted-substituters = ${toString cfg.trustedBinaryCaches}
47- trusted-public-keys = ${toString cfg.binaryCachePublicKeys}
48- auto-optimise-store = ${boolToString cfg.autoOptimiseStore}
49- require-sigs = ${boolToString cfg.requireSignedBinaryCaches}
50- trusted-users = ${toString cfg.trustedUsers}
51- allowed-users = ${toString cfg.allowedUsers}
52- ${optionalString (!cfg.distributedBuilds) ''
53- builders =
54- ''}
55- system-features = ${toString cfg.systemFeatures}
56- ${optionalString isNix23 ''
57- sandbox-fallback = false
58- ''}
59- $extraOptions
60- END
61- '' + optionalString cfg.checkConfig (
62- if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
63- echo "Ignore nix.checkConfig when cross-compiling"
64- '' else ''
65- echo "Checking that Nix can read nix.conf..."
66- ln -s $out ./nix.conf
67- NIX_CONF_DIR=$PWD ${cfg.package}/bin/nix show-config ${optionalString isNix23 "--no-net --option experimental-features nix-command"} >/dev/null
68- '')
69- );
000000000000000000007071in
72···76 (mkRenamedOptionModule [ "nix" "chrootDirs" ] [ "nix" "sandboxPaths" ])
77 (mkRenamedOptionModule [ "nix" "daemonIONiceLevel" ] [ "nix" "daemonIOSchedPriority" ])
78 (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
79- ];
8081 ###### interface
82···102 '';
103 };
104105- maxJobs = mkOption {
106- type = types.either types.int (types.enum ["auto"]);
107- default = "auto";
108- example = 64;
109- description = ''
110- This option defines the maximum number of jobs that Nix will try to
111- build in parallel. The default is auto, which means it will use all
112- available logical cores. It is recommend to set it to the total
113- number of logical cores in your system (e.g., 16 for two CPUs with 4
114- cores each and hyper-threading).
115- '';
116- };
117-118- autoOptimiseStore = mkOption {
119- type = types.bool;
120- default = false;
121- example = true;
122- description = ''
123- If set to true, Nix automatically detects files in the store that have
124- identical contents, and replaces them with hard links to a single copy.
125- This saves disk space. If set to false (the default), you can still run
126- nix-store --optimise to get rid of duplicate files.
127- '';
128- };
129-130- buildCores = mkOption {
131- type = types.int;
132- default = 0;
133- example = 64;
134- description = ''
135- This option defines the maximum number of concurrent tasks during
136- one build. It affects, e.g., -j option for make.
137- The special value 0 means that the builder should use all
138- available CPU cores in the system. Some builds may become
139- non-deterministic with this option; use with care! Packages will
140- only be affected if enableParallelBuilding is set for them.
141- '';
142- };
143-144- useSandbox = mkOption {
145- type = types.either types.bool (types.enum ["relaxed"]);
146- default = true;
147- description = "
148- If set, Nix will perform builds in a sandboxed environment that it
149- will set up automatically for each build. This prevents impurities
150- in builds by disallowing access to dependencies outside of the Nix
151- store by using network and mount namespaces in a chroot environment.
152- This is enabled by default even though it has a possible performance
153- impact due to the initial setup time of a sandbox for each build. It
154- doesn't affect derivation hashes, so changing this option will not
155- trigger a rebuild of packages.
156- ";
157- };
158-159- sandboxPaths = mkOption {
160- type = types.listOf types.str;
161- default = [];
162- example = [ "/dev" "/proc" ];
163- description =
164- ''
165- Directories from the host filesystem to be included
166- in the sandbox.
167- '';
168- };
169-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 <filename>nix.conf</filename>.";
178- };
179-180 distributedBuilds = mkOption {
181 type = types.bool;
182 default = false;
···187 };
188189 daemonCPUSchedPolicy = mkOption {
190- type = types.enum ["other" "batch" "idle"];
191 default = "other";
192 example = "batch";
193 description = ''
···218 };
219220 daemonIOSchedClass = mkOption {
221- type = types.enum ["best-effort" "idle"];
222 default = "best-effort";
223 example = "idle";
224 description = ''
···250 scheduling policy: With idle, priorities are not used in scheduling
251 decisions. best-effort supports values in the range 0 (high) to 7
252 (low).
253- '';
254 };
255256 buildMachines = mkOption {
257- type = types.listOf (types.submodule ({
258 options = {
259 hostName = mkOption {
260 type = types.str;
···276 };
277 systems = mkOption {
278 type = types.listOf types.str;
279- default = [];
280 example = [ "x86_64-linux" "aarch64-linux" ];
281 description = ''
282 The system types the build machine can execute derivations on.
···293 The username to log in as on the remote host. This user must be
294 able to log in and run nix commands non-interactively. It must
295 also be privileged to build derivations, so must be included in
296- <option>nix.trustedUsers</option>.
297 '';
298 };
299 sshKey = mkOption {
···331 };
332 mandatoryFeatures = mkOption {
333 type = types.listOf types.str;
334- default = [];
335 example = [ "big-parallel" ];
336 description = ''
337 A list of features mandatory for this builder. The builder will
···342 };
343 supportedFeatures = mkOption {
344 type = types.listOf types.str;
345- default = [];
346 example = [ "kvm" "big-parallel" ];
347 description = ''
348 A list of features supported by this builder. The builder will
···350 list.
351 '';
352 };
000000000353 };
354- }));
355- default = [];
356 description = ''
357 This option lists the machines to be used if distributed builds are
358 enabled (see <option>nix.distributedBuilds</option>).
···366 envVars = mkOption {
367 type = types.attrs;
368 internal = true;
369- default = {};
370 description = "Environment variables used by Nix.";
371 };
372···391 '';
392 };
393394- binaryCaches = mkOption {
395- type = types.listOf types.str;
396- description = ''
397- List of binary cache URLs used to obtain pre-built binaries
398- of Nix packages.
399-400- By default https://cache.nixos.org/ is added,
401- to override it use <literal>lib.mkForce []</literal>.
402- '';
403- };
404-405- trustedBinaryCaches = mkOption {
406- type = types.listOf types.str;
407- default = [ ];
408- example = [ "https://hydra.nixos.org/" ];
409- description = ''
410- List of binary cache URLs that non-root users can use (in
411- addition to those specified using
412- <option>nix.binaryCaches</option>) by passing
413- <literal>--option binary-caches</literal> to Nix commands.
414- '';
415- };
416-417- requireSignedBinaryCaches = mkOption {
418- type = types.bool;
419- default = true;
420- description = ''
421- If enabled (the default), Nix will only download binaries from binary caches if
422- they are cryptographically signed with any of the keys listed in
423- <option>nix.binaryCachePublicKeys</option>. If disabled, signatures are neither
424- required nor checked, so it's strongly recommended that you use only
425- trustworthy caches and https to prevent man-in-the-middle attacks.
426- '';
427- };
428-429- binaryCachePublicKeys = mkOption {
430- type = types.listOf types.str;
431- example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
432- description = ''
433- List of public keys used to sign binary caches. If
434- <option>nix.requireSignedBinaryCaches</option> is enabled,
435- then Nix will use a binary from a binary cache if and only
436- if it is signed by <emphasis>any</emphasis> of the keys
437- listed here. By default, only the key for
438- <uri>cache.nixos.org</uri> is included.
439- '';
440- };
441-442- trustedUsers = mkOption {
443- type = types.listOf types.str;
444- default = [ "root" ];
445- example = [ "root" "alice" "@wheel" ];
446- description = ''
447- A list of names of users that have additional rights when
448- connecting to the Nix daemon, such as the ability to specify
449- additional binary caches, or to import unsigned NARs. You
450- can also specify groups by prefixing them with
451- <literal>@</literal>; for instance,
452- <literal>@wheel</literal> means all users in the wheel
453- group.
454- '';
455- };
456-457- allowedUsers = mkOption {
458- type = types.listOf types.str;
459- default = [ "*" ];
460- example = [ "@wheel" "@builders" "alice" "bob" ];
461- description = ''
462- A list of names of users (separated by whitespace) that are
463- allowed to connect to the Nix daemon. As with
464- <option>nix.trustedUsers</option>, you can specify groups by
465- prefixing them with <literal>@</literal>. Also, you can
466- allow all users by specifying <literal>*</literal>. The
467- default is <literal>*</literal>. Note that trusted users are
468- always allowed to connect.
469- '';
470- };
471-472 nixPath = mkOption {
473 type = types.listOf types.str;
474- default =
475- [
476- "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
477- "nixos-config=/etc/nixos/configuration.nix"
478- "/nix/var/nix/profiles/per-user/root/channels"
479- ];
480 description = ''
481 The default Nix expression search path, used by the Nix
482 evaluator to look up paths enclosed in angle brackets
···484 '';
485 };
486487- systemFeatures = mkOption {
488- type = types.listOf types.str;
489- example = [ "kvm" "big-parallel" "gccarch-skylake" ];
490- description = ''
491- The supported features of a machine
492- '';
493- };
494-495 checkConfig = mkOption {
496 type = types.bool;
497 default = true;
498 description = ''
499- If enabled (the default), checks that Nix can parse the generated nix.conf.
0500 '';
501 };
502503 registry = mkOption {
504 type = types.attrsOf (types.submodule (
505 let
506- inputAttrs = types.attrsOf (types.oneOf [types.str types.int types.bool types.package]);
00000507 in
508 { config, name, ... }:
509- { options = {
0510 from = mkOption {
511- type = inputAttrs;
512 example = { type = "indirect"; id = "nixpkgs"; };
513 description = "The flake reference to be rewritten.";
514 };
515 to = mkOption {
516- type = inputAttrs;
517 example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; };
518- description = "The flake reference to which <option>from></option> is to be rewritten.";
519 };
520 flake = mkOption {
521 type = types.nullOr types.attrs;
522 default = null;
523 example = literalExpression "nixpkgs";
524 description = ''
525- The flake input to which <option>from></option> is to be rewritten.
526 '';
527 };
528 exact = mkOption {
···537 };
538 config = {
539 from = mkDefault { type = "indirect"; id = name; };
540- to = mkIf (config.flake != null)
541- ({ type = "path";
542- path = config.flake.outPath;
543- } // lib.filterAttrs
544- (n: v: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash")
545- config.flake);
0546 };
547 }
548 ));
549- default = {};
550 description = ''
551 A system-wide flake registry.
552 '';
553 };
554555- };
0000000000000000000000000000000000000000000000000000000000000000000000000000055600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000557 };
558559560 ###### implementation
561562 config = mkIf cfg.enable {
563-564- nix.binaryCachePublicKeys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
565- nix.binaryCaches = [ "https://cache.nixos.org/" ];
566-567 environment.systemPackages =
568- [ nix
0569 pkgs.nix-info
570 ]
571 ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
···579580 # List of machines for distributed Nix builds in the format
581 # expected by build-remote.pl.
582- environment.etc."nix/machines" =
583- { enable = cfg.buildMachines != [];
584- text =
585- concatMapStrings (machine:
586- "${if machine.sshUser != null then "${machine.sshUser}@" else ""}${machine.hostName} "
587- + (if machine.system != null then machine.system else concatStringsSep "," machine.systems)
588- + " ${if machine.sshKey != null then machine.sshKey else "-"} ${toString machine.maxJobs} "
589- + toString (machine.speedFactor)
590- + " "
591- + concatStringsSep "," (machine.mandatoryFeatures ++ machine.supportedFeatures)
592- + " "
593- + concatStringsSep "," machine.mandatoryFeatures
00594 + "\n"
595- ) cfg.buildMachines;
596- };
00597 assertions =
598- let badMachine = m: m.system == null && m.systems == [];
599- in [
0600 {
601- assertion = !(builtins.any badMachine cfg.buildMachines);
602 message = ''
603 At least one system type (via <varname>system</varname> or
604 <varname>systems</varname>) must be set for every build machine.
605 Invalid machine specifications:
606 '' + " " +
607- (builtins.concatStringsSep "\n "
608- (builtins.map (m: m.hostName)
609- (builtins.filter (badMachine) cfg.buildMachines)));
610 }
611 ];
612613-614- systemd.packages = [ nix ];
615616 systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
617618 systemd.services.nix-daemon =
619- { path = [ nix pkgs.util-linux config.programs.ssh.package ]
0620 ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
621622 environment = cfg.envVars
···626 unitConfig.RequiresMountsFor = "/nix/store";
627628 serviceConfig =
629- { CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
0630 IOSchedulingClass = cfg.daemonIOSchedClass;
631 IOSchedulingPriority = cfg.daemonIOSchedPriority;
632 LimitNOFILE = 4096;
···636 };
637638 # Set up the environment variables for running Nix.
639- environment.sessionVariables = cfg.envVars //
640- { NIX_PATH = cfg.nixPath;
641- };
642643 environment.extraInit =
644 ''
···647 fi
648 '';
649650- nix.nrBuildUsers = mkDefault (lib.max 32 (if cfg.maxJobs == "auto" then 0 else cfg.maxJobs));
651652 users.users = nixbldUsers;
653···663 fi
664 '';
665666- nix.systemFeatures = mkDefault (
667- [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
668- optionals (pkgs.hostPlatform ? gcc.arch) (
669- # a builder can run code for `gcc.arch` and inferior architectures
670- [ "gccarch-${pkgs.hostPlatform.gcc.arch}" ] ++
671- map (x: "gccarch-${x}") lib.systems.architectures.inferiors.${pkgs.hostPlatform.gcc.arch}
672- )
673- );
000000000000674675 };
676
···67 cfg = config.nix;
89+ nixPackage = cfg.package.out;
001011+ isNixAtLeast = versionAtLeast (getVersion nixPackage);
1213 makeNixBuildUser = nr: {
14+ name = "nixbld${toString nr}";
15 value = {
16 description = "Nix build user ${toString nr}";
1718+ /*
19+ For consistency with the setgid(2), setuid(2), and setgroups(2)
20+ calls in `libstore/build.cc', don't add any supplementary group
21+ here except "nixbld".
22+ */
23 uid = builtins.add config.ids.uids.nixbld nr;
24 isSystemUser = true;
25 group = "nixbld";
···30 nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers));
3132 nixConf =
33+ assert isNixAtLeast "2.2";
34+ let
35+36+ mkValueString = v:
37+ if v == null then ""
38+ else if isInt v then toString v
39+ else if isBool v then boolToString v
40+ else if isFloat v then floatToString v
41+ else if isList v then toString v
42+ else if isDerivation v then toString v
43+ else if builtins.isPath v then toString v
44+ else if isString v then v
45+ else if isCoercibleToString v then toString v
46+ else abort "The nix conf value: ${toPretty {} v} can not be encoded";
47+48+ mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
49+50+ mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
51+52+ in
53+ pkgs.writeTextFile {
54+ name = "nix.conf";
55+ text = ''
56 # WARNING: this file is generated from the nix.* options in
57 # your NixOS configuration, typically
58 # /etc/nixos/configuration.nix. Do not edit it!
59+ ${mkKeyValuePairs cfg.settings}
60+ ${cfg.extraOptions}
61+ '';
62+ checkPhase =
63+ if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
64+ echo "Ignoring validation for cross-compilation"
65+ ''
66+ else ''
67+ echo "Validating generated nix.conf"
68+ ln -s $out ./nix.conf
69+ set -e
70+ set +o pipefail
71+ NIX_CONF_DIR=$PWD \
72+ ${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net --option experimental-features nix-command"} \
73+ |& sed -e 's/^warning:/error:/' \
74+ | (! grep '${if cfg.checkConfig then "^error:" else "^error: unknown setting"}')
75+ set -o pipefail
76+ '';
77+ };
78+79+ legacyConfMappings = {
80+ useSandbox = "sandbox";
81+ buildCores = "cores";
82+ maxJobs = "max-jobs";
83+ sandboxPaths = "extra-sandbox-paths";
84+ binaryCaches = "substituters";
85+ trustedBinaryCaches = "trusted-substituters";
86+ binaryCachePublicKeys = "trusted-public-keys";
87+ autoOptimiseStore = "auto-optimise-store";
88+ requireSignedBinaryCaches = "require-sigs";
89+ trustedUsers = "trusted-users";
90+ allowedUsers = "allowed-users";
91+ systemFeatures = "system-feature";
92+ };
93+94+ semanticConfType = with types;
95+ let
96+ confAtom = nullOr
97+ (oneOf [
98+ bool
99+ int
100+ float
101+ str
102+ path
103+ package
104+ ]) // {
105+ description = "Nix config atom (null, bool, int, float, str, path or package)";
106+ };
107+ in
108+ attrsOf (either confAtom (listOf confAtom));
109110in
111···115 (mkRenamedOptionModule [ "nix" "chrootDirs" ] [ "nix" "sandboxPaths" ])
116 (mkRenamedOptionModule [ "nix" "daemonIONiceLevel" ] [ "nix" "daemonIOSchedPriority" ])
117 (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
118+ ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings;
119120 ###### interface
121···141 '';
142 };
143000000000000000000000000000000000000000000000000000000000000000000000000000144 distributedBuilds = mkOption {
145 type = types.bool;
146 default = false;
···151 };
152153 daemonCPUSchedPolicy = mkOption {
154+ type = types.enum [ "other" "batch" "idle" ];
155 default = "other";
156 example = "batch";
157 description = ''
···182 };
183184 daemonIOSchedClass = mkOption {
185+ type = types.enum [ "best-effort" "idle" ];
186 default = "best-effort";
187 example = "idle";
188 description = ''
···214 scheduling policy: With idle, priorities are not used in scheduling
215 decisions. best-effort supports values in the range 0 (high) to 7
216 (low).
217+ '';
218 };
219220 buildMachines = mkOption {
221+ type = types.listOf (types.submodule {
222 options = {
223 hostName = mkOption {
224 type = types.str;
···240 };
241 systems = mkOption {
242 type = types.listOf types.str;
243+ default = [ ];
244 example = [ "x86_64-linux" "aarch64-linux" ];
245 description = ''
246 The system types the build machine can execute derivations on.
···257 The username to log in as on the remote host. This user must be
258 able to log in and run nix commands non-interactively. It must
259 also be privileged to build derivations, so must be included in
260+ <option>nix.settings.trusted-users</option>.
261 '';
262 };
263 sshKey = mkOption {
···295 };
296 mandatoryFeatures = mkOption {
297 type = types.listOf types.str;
298+ default = [ ];
299 example = [ "big-parallel" ];
300 description = ''
301 A list of features mandatory for this builder. The builder will
···306 };
307 supportedFeatures = mkOption {
308 type = types.listOf types.str;
309+ default = [ ];
310 example = [ "kvm" "big-parallel" ];
311 description = ''
312 A list of features supported by this builder. The builder will
···314 list.
315 '';
316 };
317+ publicHostKey = mkOption {
318+ type = types.nullOr types.str;
319+ default = null;
320+ description = ''
321+ The (base64-encoded) public host key of this builder. The field
322+ is calculated via <command>base64 -w0 /etc/ssh/ssh_host_type_key.pub</command>.
323+ If null, SSH will use its regular known-hosts file when connecting.
324+ '';
325+ };
326 };
327+ });
328+ default = [ ];
329 description = ''
330 This option lists the machines to be used if distributed builds are
331 enabled (see <option>nix.distributedBuilds</option>).
···339 envVars = mkOption {
340 type = types.attrs;
341 internal = true;
342+ default = { };
343 description = "Environment variables used by Nix.";
344 };
345···364 '';
365 };
366000000000000000000000000000000000000000000000000000000000000000000000000000000367 nixPath = mkOption {
368 type = types.listOf types.str;
369+ default = [
370+ "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos"
371+ "nixos-config=/etc/nixos/configuration.nix"
372+ "/nix/var/nix/profiles/per-user/root/channels"
373+ ];
0374 description = ''
375 The default Nix expression search path, used by the Nix
376 evaluator to look up paths enclosed in angle brackets
···378 '';
379 };
38000000000381 checkConfig = mkOption {
382 type = types.bool;
383 default = true;
384 description = ''
385+ If enabled (the default), checks for data type mismatches and that Nix
386+ can parse the generated nix.conf.
387 '';
388 };
389390 registry = mkOption {
391 type = types.attrsOf (types.submodule (
392 let
393+ referenceAttrs = with types; attrsOf (oneOf [
394+ str
395+ int
396+ bool
397+ package
398+ ]);
399 in
400 { config, name, ... }:
401+ {
402+ options = {
403 from = mkOption {
404+ type = referenceAttrs;
405 example = { type = "indirect"; id = "nixpkgs"; };
406 description = "The flake reference to be rewritten.";
407 };
408 to = mkOption {
409+ type = referenceAttrs;
410 example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; };
411+ description = "The flake reference <option>from></option> is rewritten to.";
412 };
413 flake = mkOption {
414 type = types.nullOr types.attrs;
415 default = null;
416 example = literalExpression "nixpkgs";
417 description = ''
418+ The flake input <option>from></option> is rewritten to.
419 '';
420 };
421 exact = mkOption {
···430 };
431 config = {
432 from = mkDefault { type = "indirect"; id = name; };
433+ to = mkIf (config.flake != null) (mkDefault
434+ {
435+ type = "path";
436+ path = config.flake.outPath;
437+ } // filterAttrs
438+ (n: _: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash")
439+ config.flake);
440 };
441 }
442 ));
443+ default = { };
444 description = ''
445 A system-wide flake registry.
446 '';
447 };
448449+ extraOptions = mkOption {
450+ type = types.lines;
451+ default = "";
452+ example = ''
453+ keep-outputs = true
454+ keep-derivations = true
455+ '';
456+ description = "Additional text appended to <filename>nix.conf</filename>.";
457+ };
458+459+ settings = mkOption {
460+ type = types.submodule {
461+ freeformType = semanticConfType;
462+463+ options = {
464+ max-jobs = mkOption {
465+ type = types.either types.int (types.enum [ "auto" ]);
466+ default = "auto";
467+ example = 64;
468+ description = ''
469+ This option defines the maximum number of jobs that Nix will try to
470+ build in parallel. The default is auto, which means it will use all
471+ available logical cores. It is recommend to set it to the total
472+ number of logical cores in your system (e.g., 16 for two CPUs with 4
473+ cores each and hyper-threading).
474+ '';
475+ };
476+477+ auto-optimise-store = mkOption {
478+ type = types.bool;
479+ default = false;
480+ example = true;
481+ description = ''
482+ If set to true, Nix automatically detects files in the store that have
483+ identical contents, and replaces them with hard links to a single copy.
484+ This saves disk space. If set to false (the default), you can still run
485+ nix-store --optimise to get rid of duplicate files.
486+ '';
487+ };
488+489+ cores = mkOption {
490+ type = types.int;
491+ default = 0;
492+ example = 64;
493+ description = ''
494+ This option defines the maximum number of concurrent tasks during
495+ one build. It affects, e.g., -j option for make.
496+ The special value 0 means that the builder should use all
497+ available CPU cores in the system. Some builds may become
498+ non-deterministic with this option; use with care! Packages will
499+ only be affected if enableParallelBuilding is set for them.
500+ '';
501+ };
502+503+ sandbox = mkOption {
504+ type = types.either types.bool (types.enum [ "relaxed" ]);
505+ default = true;
506+ description = ''
507+ If set, Nix will perform builds in a sandboxed environment that it
508+ will set up automatically for each build. This prevents impurities
509+ in builds by disallowing access to dependencies outside of the Nix
510+ store by using network and mount namespaces in a chroot environment.
511+ This is enabled by default even though it has a possible performance
512+ impact due to the initial setup time of a sandbox for each build. It
513+ doesn't affect derivation hashes, so changing this option will not
514+ trigger a rebuild of packages.
515+ '';
516+ };
517+518+ extra-sandbox-paths = mkOption {
519+ type = types.listOf types.str;
520+ default = [ ];
521+ example = [ "/dev" "/proc" ];
522+ description = ''
523+ Directories from the host filesystem to be included
524+ in the sandbox.
525+ '';
526+ };
527528+ substituters = mkOption {
529+ type = types.listOf types.str;
530+ description = ''
531+ List of binary cache URLs used to obtain pre-built binaries
532+ of Nix packages.
533+534+ By default https://cache.nixos.org/ is added.
535+ '';
536+ };
537+538+ trusted-substituters = mkOption {
539+ type = types.listOf types.str;
540+ default = [ ];
541+ example = [ "https://hydra.nixos.org/" ];
542+ description = ''
543+ List of binary cache URLs that non-root users can use (in
544+ addition to those specified using
545+ <option>nix.settings.substituters</option>) by passing
546+ <literal>--option binary-caches</literal> to Nix commands.
547+ '';
548+ };
549+550+ require-sigs = mkOption {
551+ type = types.bool;
552+ default = true;
553+ description = ''
554+ If enabled (the default), Nix will only download binaries from binary caches if
555+ they are cryptographically signed with any of the keys listed in
556+ <option>nix.settings.trusted-public-keys</option>. If disabled, signatures are neither
557+ required nor checked, so it's strongly recommended that you use only
558+ trustworthy caches and https to prevent man-in-the-middle attacks.
559+ '';
560+ };
561+562+ trusted-public-keys = mkOption {
563+ type = types.listOf types.str;
564+ example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ];
565+ description = ''
566+ List of public keys used to sign binary caches. If
567+ <option>nix.settings.trusted-public-keys</option> is enabled,
568+ then Nix will use a binary from a binary cache if and only
569+ if it is signed by <emphasis>any</emphasis> of the keys
570+ listed here. By default, only the key for
571+ <uri>cache.nixos.org</uri> is included.
572+ '';
573+ };
574+575+ trusted-users = mkOption {
576+ type = types.listOf types.str;
577+ default = [ "root" ];
578+ example = [ "root" "alice" "@wheel" ];
579+ description = ''
580+ A list of names of users that have additional rights when
581+ connecting to the Nix daemon, such as the ability to specify
582+ additional binary caches, or to import unsigned NARs. You
583+ can also specify groups by prefixing them with
584+ <literal>@</literal>; for instance,
585+ <literal>@wheel</literal> means all users in the wheel
586+ group.
587+ '';
588+ };
589+590+ system-features = mkOption {
591+ type = types.listOf types.str;
592+ example = [ "kvm" "big-parallel" "gccarch-skylake" ];
593+ description = ''
594+ The set of features supported by the machine. Derivations
595+ can express dependencies on system features through the
596+ <literal>requiredSystemFeatures</literal> attribute.
597+598+ By default, pseudo-features <literal>nixos-test</literal>, <literal>benchmark</literal>,
599+ and <literal>big-parallel</literal> used in Nixpkgs are set, <literal>kvm</literal>
600+ is also included in it is avaliable.
601+ '';
602+ };
603+604+ allowed-users = mkOption {
605+ type = types.listOf types.str;
606+ default = [ "*" ];
607+ example = [ "@wheel" "@builders" "alice" "bob" ];
608+ description = ''
609+ A list of names of users (separated by whitespace) that are
610+ allowed to connect to the Nix daemon. As with
611+ <option>nix.settings.trusted-users</option>, you can specify groups by
612+ prefixing them with <literal>@</literal>. Also, you can
613+ allow all users by specifying <literal>*</literal>. The
614+ default is <literal>*</literal>. Note that trusted users are
615+ always allowed to connect.
616+ '';
617+ };
618+ };
619+ };
620+ default = { };
621+ example = literalExpression ''
622+ {
623+ use-sandbox = true;
624+ show-trace = true;
625+626+ system-features = [ "big-parallel" "kvm" "recursive-nix" ];
627+ sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; };
628+ }
629+ '';
630+ description = ''
631+ Configuration for Nix, see
632+ <link xlink:href="https://nixos.org/manual/nix/stable/#sec-conf-file"/> or
633+ <citerefentry>
634+ <refentrytitle>nix.conf</refentrytitle>
635+ <manvolnum>5</manvolnum>
636+ </citerefentry> for avalaible options.
637+ The value declared here will be translated directly to the key-value pairs Nix expects.
638+ </para>
639+ <para>
640+ You can use <command>nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings</command>
641+ to view the current value. By default it is empty.
642+ </para>
643+ <para>
644+ Nix configurations defined under <option>nix.*</option> will be translated and applied to this
645+ option. In addition, configuration specified in <option>nix.extraOptions</option> which will be appended
646+ verbatim to the resulting config file.
647+ '';
648+ };
649+ };
650 };
651652653 ###### implementation
654655 config = mkIf cfg.enable {
0000656 environment.systemPackages =
657+ [
658+ nixPackage
659 pkgs.nix-info
660 ]
661 ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions;
···669670 # List of machines for distributed Nix builds in the format
671 # expected by build-remote.pl.
672+ environment.etc."nix/machines" = mkIf (cfg.buildMachines != [ ]) {
673+ text =
674+ concatMapStrings
675+ (machine:
676+ (concatStringsSep " " ([
677+ "${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}"
678+ (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-")
679+ (if machine.sshKey != null then machine.sshKey else "-")
680+ (toString machine.maxJobs)
681+ (toString machine.speedFactor)
682+ (concatStringsSep "," machine.supportedFeatures)
683+ (concatStringsSep "," machine.mandatoryFeatures)
684+ ]
685+ ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-")))
686 + "\n"
687+ )
688+ cfg.buildMachines;
689+ };
690+691 assertions =
692+ let badMachine = m: m.system == null && m.systems == [ ];
693+ in
694+ [
695 {
696+ assertion = !(any badMachine cfg.buildMachines);
697 message = ''
698 At least one system type (via <varname>system</varname> or
699 <varname>systems</varname>) must be set for every build machine.
700 Invalid machine specifications:
701 '' + " " +
702+ (concatStringsSep "\n "
703+ (map (m: m.hostName)
704+ (filter (badMachine) cfg.buildMachines)));
705 }
706 ];
707708+ systemd.packages = [ nixPackage ];
0709710 systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ];
711712 systemd.services.nix-daemon =
713+ {
714+ path = [ nixPackage pkgs.util-linux config.programs.ssh.package ]
715 ++ optionals cfg.distributedBuilds [ pkgs.gzip ];
716717 environment = cfg.envVars
···721 unitConfig.RequiresMountsFor = "/nix/store";
722723 serviceConfig =
724+ {
725+ CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy;
726 IOSchedulingClass = cfg.daemonIOSchedClass;
727 IOSchedulingPriority = cfg.daemonIOSchedPriority;
728 LimitNOFILE = 4096;
···732 };
733734 # Set up the environment variables for running Nix.
735+ environment.sessionVariables = cfg.envVars // { NIX_PATH = cfg.nixPath; };
00736737 environment.extraInit =
738 ''
···741 fi
742 '';
743744+ nix.nrBuildUsers = mkDefault (max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs));
745746 users.users = nixbldUsers;
747···757 fi
758 '';
759760+ # Legacy configuration conversion.
761+ nix.settings = mkMerge [
762+ {
763+ trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ];
764+ substituters = [ "https://cache.nixos.org/" ];
765+766+ system-features = mkDefault (
767+ [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++
768+ optionals (pkgs.hostPlatform ? gcc.arch) (
769+ # a builder can run code for `gcc.arch` and inferior architectures
770+ [ "gccarch-${pkgs.hostPlatform.gcc.arch}" ] ++
771+ map (x: "gccarch-${x}") systems.architectures.inferiors.${pkgs.hostPlatform.gcc.arch}
772+ )
773+ );
774+ }
775+776+ (mkIf (!cfg.distributedBuilds) { builders = null; })
777+778+ (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; })
779+ ];
780781 };
782
+1-1
nixos/modules/services/misc/nix-ssh-serve.nix
···20 write = mkOption {
21 type = types.bool;
22 default = false;
23- description = "Whether to enable writing to the Nix store as a remote store via SSH. Note: the sshServe user is named nix-ssh and is not a trusted-user. nix-ssh should be added to the nix.trustedUsers option in most use cases, such as allowing remote building of derivations.";
24 };
2526 keys = mkOption {
···20 write = mkOption {
21 type = types.bool;
22 default = false;
23+ description = "Whether to enable writing to the Nix store as a remote store via SSH. Note: the sshServe user is named nix-ssh and is not a trusted-user. nix-ssh should be added to the <option>nix.settings.trusted-users</option> option in most use cases, such as allowing remote building of derivations.";
24 };
2526 keys = mkOption {
···23use strict;
4use warnings;
05use File::Path qw(make_path);
6use File::Basename;
7use File::Slurp;
···113 return ($fss, $swaps);
114}
115000000000000000000000000000000000000000000000000116sub parseUnit {
117- my ($filename) = @_;
118- my $info = {};
119- parseKeyValues($info, read_file($filename)) if -f $filename;
120- parseKeyValues($info, read_file("${filename}.d/overrides.conf")) if -f "${filename}.d/overrides.conf";
121- return $info;
0122}
123124-sub parseKeyValues {
125- my $info = shift;
126- foreach my $line (@_) {
127- # FIXME: not quite correct.
128- $line =~ /^([^=]+)=(.*)$/ or next;
129- $info->{$1} = $2;
000130 }
131-}
132-133-sub boolIsTrue {
134- my ($s) = @_;
135- return $s eq "yes" || $s eq "true";
136}
137138sub recordUnit {
···167 # Revert of the attempt: https://github.com/NixOS/nixpkgs/pull/147609
168 # More details: https://github.com/NixOS/nixpkgs/issues/74899#issuecomment-981142430
169 } else {
170- my $unitInfo = parseUnit($newUnitFile);
171- if (boolIsTrue($unitInfo->{'X-ReloadIfChanged'} // "no")) {
172 $unitsToReload->{$unit} = 1;
173 recordUnit($reloadListFile, $unit);
174 }
175- elsif (!boolIsTrue($unitInfo->{'X-RestartIfChanged'} // "yes") || boolIsTrue($unitInfo->{'RefuseManualStop'} // "no") || boolIsTrue($unitInfo->{'X-OnlyManualStart'} // "no")) {
176 $unitsToSkip->{$unit} = 1;
177 } else {
178 # It doesn't make sense to stop and start non-services because
179 # they can't have ExecStop=
180- if (!boolIsTrue($unitInfo->{'X-StopIfChanged'} // "yes") || $unit !~ /\.service$/) {
181 # This unit should be restarted instead of
182 # stopped and started.
183 $unitsToRestart->{$unit} = 1;
···188 # socket(s) instead of the service.
189 my $socketActivated = 0;
190 if ($unit =~ /\.service$/) {
191- my @sockets = split / /, ($unitInfo->{Sockets} // "");
192 if (scalar @sockets == 0) {
193 @sockets = ("$baseName.socket");
194 }
···254255 if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
256 if (! -e $newUnitFile || abs_path($newUnitFile) eq "/dev/null") {
257- my $unitInfo = parseUnit($prevUnitFile);
258- $unitsToStop{$unit} = 1 if boolIsTrue($unitInfo->{'X-StopOnRemoval'} // "yes");
259 }
260261 elsif ($unit =~ /\.target$/) {
262- my $unitInfo = parseUnit($newUnitFile);
263264 # Cause all active target units to be restarted below.
265 # This should start most changed units we stop here as
···268 # active after the system has resumed, which probably
269 # should not be the case. Just ignore it.
270 if ($unit ne "suspend.target" && $unit ne "hibernate.target" && $unit ne "hybrid-sleep.target") {
271- unless (boolIsTrue($unitInfo->{'RefuseManualStart'} // "no") || boolIsTrue($unitInfo->{'X-OnlyManualStart'} // "no")) {
272 $unitsToStart{$unit} = 1;
273 recordUnit($startListFile, $unit);
274 # Don't spam the user with target units that always get started.
···287 # Stopping a target generally has no effect on other units
288 # (unless there is a PartOf dependency), so this is just a
289 # bookkeeping thing to get systemd to do the right thing.
290- if (boolIsTrue($unitInfo->{'X-StopOnReconfiguration'} // "no")) {
291 $unitsToStop{$unit} = 1;
292 }
293 }
···546while (my ($unit, $state) = each %{$activeNew}) {
547 if ($state->{state} eq "failed") {
548 push @failed, $unit;
0549 }
550- elsif ($state->{state} eq "auto-restart") {
551- # A unit in auto-restart state is a failure *if* it previously failed to start
552- my $lines = `@systemd@/bin/systemctl show '$unit'`;
553- my $info = {};
554- parseKeyValues($info, split("\n", $lines));
555556- if ($info->{ExecMainStatus} ne '0') {
00000557 push @failed, $unit;
0558 }
559 }
0560 # Ignore scopes since they are not managed by this script but rather
561 # created and managed by third-party services via the systemd dbus API.
562- elsif ($state->{state} ne "failed" && !defined $activePrev->{$unit} && $unit !~ /\.scope$/) {
0563 push @new, $unit;
564 }
565}
566567-print STDERR "the following new units were started: ", join(", ", sort(@new)), "\n"
568- if scalar @new > 0;
0569570if (scalar @failed > 0) {
571- print STDERR "warning: the following units failed: ", join(", ", sort(@failed)), "\n";
572- foreach my $unit (@failed) {
573- print STDERR "\n";
574- system("COLUMNS=1000 @systemd@/bin/systemctl status --no-pager '$unit' >&2");
575- }
576 $res = 4;
577}
578
···23use strict;
4use warnings;
5+use Config::IniFiles;
6use File::Path qw(make_path);
7use File::Basename;
8use File::Slurp;
···114 return ($fss, $swaps);
115}
116117+# This subroutine takes a single ini file that specified systemd configuration
118+# like unit configuration and parses it into a hash where the keys are the sections
119+# of the unit file and the values are hashes themselves. These hashes have the unit file
120+# keys as their keys (left side of =) and an array of all values that were set as their
121+# values. If a value is empty (for example `ExecStart=`), then all current definitions are
122+# removed.
123+#
124+# Instead of returning the hash, this subroutine takes a hashref to return the data in. This
125+# allows calling the subroutine multiple times with the same hash to parse override files.
126+sub parseSystemdIni {
127+ my ($unitContents, $path) = @_;
128+ # Tie the ini file to a hash for easier access
129+ my %fileContents;
130+ tie %fileContents, "Config::IniFiles", (-file => $path, -allowempty => 1, -allowcontinue => 1);
131+132+ # Copy over all sections
133+ foreach my $sectionName (keys %fileContents) {
134+ # Copy over all keys
135+ foreach my $iniKey (keys %{$fileContents{$sectionName}}) {
136+ # Ensure the value is an array so it's easier to work with
137+ my $iniValue = $fileContents{$sectionName}{$iniKey};
138+ my @iniValues;
139+ if (ref($iniValue) eq "ARRAY") {
140+ @iniValues = @{$iniValue};
141+ } else {
142+ @iniValues = $iniValue;
143+ }
144+ # Go over all values
145+ for my $iniValue (@iniValues) {
146+ # If a value is empty, it's an override that tells us to clean the value
147+ if ($iniValue eq "") {
148+ delete $unitContents->{$sectionName}->{$iniKey};
149+ next;
150+ }
151+ push(@{$unitContents->{$sectionName}->{$iniKey}}, $iniValue);
152+ }
153+ }
154+ }
155+ return;
156+}
157+158+# This subroutine takes the path to a systemd configuration file (like a unit configuration),
159+# parses it, and returns a hash that contains the contents. The contents of this hash are
160+# explained in the `parseSystemdIni` subroutine. Neither the sections nor the keys inside
161+# the sections are consistently sorted.
162+#
163+# If a directory with the same basename ending in .d exists next to the unit file, it will be
164+# assumed to contain override files which will be parsed as well and handled properly.
165sub parseUnit {
166+ my ($unitPath) = @_;
167+168+ # Parse the main unit and all overrides
169+ my %unitData;
170+ parseSystemdIni(\%unitData, $_) for glob("${unitPath}{,.d/*.conf}");
171+ return %unitData;
172}
173174+# Checks whether a specified boolean in a systemd unit is true
175+# or false, with a default that is applied when the value is not set.
176+sub parseSystemdBool {
177+ my ($unitConfig, $sectionName, $boolName, $default) = @_;
178+179+ my @values = @{$unitConfig->{$sectionName}{$boolName} // []};
180+ # Return default if value is not set
181+ if (scalar @values lt 1 || not defined $values[-1]) {
182+ return $default;
183 }
184+ # If value is defined multiple times, use the last definition
185+ my $last = $values[-1];
186+ # These are valid values as of systemd.syntax(7)
187+ return $last eq "1" || $last eq "yes" || $last eq "true" || $last eq "on";
0188}
189190sub recordUnit {
···219 # Revert of the attempt: https://github.com/NixOS/nixpkgs/pull/147609
220 # More details: https://github.com/NixOS/nixpkgs/issues/74899#issuecomment-981142430
221 } else {
222+ my %unitInfo = parseUnit($newUnitFile);
223+ if (parseSystemdBool(\%unitInfo, "Service", "X-ReloadIfChanged", 0)) {
224 $unitsToReload->{$unit} = 1;
225 recordUnit($reloadListFile, $unit);
226 }
227+ elsif (!parseSystemdBool(\%unitInfo, "Service", "X-RestartIfChanged", 1) || parseSystemdBool(\%unitInfo, "Unit", "RefuseManualStop", 0) || parseSystemdBool(\%unitInfo, "Unit", "X-OnlyManualStart", 0)) {
228 $unitsToSkip->{$unit} = 1;
229 } else {
230 # It doesn't make sense to stop and start non-services because
231 # they can't have ExecStop=
232+ if (!parseSystemdBool(\%unitInfo, "Service", "X-StopIfChanged", 1) || $unit !~ /\.service$/) {
233 # This unit should be restarted instead of
234 # stopped and started.
235 $unitsToRestart->{$unit} = 1;
···240 # socket(s) instead of the service.
241 my $socketActivated = 0;
242 if ($unit =~ /\.service$/) {
243+ my @sockets = split(/ /, join(" ", @{$unitInfo{Service}{Sockets} // []}));
244 if (scalar @sockets == 0) {
245 @sockets = ("$baseName.socket");
246 }
···306307 if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
308 if (! -e $newUnitFile || abs_path($newUnitFile) eq "/dev/null") {
309+ my %unitInfo = parseUnit($prevUnitFile);
310+ $unitsToStop{$unit} = 1 if parseSystemdBool(\%unitInfo, "Unit", "X-StopOnRemoval", 1);
311 }
312313 elsif ($unit =~ /\.target$/) {
314+ my %unitInfo = parseUnit($newUnitFile);
315316 # Cause all active target units to be restarted below.
317 # This should start most changed units we stop here as
···320 # active after the system has resumed, which probably
321 # should not be the case. Just ignore it.
322 if ($unit ne "suspend.target" && $unit ne "hibernate.target" && $unit ne "hybrid-sleep.target") {
323+ unless (parseSystemdBool(\%unitInfo, "Unit", "RefuseManualStart", 0) || parseSystemdBool(\%unitInfo, "Unit", "X-OnlyManualStart", 0)) {
324 $unitsToStart{$unit} = 1;
325 recordUnit($startListFile, $unit);
326 # Don't spam the user with target units that always get started.
···339 # Stopping a target generally has no effect on other units
340 # (unless there is a PartOf dependency), so this is just a
341 # bookkeeping thing to get systemd to do the right thing.
342+ if (parseSystemdBool(\%unitInfo, "Unit", "X-StopOnReconfiguration", 0)) {
343 $unitsToStop{$unit} = 1;
344 }
345 }
···598while (my ($unit, $state) = each %{$activeNew}) {
599 if ($state->{state} eq "failed") {
600 push @failed, $unit;
601+ next;
602 }
00000603604+ if ($state->{substate} eq "auto-restart") {
605+ # A unit in auto-restart substate is a failure *if* it previously failed to start
606+ my $main_status = `@systemd@/bin/systemctl show --value --property=ExecMainStatus '$unit'`;
607+ chomp($main_status);
608+609+ if ($main_status ne "0") {
610 push @failed, $unit;
611+ next;
612 }
613 }
614+615 # Ignore scopes since they are not managed by this script but rather
616 # created and managed by third-party services via the systemd dbus API.
617+ # This only lists units that are not failed (including ones that are in auto-restart but have not failed previously)
618+ if ($state->{state} ne "failed" && !defined $activePrev->{$unit} && $unit !~ /\.scope$/msx) {
619 push @new, $unit;
620 }
621}
622623+if (scalar @new > 0) {
624+ print STDERR "the following new units were started: ", join(", ", sort(@new)), "\n"
625+}
626627if (scalar @failed > 0) {
628+ my @failed_sorted = sort @failed;
629+ print STDERR "warning: the following units failed: ", join(", ", @failed_sorted), "\n\n";
630+ system "@systemd@/bin/systemctl status --no-pager --full '" . join("' '", @failed_sorted) . "' >&2";
00631 $res = 4;
632}
633
+2-2
nixos/modules/system/activation/top-level.nix
···117 configurationName = config.boot.loader.grub.configurationName;
118119 # Needed by switch-to-configuration.
120- perl = pkgs.perl.withPackages (p: with p; [ FileSlurp NetDBus XMLParser XMLTwig ]);
121 };
122123 # Handle assertions and warnings
···156157 specialisation = mkOption {
158 default = {};
159- example = lib.literalExpression "{ fewJobsManyCores.configuration = { nix.buildCores = 0; nix.maxJobs = 1; }; }";
160 description = ''
161 Additional configurations to build. If
162 <literal>inheritParentConfig</literal> is true, the system
···117 configurationName = config.boot.loader.grub.configurationName;
118119 # Needed by switch-to-configuration.
120+ perl = pkgs.perl.withPackages (p: with p; [ FileSlurp NetDBus XMLParser XMLTwig ConfigIniFiles ]);
121 };
122123 # Handle assertions and warnings
···156157 specialisation = mkOption {
158 default = {};
159+ example = lib.literalExpression "{ fewJobsManyCores.configuration = { nix.settings = { core = 0; max-jobs = 1; }; }";
160 description = ''
161 Additional configurations to build. If
162 <literal>inheritParentConfig</literal> is true, the system
···1011 # XXX: Sandbox setup fails while trying to hardlink files from the host's
12 # store file system into the prepared chroot directory.
13- nix.useSandbox = false;
14- nix.binaryCaches = []; # don't try to access cache.nixos.org
1516 virtualisation.writableStore = true;
17 # Make sure we always have all the required dependencies for creating a
···1011 # XXX: Sandbox setup fails while trying to hardlink files from the host's
12 # store file system into the prepared chroot directory.
13+ nix.settings.sandbox = false;
14+ nix.settings.substituters = []; # don't try to access cache.nixos.org
1516 virtualisation.writableStore = true;
17 # Make sure we always have all the required dependencies for creating a
···43 # vda is a filesystem without partition table
44 forceInstall = true;
45 };
46- nix.binaryCaches = lib.mkForce [ ];
47- nix.extraOptions = ''
48- hashed-mirrors =
49- connect-timeout = 1
50- '';
51 # save some memory
52 documentation.enable = false;
53 };
···43 # vda is a filesystem without partition table
44 forceInstall = true;
45 };
46+ nix.settings = {
47+ substituters = lib.mkForce [];
48+ hashed-mirrors = null;
49+ connect-timeout = 1;
50+ };
51 # save some memory
52 documentation.enable = false;
53 };
+77-2
nixos/tests/switch-test.nix
···45 systemd.services.test.restartIfChanged = false;
46 };
47000000000000000000000000048 restart-and-reload-by-activation-script.configuration = {
49 systemd.services = rec {
50 simple-service = {
···189 exec env -i "$@" | tee /dev/stderr
190 '';
191 in /* python */ ''
192- def switch_to_specialisation(system, name, action="test"):
193 if name == "":
194 stc = f"{system}/bin/switch-to-configuration"
195 else:
196 stc = f"{system}/specialisation/{name}/bin/switch-to-configuration"
197- out = machine.succeed(f"{stc} {action} 2>&1")
0198 assert_lacks(out, "switch-to-configuration line") # Perl warnings
199 return out
200···305 assert_lacks(out, "as well:")
306 assert_contains(out, "would start the following units: test.service\n")
307000000000000000000000000000000000000000000000000308 with subtest("restart and reload by activation script"):
0309 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script")
310 assert_contains(out, "stopping the following units: test.service\n")
311 assert_lacks(out, "NOT restarting the following changed units:")
···45 systemd.services.test.restartIfChanged = false;
46 };
4748+ simpleServiceFailing.configuration = {
49+ imports = [ simpleServiceModified.configuration ];
50+ systemd.services.test.serviceConfig.ExecStart = lib.mkForce "${pkgs.coreutils}/bin/false";
51+ };
52+53+ autorestartService.configuration = {
54+ # A service that immediately goes into restarting (but without failing)
55+ systemd.services.autorestart = {
56+ wantedBy = [ "multi-user.target" ];
57+ serviceConfig = {
58+ Type = "simple";
59+ Restart = "always";
60+ RestartSec = "20y"; # Should be long enough
61+ ExecStart = "${pkgs.coreutils}/bin/true";
62+ };
63+ };
64+ };
65+66+ autorestartServiceFailing.configuration = {
67+ imports = [ autorestartService.configuration ];
68+ systemd.services.autorestart.serviceConfig = {
69+ ExecStart = lib.mkForce "${pkgs.coreutils}/bin/false";
70+ };
71+ };
72+73 restart-and-reload-by-activation-script.configuration = {
74 systemd.services = rec {
75 simple-service = {
···214 exec env -i "$@" | tee /dev/stderr
215 '';
216 in /* python */ ''
217+ def switch_to_specialisation(system, name, action="test", fail=False):
218 if name == "":
219 stc = f"{system}/bin/switch-to-configuration"
220 else:
221 stc = f"{system}/specialisation/{name}/bin/switch-to-configuration"
222+ out = machine.fail(f"{stc} {action} 2>&1") if fail \
223+ else machine.succeed(f"{stc} {action} 2>&1")
224 assert_lacks(out, "switch-to-configuration line") # Perl warnings
225 return out
226···331 assert_lacks(out, "as well:")
332 assert_contains(out, "would start the following units: test.service\n")
333334+ with subtest("failing units"):
335+ # Let the simple service fail
336+ switch_to_specialisation("${machine}", "simpleServiceModified")
337+ out = switch_to_specialisation("${machine}", "simpleServiceFailing", fail=True)
338+ assert_contains(out, "stopping the following units: test.service\n")
339+ assert_lacks(out, "NOT restarting the following changed units:")
340+ assert_lacks(out, "reloading the following units:")
341+ assert_lacks(out, "\nrestarting the following units:")
342+ assert_contains(out, "\nstarting the following units: test.service\n")
343+ assert_lacks(out, "the following new units were started:")
344+ assert_contains(out, "warning: the following units failed: test.service\n")
345+ assert_contains(out, "Main PID:") # output of systemctl
346+ assert_lacks(out, "as well:")
347+348+ # A unit that gets into autorestart without failing is not treated as failed
349+ out = switch_to_specialisation("${machine}", "autorestartService")
350+ assert_lacks(out, "stopping the following units:")
351+ assert_lacks(out, "NOT restarting the following changed units:")
352+ assert_lacks(out, "reloading the following units:")
353+ assert_lacks(out, "\nrestarting the following units:")
354+ assert_lacks(out, "\nstarting the following units:")
355+ assert_contains(out, "the following new units were started: autorestart.service\n")
356+ assert_lacks(out, "as well:")
357+ machine.systemctl('stop autorestart.service') # cancel the 20y timer
358+359+ # Switching to the same system should do nothing (especially not treat the unit as failed)
360+ out = switch_to_specialisation("${machine}", "autorestartService")
361+ assert_lacks(out, "stopping the following units:")
362+ assert_lacks(out, "NOT restarting the following changed units:")
363+ assert_lacks(out, "reloading the following units:")
364+ assert_lacks(out, "\nrestarting the following units:")
365+ assert_lacks(out, "\nstarting the following units:")
366+ assert_contains(out, "the following new units were started: autorestart.service\n")
367+ assert_lacks(out, "as well:")
368+ machine.systemctl('stop autorestart.service') # cancel the 20y timer
369+370+ # If systemd thinks the unit has failed and is in autorestart, we should show it as failed
371+ out = switch_to_specialisation("${machine}", "autorestartServiceFailing", fail=True)
372+ assert_lacks(out, "stopping the following units:")
373+ assert_lacks(out, "NOT restarting the following changed units:")
374+ assert_lacks(out, "reloading the following units:")
375+ assert_lacks(out, "\nrestarting the following units:")
376+ assert_lacks(out, "\nstarting the following units:")
377+ assert_lacks(out, "the following new units were started:")
378+ assert_contains(out, "warning: the following units failed: autorestart.service\n")
379+ assert_contains(out, "Main PID:") # output of systemctl
380+ assert_lacks(out, "as well:")
381+382 with subtest("restart and reload by activation script"):
383+ switch_to_specialisation("${machine}", "simpleServiceNorestart")
384 out = switch_to_specialisation("${machine}", "restart-and-reload-by-activation-script")
385 assert_contains(out, "stopping the following units: test.service\n")
386 assert_lacks(out, "NOT restarting the following changed units:")
···108 gappsWrapperArgs+=(
109 # Add gio to PATH so that moving files to the trash works when not using a desktop environment
110 --prefix PATH : ${glib.bin}/bin
0111 )
112 '';
113
···108 gappsWrapperArgs+=(
109 # Add gio to PATH so that moving files to the trash works when not using a desktop environment
110 --prefix PATH : ${glib.bin}/bin
111+ --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}"
112 )
113 '';
114
···2425in stdenv.mkDerivation rec {
26 pname = "signal-desktop";
27- version = "5.27.1"; # Please backport all updates to the stable channel.
28 # All releases have a limited lifetime and "expire" 90 days after the release.
29 # When releases "expire" the application becomes unusable until an update is
30 # applied. The expiration date for the current release can be extracted with:
···3435 src = fetchurl {
36 url = "https://updates.signal.org/desktop/apt/pool/main/s/signal-desktop/signal-desktop_${version}_amd64.deb";
37- sha256 = "0z0v7q0rpxdx7ic78jv7wp1hq8nrfp51jjdr6d85x0hsfdj0z1mc";
38 };
3940 nativeBuildInputs = [
···123 gappsWrapperArgs+=(
124 --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ stdenv.cc.cc ] }"
125 ${customLanguageWrapperArgs}
0126 )
127128 # Fix the desktop link
···2425in stdenv.mkDerivation rec {
26 pname = "signal-desktop";
27+ version = "5.29.1"; # Please backport all updates to the stable channel.
28 # All releases have a limited lifetime and "expire" 90 days after the release.
29 # When releases "expire" the application becomes unusable until an update is
30 # applied. The expiration date for the current release can be extracted with:
···3435 src = fetchurl {
36 url = "https://updates.signal.org/desktop/apt/pool/main/s/signal-desktop/signal-desktop_${version}_amd64.deb";
37+ sha256 = "1a56mnmv0lnizmd4dl8fya3mdsy0jy5qr5bqb72m9cipq0069alc";
38 };
3940 nativeBuildInputs = [
···123 gappsWrapperArgs+=(
124 --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ stdenv.cc.cc ] }"
125 ${customLanguageWrapperArgs}
126+ --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}"
127 )
128129 # Fix the desktop link
···1-Next to file.nix we get src-for-file.nix
2-src-for-file.nix should evaluate to a flat attribute set with
3-string values.
4-It is supposed to be imported in the main expression.
5-In the ideal world it can export url, hash, version.
6-7-src-for-file.nix generation is directed by
8-src-info-for-file.nix.
9-10-Attributes:
11-12-src-info-for-file.nix:
13-14-downloadPage
15-rev (for repos)
16-baseName (default = unnamed-package)
17-sourceRegexp (default = '.*[.]tar[.].*')
18-choiceCommand (default = 'head -1')
19-versionExtractorSedScript (default = 's/.*-([0-9.]+)[.].*/\1/')
20-versionReferenceCreator (default = 's/-([0-9.]+)[.]/-${version}./')
21-mirrorSedScript (default = none)
22-23-src-for-file.nix:
24-25-advertisedUrl (its match is the check for update presence)
26-url
27-hash
28-version
29-name
···1-{
2- a=1;
3- b="text";
4- c=''
5- text
6- '';
7- d=''
8- Multi-line text with special characters -
9- like \ (backslash) and ''${} (dollar +
10- curly braces) and $ (dollar) and ' (quote)
11- and " (double quote).
12- '';
13-}
···1-update-walker is an imperative semiautomated update helper.
2-3-It runs the X.upstream file to find the freshest version of the package in
4-the specified upstream source and updates the corresponding X.nix file.
5-6-7-8-The simplest available commands:
9-10-url: set the upstream source list URL equal to $1; the default is
11-meta.downloadPage with meta.homepage fallback
12-13-dl_url_re: set the regular expression used to select download links to $1; the
14-default is meta.downloadURLRegexp or '[.]tar[.]([^./])+\$' if it is not set
15-16-target: specify target expression; default is to replace .upstream extension
17-with .nix extension
18-19-name: specify the derivation name; default is the basename of the dirname
20-of the .upstream file
21-22-attribute_name: specify the attribute name to evaluate for getting the current
23-version from meta.version; default is to use the derivation name
24-25-minimize_overwrite: set config options that mean that only version= and
26-sha256= have to be replaced; the default is to regenerate a full upstream
27-description block with url, name, version, hash etc.
28-29-30-31-A lot of packages can be updated in a pseudo-declarative style using only
32-the commands from the previous paragraph.
33-34-Some packages do not need any non-default settings, in these case just setting
35-meta.updateWalker to true is enough, you can run update-walker directly on the
36-.nix file afterwards. In this case minimize_overwrite it implied unless
37-meta.fullRegenerate is set.
38-39-40-41-The packages that require more fine-grained control than the described options
42-allow, you need to take into account the default control flow of the tool.
43-44-First, the definitions from update-walker script and additional definitions
45-from update-walker-service-specific.sh are loaded. Then the config is executed
46-as a shell script. Some of the commands it can use do remember whether they
47-have been used. Afterwards the following steps happen:
48-49-attribute_name is set to name unless it has been already set
50-51-meta.version is read from the NixPkgs package called attribute_name
52-53-download URL regexp is set to default unless it has been already set in the
54-updater script
55-56-the download page URL gets set to default value unless it has been set
57-previously
58-59-if the action of getting the download page and choosing the freshest link by
60-version has not yet been taken, it happens
61-62-if the version has not yet been extracted from the URL, it gets extracted
63-64-target nix expression to update gets set to the default value unless it has
65-been set explicitly
66-67-if the URL version is fresher than the packaged version, the new file gets
68-downloaded and its hash is calculated
69-70-do_overwrite function is called; the default calculates a big upstream data
71-block and puts it after the '# Generated upstream information' marker (the
72-marker can be changed by the command marker)
73-74-75-76-If the update needs some special logic, it is put into the updater script and
77-the corresponding steps are skipped because the needed action has already been
78-performed.
79-80-For example:
81-82-minimize_overwrite is exactly the same as
83-84-do_overwrite() { do_overwrite_just_version; }
85-86-redefinition. You can do a more complex do_overwrite redifinition, if needed.
87-It can probably use ensure_hash to download the source and calculate the hash
88-and set_var_value.
89-90-set_var_value alters the $3-th instance of assigning the $1 name in the
91-expression to the value $2. $3 defaults to 1. It can modify $4 instead of the
92-current target, it can put the value without quotes if $5 is 1.
93-94-95-96-Typical steps include:
97-98-ensure_choice: download current URL and find the freshest version link on the
99-page, it is now the new URL
100-101-ensure_hash: download current URL and calculate the source package hash
102-103-ensure_version: extract version from the URL
104-105-SF_redirect: replace the current URL with a SourceForge.net mirror:// URL
106-107-SF_version_dir: assume SourceForge.net layout and choose the freshest
108-version-named subdirectory in the file catalog; you can optionally specify $1
109-as a directory name regexp (digits and periods will be required after it)
110-111-SF_version_tarball: assume SourceForge.net layout and choose the freshest
112-tarball download link
113-114-version: apply replacement of $1 with $2 (extended regexp format) to extract
115-the version from URL
116-117-version_link: choose the freshest versioned link, $1 is the regexp of
118-acceptable links
···6263 hardeningDisable = [ "format" ];
6465- CXXFLAGS = "-fpermissive";
00006667 # - Unset CC and CXX as they confuse libtool.
68 # - teach gdal that libdf is the legacy name for libhdf
···6263 hardeningDisable = [ "format" ];
6465+ CXXFLAGS = lib.concatStringsSep " " [
66+ "-fpermissive"
67+ # poppler uses std::optional
68+ "-std=c++17"
69+ ];
7071 # - Unset CC and CXX as they confuse libtool.
72 # - teach gdal that libdf is the legacy name for libhdf
···8 sha256 = "1y0gikds2nr8jk8smhrl617njk23ymmpxyjb2j1xbj0k82xspv78";
9 };
1011- passthru = {
12- updateScript = ''
13- #!${runtimeShell}
14- cd ${toString ./.}
15- ${toString path}/pkgs/build-support/upstream-updater/update-walker.sh default.nix
16- '';
17- };
18-19- meta = {
20 description = "File open routines to safely open a file when in the presence of an attack";
21- license = lib.licenses.asl20 ;
22- maintainers = [lib.maintainers.raskin];
23- platforms = lib.platforms.all;
24 homepage = "https://research.cs.wisc.edu/mist/safefile/";
25- updateWalker = true;
26 };
27}
···8 sha256 = "1y0gikds2nr8jk8smhrl617njk23ymmpxyjb2j1xbj0k82xspv78";
9 };
1011+ meta = with lib; {
0000000012 description = "File open routines to safely open a file when in the presence of an attack";
13+ license = licenses.asl20;
14+ maintainers = with maintainers; [ raskin ];
15+ platforms = platforms.all;
16 homepage = "https://research.cs.wisc.edu/mist/safefile/";
017 };
18}
···73 description = "XML Security Library in C based on libxml2";
74 license = lib.licenses.mit;
75 platforms = with lib.platforms; linux ++ darwin;
76- updateWalker = true;
77 };
78}
79)
···73 description = "XML Security Library in C based on libxml2";
74 license = lib.licenses.mit;
75 platforms = with lib.platforms; linux ++ darwin;
076 };
77}
78)
···1+diff --git a/pthread_stop_world.c b/pthread_stop_world.c
2+index 4b2c429..1fb4c52 100644
3+--- a/pthread_stop_world.c
4++++ b/pthread_stop_world.c
5+@@ -673,6 +673,8 @@ GC_INNER void GC_push_all_stacks(void)
6+ struct GC_traced_stack_sect_s *traced_stack_sect;
7+ pthread_t self = pthread_self();
8+ word total_size = 0;
9++ size_t stack_limit;
10++ pthread_attr_t pattr;
11+12+ if (!EXPECT(GC_thr_initialized, TRUE))
13+ GC_thr_init();
14+@@ -722,6 +724,31 @@ GC_INNER void GC_push_all_stacks(void)
15+ hi = p->altstack + p->altstack_size;
16+ /* FIXME: Need to scan the normal stack too, but how ? */
17+ /* FIXME: Assume stack grows down */
18++ } else {
19++ if (pthread_getattr_np(p->id, &pattr)) {
20++ ABORT("GC_push_all_stacks: pthread_getattr_np failed!");
21++ }
22++ if (pthread_attr_getstacksize(&pattr, &stack_limit)) {
23++ ABORT("GC_push_all_stacks: pthread_attr_getstacksize failed!");
24++ }
25++ if (pthread_attr_destroy(&pattr)) {
26++ ABORT("GC_push_all_stacks: pthread_attr_destroy failed!");
27++ }
28++ // When a thread goes into a coroutine, we lose its original sp until
29++ // control flow returns to the thread.
30++ // While in the coroutine, the sp points outside the thread stack,
31++ // so we can detect this and push the entire thread stack instead,
32++ // as an approximation.
33++ // We assume that the coroutine has similarly added its entire stack.
34++ // This could be made accurate by cooperating with the application
35++ // via new functions and/or callbacks.
36++ #ifndef STACK_GROWS_UP
37++ if (lo >= hi || lo < hi - stack_limit) { // sp outside stack
38++ lo = hi - stack_limit;
39++ }
40++ #else
41++ #error "STACK_GROWS_UP not supported in boost_coroutine2 (as of june 2021), so we don't support it in Nix."
42++ #endif
43+ }
44+ GC_push_all_stack_sections(lo, hi, traced_stack_sect);
45+ # ifdef STACK_GROWS_UP
···667 nilfs_utils = nilfs-utils; # added 2018-04-25
668 nix-direnv-flakes = nix-direnv;
669 nix-review = nixpkgs-review; # added 2019-12-22
670- nixFlakes = nixStable; # added 2021-05-21
000000671 nmap_graphical = nmap-graphical; # added 2017-01-19
672 nmap-unfree = nmap; # added 2021-04-06
673 nologin = shadow; # added 2018-04-25
···1033 tftp_hpa = tftp-hpa; # added 2015-04-03
1034 timescale-prometheus = promscale; # added 2020-09-29
1035 timetable = throw "timetable has been removed, as the upstream project has been abandoned"; # added 2021-09-05
01036 tomcat7 = throw "tomcat7 has been removed from nixpkgs as it has reached end of life."; # added 2021-06-16
1037 tomcat8 = throw "tomcat8 has been removed from nixpkgs as it has reached end of life."; # added 2021-06-16
1038 tomcat85 = throw "tomcat85 has been removed from nixpkgs as it has reached end of life."; # added 2020-03-11
···667 nilfs_utils = nilfs-utils; # added 2018-04-25
668 nix-direnv-flakes = nix-direnv;
669 nix-review = nixpkgs-review; # added 2019-12-22
670+ nixFlakes = nixVersions.stable; # added 2021-05-21
671+ nixStable = nixVersions.stable; # added 2022-01-24
672+ nixUnstable = nixVersions.unstable; # added 2022-01-26
673+ nix_2_3 = nixVersions.nix_2_3;
674+ nix_2_4 = nixVersions.nix_2_4;
675+ nix_2_5 = nixVersions.nix_2_5;
676+ nix_2_6 = nixVersions.nix_2_6;
677 nmap_graphical = nmap-graphical; # added 2017-01-19
678 nmap-unfree = nmap; # added 2021-04-06
679 nologin = shadow; # added 2018-04-25
···1039 tftp_hpa = tftp-hpa; # added 2015-04-03
1040 timescale-prometheus = promscale; # added 2020-09-29
1041 timetable = throw "timetable has been removed, as the upstream project has been abandoned"; # added 2021-09-05
1042+ tomboy = throw "tomboy is not actively developed anymore and was removed."; # added 2022-01-27
1043 tomcat7 = throw "tomcat7 has been removed from nixpkgs as it has reached end of life."; # added 2021-06-16
1044 tomcat8 = throw "tomcat8 has been removed from nixpkgs as it has reached end of life."; # added 2021-06-16
1045 tomcat85 = throw "tomcat85 has been removed from nixpkgs as it has reached end of life."; # added 2020-03-11
···32 feature = "run <literal>checkPhase</literal> by default";
33 };
3435- path = mkOption {
36- type = types.path;
37- default = ../..;
38- defaultText = lib.literalDocBook "a path expression";
39- internal = true;
40- description = ''
41- A reference to Nixpkgs' own sources.
42-43- This is overridable in order to avoid copying sources unnecessarily,
44- as a path expression that references a store path will not short-circuit
45- to the store path itself, but copy the store path instead.
46- '';
47- };
48-49 };
5051in {