Skip to content

Commit d947011

Browse files
committed
modules/nix: use structural settings (Nix RFC 42)
Port structural settings from nixos/nix-daemon. Adjust the description based on those from previous options and the Home Manager nix.settings option.
1 parent 2301e01 commit d947011

File tree

6 files changed

+154
-39
lines changed

6 files changed

+154
-39
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22

33
## Release 23.11 (unreleased)
44

5+
* Add option `nix.settings` to support
6+
[structural `settings`](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md)
7+
for `nix.conf`.
8+
`nix.substituters` and `nix.trustedPublicKeys` are now aliases of
9+
`nix.settings.substituters` and `nix.settings.trusted-public-keys`,
10+
respectively.
11+
Nix Flakes functionality can now be enabled with
12+
`nix.settings.experimental-features = [ "nix-command" "flakes" ];`
13+
514
## Release 23.05
615

716
### New Options

modules/environment/login/nix-on-droid.nix.default

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
system.stateVersion = "23.05";
3232

3333
# Set up nix for flakes
34-
#nix.extraOptions = ''
35-
# experimental-features = nix-command flakes
36-
#'';
34+
#nix.settings.experimental-features = [ "nix-command" "flakes" ];
3735

3836
# Set your time zone
3937
#time.timeZone = "Europe/Berlin";

modules/environment/nix.nix

Lines changed: 141 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,94 @@
22

33
# Based on
44
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/nix-daemon.nix
5-
# (Copyright (c) 2003-2022 Eelco Dolstra and the Nixpkgs/NixOS contributors,
6-
# licensed under MIT License as well)
5+
# (Copyright (c) 2003-2023 Eelco Dolstra and the Nixpkgs/NixOS contributors)
6+
# and
7+
# https://github.com/nix-community/home-manager/blob/master/modules/misc/nix.nix
8+
# (Copyright (c) 2017-2023 Home Manager contributors)
9+
# both licensed under MIT License as well)
710

811
{ config, lib, pkgs, ... }:
912

1013
with lib;
1114

1215
let
1316
cfg = config.nix;
17+
1418
renameNixOpt = old: new:
1519
(mkRenamedOptionModule [ "nix" old ] [ "nix" new ]);
20+
21+
isNixAtLeast = versionAtLeast (getVersion cfg.package);
22+
23+
nixConf =
24+
assert isNixAtLeast "2.2";
25+
let
26+
27+
mkValueString = v:
28+
if v == null then ""
29+
else if isInt v then toString v
30+
else if isBool v then boolToString v
31+
else if isFloat v then floatToString v
32+
else if isList v then toString v
33+
else if isDerivation v then toString v
34+
else if builtins.isPath v then toString v
35+
else if isString v then v
36+
else if strings.isConvertibleWithToString v then toString v
37+
else abort "The nix conf value: ${toPretty {} v} can not be encoded";
38+
39+
mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
40+
41+
mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
42+
43+
in
44+
pkgs.writeTextFile {
45+
name = "nix.conf";
46+
text = ''
47+
# WARNING: this file is generated from the nix.* options in
48+
# your NixOS configuration, typically
49+
# /etc/nixos/configuration.nix. Do not edit it!
50+
${mkKeyValuePairs cfg.settings}
51+
${cfg.extraOptions}
52+
'';
53+
checkPhase = lib.optionalString cfg.checkConfig (
54+
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
55+
echo "Ignoring validation for cross-compilation"
56+
''
57+
else ''
58+
echo "Validating generated nix.conf"
59+
ln -s $out ./nix.conf
60+
set -e
61+
set +o pipefail
62+
NIX_CONF_DIR=$PWD \
63+
${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
64+
${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
65+
|& sed -e 's/^warning:/error:/' \
66+
| (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
67+
set -o pipefail
68+
''
69+
);
70+
};
71+
72+
legacyConfMappings = {
73+
substituters = "substituters";
74+
trustedPublicKeys = "trusted-public-keys";
75+
};
76+
77+
semanticConfType = with types;
78+
let
79+
confAtom = nullOr
80+
(oneOf [
81+
bool
82+
int
83+
float
84+
str
85+
path
86+
package
87+
]) // {
88+
description = "Nix config atom (null, bool, int, float, str, path or package)";
89+
};
90+
in
91+
attrsOf (either confAtom (listOf confAtom));
92+
1693
in
1794

1895
{
@@ -21,7 +98,7 @@ in
2198
(renameNixOpt "binaryCaches" "substituters")
2299
(renameNixOpt "binaryCachePublicKeys" "trustedPublicKeys")
23100
(renameNixOpt "extraConfig" "extraOptions")
24-
];
101+
] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings;
25102

26103
###### interface
27104

@@ -104,29 +181,71 @@ in
104181
description = "A system-wide flake registry.";
105182
};
106183

