Skip to content

Commit

Permalink
modules/nix: use structural settings (Nix RFC 42)
Browse files Browse the repository at this point in the history
Port structural settings from nixos/nix-daemon.

Adjust the description based on those from previous options
and the Home Manager nix.settings option.
  • Loading branch information
ShamrockLee committed Feb 15, 2024
1 parent 82b4cd6 commit 3db1fca
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 39 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
* New options `networking.hosts`, `networking.hostFiles` and
`networking.extraHosts` for `/etc/hosts` configuration.

* Add option `nix.settings` to support
[structural `settings`](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md)
for `nix.conf`.
`nix.substituters` and `nix.trustedPublicKeys` are now aliases of
`nix.settings.substituters` and `nix.settings.trusted-public-keys`,
respectively.
Nix Flakes functionality can now be enabled with
`nix.settings.experimental-features = [ "nix-command" "flakes" ];`

## Release 23.05

### New Options
Expand Down
4 changes: 1 addition & 3 deletions modules/environment/login/nix-on-droid.nix.default
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@
system.stateVersion = "23.05";

# Set up nix for flakes
#nix.extraOptions = ''
# experimental-features = nix-command flakes
#'';
#nix.settings.experimental-features = [ "nix-command" "flakes" ];

# Set your time zone
#time.timeZone = "Europe/Berlin";
Expand Down
167 changes: 140 additions & 27 deletions modules/environment/nix.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,93 @@

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

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

with lib;

let
cfg = config.nix;

renameNixOpt = old: new:
(mkRenamedOptionModule [ "nix" old ] [ "nix" new ]);

isNixAtLeast = versionAtLeast (getVersion cfg.package);

nixConf =
let

mkValueString = v:
if v == null then ""
else if isInt v then toString v
else if isBool v then boolToString v
else if isFloat v then floatToString v
else if isList v then toString v
else if isDerivation v then toString v
else if builtins.isPath v then toString v
else if isString v then v
else if strings.isConvertibleWithToString v then toString v
else abort "The nix conf value: ${toPretty {} v} can not be encoded";

mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";

mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);

in
pkgs.writeTextFile {
name = "nix.conf";
text = ''
# WARNING: this file is generated from the nix.* options in
# your NixOS configuration, typically
# /etc/nixos/configuration.nix. Do not edit it!
${mkKeyValuePairs cfg.settings}
${cfg.extraOptions}
'';
checkPhase = lib.optionalString cfg.checkConfig (
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
echo "Ignoring validation for cross-compilation"
''
else ''
echo "Validating generated nix.conf"
ln -s $out ./nix.conf
set -e
set +o pipefail
NIX_CONF_DIR=$PWD \
${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
|& sed -e 's/^warning:/error:/' \
| (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
set -o pipefail
''
);
};

legacyConfMappings = {
substituters = "substituters";
trustedPublicKeys = "trusted-public-keys";
};

semanticConfType = with types;
let
confAtom = nullOr
(oneOf [
bool
int
float
str
path
package
]) // {
description = "Nix config atom (null, bool, int, float, str, path or package)";
};
in
attrsOf (either confAtom (listOf confAtom));

in

{
Expand All @@ -21,7 +97,7 @@ in
(renameNixOpt "binaryCaches" "substituters")
(renameNixOpt "binaryCachePublicKeys" "trustedPublicKeys")
(renameNixOpt "extraConfig" "extraOptions")
];
] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings;

###### interface

Expand Down Expand Up @@ -104,29 +180,71 @@ in
description = "A system-wide flake registry.";
};

substituters = mkOption {
type = types.listOf types.str;
default = [ ];
extraOptions = mkOption {
type = types.lines;
default = "";
description = "Extra config to be appended to <filename>/etc/nix/nix.conf</filename>.";
};

checkConfig = mkOption {
type = types.bool;
default = true;
description = ''
A list of URLs of substituters. The official NixOS and Nix-on-Droid
substituters are added by default.
If enabled, checks that Nix can parse the generated nix.conf.
'';
};

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

extraOptions = mkOption {
type = types.lines;
default = "";
description = "Extra config to be appended to <filename>/etc/nix/nix.conf</filename>.";
settings = mkOption {
type = types.submodule {
freeformType = semanticConfType;

options = {
substituters = mkOption {
type = types.listOf types.str;
description = ''
A list of URLs of substituters. The official NixOS and Nix-on-Droid
substituters are added by default.
'';
};

trusted-public-keys = mkOption {
type = types.listOf types.str;
description = ''
A list of public keys. When paths are copied from another Nix store (such as a
binary cache), they must be signed with one of these keys. The official NixOS
and Nix-on-Droid public keys are added by default.
'';
};
};
};
default = { };
example = literalExpression ''
{
experimental-fetures = [ "nix-commnd" "flake" ];
}
'';
description = ''
Configuration for Nix, see
<link xlink:href="https://nixos.org/manual/nix/stable/#sec-conf-file"/> or
<citerefentry>
<refentrytitle>nix.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for available options.
The value declared here will be translated directly to the key-value pairs Nix expects.
</para>
<para>
Nix configurations defined under <option>nix.*</option> will be translated and applied to this
option. In addition, configuration specified in <option>nix.extraOptions</option> will be appended
verbatim to the resulting config file.
'';
};
};

Expand All @@ -138,25 +256,20 @@ in
config = mkMerge [
{
environment.etc = {
"nix/nix.conf".text = ''
sandbox = false
substituters = ${concatStringsSep " " cfg.substituters}
trusted-public-keys = ${concatStringsSep " " cfg.trustedPublicKeys}
${cfg.extraOptions}
'';

"nix/nix.conf".source = nixConf;
"nix/registry.json".text = builtins.toJSON {
version = 2;
flakes = mapAttrsToList (_n: v: { inherit (v) from to exact; }) cfg.registry;
};
};

nix = {
nix.settings = {
sandbox = false;
substituters = [
"https://cache.nixos.org"
"https://nix-on-droid.cachix.org"
];
trustedPublicKeys = [
trusted-public-keys = [
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nix-on-droid.cachix.org-1:56snoMJTXmDRC1Ei24CmKoUqvHJ9XCp+nidK7qkMQrU="
];
Expand Down
4 changes: 1 addition & 3 deletions templates/advanced/nix-on-droid.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@
system.stateVersion = "23.05";

# Set up nix for flakes
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
nix.settings.experimental-features = [ "nix-command" "flakes" ];

# Set your time zone
#time.timeZone = "Europe/Berlin";
Expand Down
4 changes: 1 addition & 3 deletions templates/home-manager/nix-on-droid.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@
system.stateVersion = "23.05";

# Set up nix for flakes
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
nix.settings.experimental-features = [ "nix-command" "flakes" ];

# Set your time zone
#time.timeZone = "Europe/Berlin";
Expand Down
4 changes: 1 addition & 3 deletions templates/minimal/nix-on-droid.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@
system.stateVersion = "23.05";

# Set up nix for flakes
nix.extraOptions = ''
experimental-features = nix-command flakes
'';
nix.settings.experimental-features = [ "nix-command" "flakes" ];

# Set your time zone
#time.timeZone = "Europe/Berlin";
Expand Down

0 comments on commit 3db1fca

Please sign in to comment.