diff options
| author | Malo Bourgon <mbourgon@gmail.com> | 2022-08-13 15:11:58 -0700 |
|---|---|---|
| committer | Malo Bourgon <mbourgon@gmail.com> | 2022-08-16 10:41:51 -0700 |
| commit | a00b3836a5c60efc652bcbed83393bae13fab2af (patch) | |
| tree | 3a2b10a01b112aec270c7bfe3901b464c97564f8 /modules/nix/default.nix | |
| parent | 5f141365afa8fcdd7fc7aee65031b850118f1bc0 (diff) | |
Update `nix.settings` def and implementation to match NixOS module
Diffstat (limited to 'modules/nix/default.nix')
| -rw-r--r-- | modules/nix/default.nix | 434 |
1 files changed, 273 insertions, 161 deletions
diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 92b7d17..6735ac0 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -8,40 +8,55 @@ let nixPackage = cfg.package.out; + isNixAtLeast = versionAtLeast (getVersion nixPackage); + nixConf = + assert isNixAtLeast "2.2"; let - # If we're using sandbox for builds, then provide /bin/sh in - # the sandbox as a bind-mount to bash. This means we also need to - # include the entire closure of bash. - sh = pkgs.stdenv.shell; - binshDeps = pkgs.writeReferencesToFile sh; + + 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 isCoercibleToString 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.runCommandNoCC "nix.conf" - { preferLocalBuild = true; extraOptions = cfg.extraOptions; } + 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 = + if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then '' + echo "Ignoring validation for cross-compilation" '' - cat > $out <<END - # WARNING: this file is generated from the nix.* options in - # your NixOS configuration, typically - # /etc/nixos/configuration.nix. Do not edit it! - ${optionalString cfg.useDaemon '' - build-users-group = nixbld - ''} - max-jobs = ${toString cfg.settings.max-jobs} - auto-optimise-store = ${if cfg.settings.auto-optimise-store then "true" else "false"} - cores = ${toString cfg.settings.cores} - sandbox = ${if (builtins.isBool cfg.settings.sandbox) then boolToString cfg.settings.sandbox else cfg.settings.sandbox} - ${optionalString (cfg.settings.extra-sandbox-paths != []) '' - extra-sandbox-paths = ${toString cfg.settings.extra-sandbox-paths} - ''} - substituters = ${toString cfg.settings.substituters} - trusted-substituters = ${toString cfg.settings.trusted-substituters} - trusted-public-keys = ${toString cfg.settings.trusted-public-keys} - require-sigs = ${if cfg.settings.require-sigs then "true" else "false"} - trusted-users = ${toString cfg.settings.trusted-users} - allowed-users = ${toString cfg.settings.allowed-users} - $extraOptions - END + 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.checkConfig then "^error:" else "^error: unknown setting"}') + set -o pipefail ''; + }; legacyConfMappings = { useSandbox = "sandbox"; @@ -58,6 +73,22 @@ let # systemFeatures = "system-features"; }; + 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 { @@ -231,6 +262,15 @@ in ''; }; + checkConfig = mkOption { + type = types.bool; + default = true; + description = '' + If enabled (the default), checks for data type mismatches and that Nix + can parse the generated nix.conf. + ''; + }; + registry = mkOption { type = types.attrsOf (types.submodule ( let @@ -293,147 +333,196 @@ in description = "Additional text appended to <filename>nix.conf</filename>."; }; - settings = { - max-jobs = mkOption { - type = types.either types.int (types.enum [ "auto" ]); - default = "auto"; - example = 64; - description = '' - This option defines the maximum number of jobs that Nix will try to - build in parallel. The default is auto, which means it will use all - available logical cores. It is recommend to set it to the total - number of logical cores in your system (e.g., 16 for two CPUs with 4 - cores each and hyper-threading). - ''; - }; + settings = mkOption { + type = types.submodule { + freeformType = semanticConfType; + + options = { + max-jobs = mkOption { + type = types.either types.int (types.enum [ "auto" ]); + default = "auto"; + example = 64; + description = '' + This option defines the maximum number of jobs that Nix will try to + build in parallel. The default is auto, which means it will use all + available logical cores. It is recommend to set it to the total + number of logical cores in your system (e.g., 16 for two CPUs with 4 + cores each and hyper-threading). + ''; + }; - auto-optimise-store = mkOption { - type = types.bool; - default = false; - example = true; - description = '' - If set to true, Nix automatically detects files in the store that have - identical contents, and replaces them with hard links to a single copy. - This saves disk space. If set to false (the default), you can still run - nix-store --optimise to get rid of duplicate files. - ''; - }; + auto-optimise-store = mkOption { + type = types.bool; + default = false; + example = true; + description = '' + If set to true, Nix automatically detects files in the store that have + identical contents, and replaces them with hard links to a single copy. + This saves disk space. If set to false (the default), you can still run + nix-store --optimise to get rid of duplicate files. + ''; + }; - cores = mkOption { - type = types.int; - default = 0; - example = 64; - description = '' - This option defines the maximum number of concurrent tasks during - one build. It affects, e.g., -j option for make. - The special value 0 means that the builder should use all - available CPU cores in the system. Some builds may become - non-deterministic with this option; use with care! Packages will - only be affected if enableParallelBuilding is set for them. - ''; - }; + cores = mkOption { + type = types.int; + default = 0; + example = 64; + description = '' + This option defines the maximum number of concurrent tasks during + one build. It affects, e.g., -j option for make. + The special value 0 means that the builder should use all + available CPU cores in the system. Some builds may become + non-deterministic with this option; use with care! Packages will + only be affected if enableParallelBuilding is set for them. + ''; + }; - sandbox = mkOption { - type = types.either types.bool (types.enum [ "relaxed" ]); - default = false; - description = '' - If set, Nix will perform builds in a sandboxed environment that it - will set up automatically for each build. This prevents impurities - in builds by disallowing access to dependencies outside of the Nix - store by using network and mount namespaces in a chroot environment. - This is enabled by default even though it has a possible performance - impact due to the initial setup time of a sandbox for each build. It - doesn't affect derivation hashes, so changing this option will not - trigger a rebuild of packages. - ''; - }; + sandbox = mkOption { + type = types.either types.bool (types.enum [ "relaxed" ]); + default = false; + description = '' + If set, Nix will perform builds in a sandboxed environment that it + will set up automatically for each build. This prevents impurities + in builds by disallowing access to dependencies outside of the Nix + store by using network and mount namespaces in a chroot environment. + This is enabled by default even though it has a possible performance + impact due to the initial setup time of a sandbox for each build. It + doesn't affect derivation hashes, so changing this option will not + trigger a rebuild of packages. + ''; + }; - extra-sandbox-paths = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "/dev" "/proc" ]; - description = '' - Directories from the host filesystem to be included - in the sandbox. - ''; - }; + extra-sandbox-paths = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "/dev" "/proc" ]; + description = '' + Directories from the host filesystem to be included + in the sandbox. + ''; + }; - substituters = mkOption { - type = types.listOf types.str; - description = '' - List of binary cache URLs used to obtain pre-built binaries - of Nix packages. + substituters = mkOption { + type = types.listOf types.str; + description = '' + List of binary cache URLs used to obtain pre-built binaries + of Nix packages. - By default https://cache.nixos.org/ is added. - ''; - }; + By default https://cache.nixos.org/ is added. + ''; + }; - trusted-substituters = mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "https://hydra.nixos.org/" ]; - description = '' - List of binary cache URLs that non-root users can use (in - addition to those specified using - <option>nix.settings.substituters</option>) by passing - <literal>--option binary-caches</literal> to Nix commands. - ''; - }; + trusted-substituters = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "https://hydra.nixos.org/" ]; + description = '' + List of binary cache URLs that non-root users can use (in + addition to those specified using + <option>nix.settings.substituters</option>) by passing + <literal>--option binary-caches</literal> to Nix commands. + ''; + }; - require-sigs = mkOption { - type = types.bool; - default = true; - description = '' - If enabled (the default), Nix will only download binaries from binary caches if - they are cryptographically signed with any of the keys listed in - <option>nix.settings.trusted-public-keys</option>. If disabled, signatures are neither - required nor checked, so it's strongly recommended that you use only - trustworthy caches and https to prevent man-in-the-middle attacks. - ''; - }; + require-sigs = mkOption { + type = types.bool; + default = true; + description = '' + If enabled (the default), Nix will only download binaries from binary caches if + they are cryptographically signed with any of the keys listed in + <option>nix.settings.trusted-public-keys</option>. If disabled, signatures are neither + required nor checked, so it's strongly recommended that you use only + trustworthy caches and https to prevent man-in-the-middle attacks. + ''; + }; - trusted-public-keys = mkOption { - type = types.listOf types.str; - example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ]; - description = '' - List of public keys used to sign binary caches. If - <option>nix.settings.trusted-public-keys</option> is enabled, - then Nix will use a binary from a binary cache if and only - if it is signed by <emphasis>any</emphasis> of the keys - listed here. By default, only the key for - <uri>cache.nixos.org</uri> is included. - ''; - }; + trusted-public-keys = mkOption { + type = types.listOf types.str; + example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ]; + description = '' + List of public keys used to sign binary caches. If + <option>nix.settings.trusted-public-keys</option> is enabled, + then Nix will use a binary from a binary cache if and only + if it is signed by <emphasis>any</emphasis> of the keys + listed here. By default, only the key for + <uri>cache.nixos.org</uri> is included. + ''; + }; - trusted-users = mkOption { - type = types.listOf types.str; - default = [ "root" ]; - example = [ "root" "alice" "@wheel" ]; - description = '' - A list of names of users that have additional rights when - connecting to the Nix daemon, such as the ability to specify - additional binary caches, or to import unsigned NARs. You - can also specify groups by prefixing them with - <literal>@</literal>; for instance, - <literal>@wheel</literal> means all users in the wheel - group. - ''; - }; + trusted-users = mkOption { + type = types.listOf types.str; + default = [ "root" ]; + example = [ "root" "alice" "@wheel" ]; + description = '' + A list of names of users that have additional rights when + connecting to the Nix daemon, such as the ability to specify + additional binary caches, or to import unsigned NARs. You + can also specify groups by prefixing them with + <literal>@</literal>; for instance, + <literal>@wheel</literal> means all users in the wheel + group. + ''; + }; - allowed-users = mkOption { - type = types.listOf types.str; - default = [ "*" ]; - example = [ "@wheel" "@builders" "alice" "bob" ]; - description = '' - A list of names of users (separated by whitespace) that are - allowed to connect to the Nix daemon. As with - <option>nix.settings.trusted-users</option>, you can specify groups by - prefixing them with <literal>@</literal>. Also, you can - allow all users by specifying <literal>*</literal>. The - default is <literal>*</literal>. Note that trusted users are - always allowed to connect. - ''; + # Not implemented yet + # system-features = mkOption { + # type = types.listOf types.str; + # example = [ "kvm" "big-parallel" "gccarch-skylake" ]; + # description = '' + # The set of features supported by the machine. Derivations + # can express dependencies on system features through the + # <literal>requiredSystemFeatures</literal> attribute. + + # By default, pseudo-features <literal>nixos-test</literal>, <literal>benchmark</literal>, + # and <literal>big-parallel</literal> used in Nixpkgs are set, <literal>kvm</literal> + # is also included in it is avaliable. + # ''; + # }; + + allowed-users = mkOption { + type = types.listOf types.str; + default = [ "*" ]; + example = [ "@wheel" "@builders" "alice" "bob" ]; + description = '' + A list of names of users (separated by whitespace) that are + allowed to connect to the Nix daemon. As with + <option>nix.settings.trusted-users</option>, you can specify groups by + prefixing them with <literal>@</literal>. Also, you can + allow all users by specifying <literal>*</literal>. The + default is <literal>*</literal>. Note that trusted users are + always allowed to connect. + ''; + }; + }; }; + default = { }; + example = literalExpression '' + { + use-sandbox = true; + show-trace = true; + + system-features = [ "big-parallel" "kvm" "recursive-nix" ]; + sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; }; + } + ''; + 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 avalaible options. + The value declared here will be translated directly to the key-value pairs Nix expects. + </para> + <para> + You can use <command>nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings</command> + to view the current value. By default it is empty. + </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> which will be appended + verbatim to the resulting config file. + ''; }; }; }; @@ -448,9 +537,6 @@ in (mkIf (!cfg.distributedBuilds && cfg.buildMachines != []) "nix.distributedBuilds is not enabled, build machines won't be configured.") ]; - nix.settings.substituters = mkAfter [ https://cache.nixos.org/ ]; - nix.settings.trusted-public-keys = mkAfter [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ]; - nix.nixPath = mkMerge [ (mkIf (config.system.stateVersion < 2) (mkDefault [ "darwin=$HOME/.nix-defexpr/darwin" @@ -473,6 +559,7 @@ in environment.etc."nix/nix.conf".source = nixConf; + # Not in NixOS module environment.etc."nix/nix.conf".knownSha256Hashes = [ "7c2d80499b39256b03ee9abd3d6258343718306aca8d472c26ac32c9b0949093" # nix installer "19299897fa312d9d32b3c968c2872dd143085aa727140cec51f57c59083e93b9" @@ -526,6 +613,31 @@ in done ''; + # Legacy configuration conversion. + nix.settings = mkMerge [ + { + trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ]; + substituters = mkAfter [ "https://cache.nixos.org/" ]; + + # Not implemented yet + # system-features = mkDefault ( + # [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++ + # optionals (pkgs.hostPlatform ? gcc.arch) ( + # # a builder can run code for `gcc.arch` and inferior architectures + # [ "gccarch-${pkgs.hostPlatform.gcc.arch}" ] ++ + # map (x: "gccarch-${x}") systems.architectures.inferiors.${pkgs.hostPlatform.gcc.arch} + # ) + # ); + } + + (mkIf (!cfg.distributedBuilds) { builders = null; }) + + (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; }) + + # Not in NixOS module + (mkIf cfg.useDaemon { build-users-group = "nixbld"; }) + ]; + }; } |