107-
substituters = mkOption {
108-
type = types.listOf types.str;
109-
default = [ ];
184+
extraOptions = mkOption {
185+
type = types.lines;
186+
default = "";
187+
description = "Extra config to be appended to <filename>/etc/nix/nix.conf</filename>.";
188+
};
189+
190+
checkConfig = mkOption {
191+
type = types.bool;
192+
default = true;
110193
description = ''
111-
A list of URLs of substituters. The official NixOS and Nix-on-Droid
112-
substituters are added by default.
194+
If enabled, checks that Nix can parse the generated nix.conf.
113195
'';
114196
};
115197

116-
trustedPublicKeys = mkOption {
117-
type = types.listOf types.str;
118-
default = [ ];
198+
checkAllErrors = mkOption {
199+
type = types.bool;
200+
default = true;
119201
description = ''
120-
A list of public keys. When paths are copied from another Nix store (such as a
121-
binary cache), they must be signed with one of these keys. The official NixOS
122-
and Nix-on-Droid public keys are added by default.
202+
If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings.
123203
'';
124204
};
125205

126-
extraOptions = mkOption {
127-
type = types.lines;
128-
default = "";
129-
description = "Extra config to be appended to <filename>/etc/nix/nix.conf</filename>.";
206+
settings = mkOption {
207+
type = types.submodule {
208+
freeformType = semanticConfType;
209+
210+
options = {
211+
substituters = mkOption {
212+
type = types.listOf types.str;
213+
description = ''
214+
A list of URLs of substituters. The official NixOS and Nix-on-Droid
215+
substituters are added by default.
216+
'';
217+
};
218+
219+
trusted-public-keys = mkOption {
220+
type = types.listOf types.str;
221+
description = ''
222+
A list of public keys. When paths are copied from another Nix store (such as a
223+
binary cache), they must be signed with one of these keys. The official NixOS
224+
and Nix-on-Droid public keys are added by default.
225+
'';
226+
};
227+
};
228+
};
229+
default = { };
230+
example = literalExpression ''
231+
{
232+
experimental-fetures = [ "nix-commnd" "flake" ];
233+
}
234+
'';
235+
description = ''
236+
Configuration for Nix, see
237+
<link xlink:href="https://nixos.org/manual/nix/stable/#sec-conf-file"/> or
238+
<citerefentry>
239+
<refentrytitle>nix.conf</refentrytitle>
240+
<manvolnum>5</manvolnum>
241+
</citerefentry> for available options.
242+
The value declared here will be translated directly to the key-value pairs Nix expects.
243+
</para>
244+
<para>
245+
Nix configurations defined under <option>nix.*</option> will be translated and applied to this
246+
option. In addition, configuration specified in <option>nix.extraOptions</option> will be appended
247+
verbatim to the resulting config file.
248+
'';
130249
};
131250
};
132251

@@ -138,25 +257,20 @@ in
138257
config = mkMerge [
139258
{
140259
environment.etc = {
141-
"nix/nix.conf".text = ''
142-
sandbox = false
143-
substituters = ${concatStringsSep " " cfg.substituters}
144-
trusted-public-keys = ${concatStringsSep " " cfg.trustedPublicKeys}
145-
${cfg.extraOptions}
146-
'';
147-
260+
"nix/nix.conf".source = nixConf;
148261
"nix/registry.json".text = builtins.toJSON {
149262
version = 2;
150263
flakes = mapAttrsToList (_n: v: { inherit (v) from to exact; }) cfg.registry;
151264
};
152265
};
153266

154-
nix = {
267+
nix.settings = {
268+
sandbox = false;
155269
substituters = [
156270
"https://cache.nixos.org"
157271
"https://nix-on-droid.cachix.org"
158272
];
159-
trustedPublicKeys = [
273+
trusted-public-keys = [
160274
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
161275
"nix-on-droid.cachix.org-1:56snoMJTXmDRC1Ei24CmKoUqvHJ9XCp+nidK7qkMQrU="
162276
];

templates/advanced/nix-on-droid.nix

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
system.stateVersion = "23.05";
3232

3333
# Set up nix for flakes
34-
nix.extraOptions = ''
35-
experimental-features = nix-command flakes
36-
'';
34+
nix.settings.experimental-features = [ "nix-command" "flakes" ];
3735

3836
# Set your time zone
3937
#time.timeZone = "Europe/Berlin";

templates/home-manager/nix-on-droid.nix

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
system.stateVersion = "23.05";
3232

3333
# Set up nix for flakes
34-
nix.extraOptions = ''
35-
experimental-features = nix-command flakes
36-
'';
34+
nix.settings.experimental-features = [ "nix-command" "flakes" ];
3735

3836
# Set your time zone
3937
#time.timeZone = "Europe/Berlin";

templates/minimal/nix-on-droid.nix

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
system.stateVersion = "23.05";
3232

3333
# Set up nix for flakes
34-
nix.extraOptions = ''
35-
experimental-features = nix-command flakes
36-
'';
34+
nix.settings.experimental-features = [ "nix-command" "flakes" ];
3735

3836
# Set your time zone
3937
#time.timeZone = "Europe/Berlin";

0 commit comments

Comments
 (0)