From f729a09a28043159d6221df04b343260b1314644 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 12:09:24 -0700 Subject: [PATCH 01/18] Update `nix` module to use `settings` sub options like in NixOS module Also update option definitions to match those in `nixpkgs` where it makes sense. --- modules/examples/hydra.nix | 6 +- modules/examples/lnl.nix | 8 +-- modules/nix/default.nix | 120 ++++++++++++++++++++++++------------- 3 files changed, 85 insertions(+), 49 deletions(-) diff --git a/modules/examples/hydra.nix b/modules/examples/hydra.nix index ddd9a638..15808d92 100644 --- a/modules/examples/hydra.nix +++ b/modules/examples/hydra.nix @@ -19,10 +19,10 @@ in services.nix-daemon.enable = true; - nix.binaryCaches = [ http://cache1 ]; - nix.binaryCachePublicKeys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ]; + nix.settings.substituters = [ http://cache1 ]; + nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ]; - nix.trustedUsers = [ "@admin" "@hydra" ]; + nix.settings.trusted-users = [ "@admin" "@hydra" ]; nix.extraOptions = '' pre-build-hook = diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index 281347c7..a0dd0ba5 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -93,11 +93,11 @@ log-lines = 128 ''; - nix.binaryCachePublicKeys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ]; - nix.trustedBinaryCaches = [ https://d3i7ezr9vxxsfy.cloudfront.net ]; + nix.settings.trusted-public-keys = [ "cache.daiderd.com-1:R8KOWZ8lDaLojqD+v9dzXAqGn29gEzPTTbr/GIpCTrI=" ]; + nix.settings.trusted-substituters = [ https://d3i7ezr9vxxsfy.cloudfront.net ]; - nix.useSandbox = true; - nix.sandboxPaths = [ "/private/tmp" "/private/var/tmp" "/usr/bin/env" ]; + nix.settings.sandbox = true; + nix.settings.extra-sandbox-paths = [ "/private/tmp" "/private/var/tmp" "/usr/bin/env" ]; programs.nix-index.enable = true; diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 40bd58b5..56d5597a 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -25,24 +25,44 @@ let ${optionalString cfg.useDaemon '' build-users-group = nixbld ''} - max-jobs = ${toString (cfg.maxJobs)} - cores = ${toString (cfg.buildCores)} - sandbox = ${if (builtins.isBool cfg.useSandbox) then boolToString cfg.useSandbox else cfg.useSandbox} - ${optionalString (cfg.sandboxPaths != []) '' - extra-sandbox-paths = ${toString cfg.sandboxPaths} + 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.binaryCaches} - trusted-substituters = ${toString cfg.trustedBinaryCaches} - trusted-public-keys = ${toString cfg.binaryCachePublicKeys} - require-sigs = ${if cfg.requireSignedBinaryCaches then "true" else "false"} - trusted-users = ${toString cfg.trustedUsers} - allowed-users = ${toString cfg.allowedUsers} + 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 ''; + + legacyConfMappings = { + useSandbox = "sandbox"; + buildCores = "cores"; + maxJobs = "max-jobs"; + sandboxPaths = "extra-sandbox-paths"; + binaryCaches = "substituters"; + trustedBinaryCaches = "trusted-substituters"; + binaryCachePublicKeys = "trusted-public-keys"; + autoOptimiseStore = "auto-optimise-store"; + requireSignedBinaryCaches = "require-sigs"; + trustedUsers = "trusted-users"; + allowedUsers = "allowed-users"; + # systemFeatures = "system-features"; + }; in { + imports = mapAttrsToList (oldConf: newConf: + mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ] + ) legacyConfMappings; + options = { nix.package = mkOption { type = types.either types.package types.path; @@ -74,8 +94,8 @@ in "; }; - nix.maxJobs = mkOption { - type = types.either types.int (types.enum ["auto"]); + nix.settings.max-jobs = mkOption { + type = types.either types.int (types.enum [ "auto" ]); default = "auto"; example = 64; description = '' @@ -87,7 +107,19 @@ in ''; }; - nix.buildCores = mkOption { + nix.settings.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. + ''; + }; + + nix.settings.cores = mkOption { type = types.int; default = 0; example = 64; @@ -101,26 +133,29 @@ in ''; }; - nix.useSandbox = mkOption { - type = types.either types.bool (types.enum ["relaxed"]); + nix.settings.sandbox = mkOption { + type = types.either types.bool (types.enum [ "relaxed" ]); default = false; - description = " + 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. - "; + 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. + ''; }; - nix.sandboxPaths = mkOption { + nix.settings.extra-sandbox-paths = mkOption { type = types.listOf types.str; - default = []; + default = [ ]; example = [ "/dev" "/proc" ]; - description = - '' - Directories from the host filesystem to be included - in the sandbox. - ''; + description = '' + Directories from the host filesystem to be included + in the sandbox. + ''; }; nix.extraOptions = mkOption { @@ -228,45 +263,46 @@ in ''; }; - nix.binaryCaches = mkOption { + nix.settings.substituters = mkOption { type = types.listOf types.str; - example = [ https://cache.example.org/ ]; description = '' List of binary cache URLs used to obtain pre-built binaries of Nix packages. + + By default https://cache.nixos.org/ is added. ''; }; - nix.trustedBinaryCaches = mkOption { + nix.settings.trusted-substituters = mkOption { type = types.listOf types.str; default = [ ]; - example = [ https://hydra.example.org/ ]; + example = [ "https://hydra.nixos.org/" ]; description = '' List of binary cache URLs that non-root users can use (in addition to those specified using - ) by passing + ) by passing --option binary-caches to Nix commands. ''; }; - nix.requireSignedBinaryCaches = mkOption { + nix.settings.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 - . If disabled, signatures are neither + . 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. ''; }; - nix.binaryCachePublicKeys = mkOption { + nix.settings.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 - is enabled, + is enabled, then Nix will use a binary from a binary cache if and only if it is signed by any of the keys listed here. By default, only the key for @@ -274,7 +310,7 @@ in ''; }; - nix.trustedUsers = mkOption { + nix.settings.trusted-users = mkOption { type = types.listOf types.str; default = [ "root" ]; example = [ "root" "alice" "@wheel" ]; @@ -289,14 +325,14 @@ in ''; }; - nix.allowedUsers = mkOption { + nix.settings.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 - , you can specify groups by + , you can specify groups by prefixing them with @. Also, you can allow all users by specifying *. The default is *. Note that trusted users are @@ -406,8 +442,8 @@ in (mkIf (!cfg.distributedBuilds && cfg.buildMachines != []) "nix.distributedBuilds is not enabled, build machines won't be configured.") ]; - nix.binaryCaches = mkAfter [ https://cache.nixos.org/ ]; - nix.binaryCachePublicKeys = mkAfter [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ]; + 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 From 9a5fb50ea91631c2862b0c917ea2b4e1d37ef3ac Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 12:34:47 -0700 Subject: [PATCH 02/18] Reorder `nix` module options to match order in NixOS module --- modules/nix/default.nix | 306 ++++++++++++++++++++-------------------- 1 file changed, 155 insertions(+), 151 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 56d5597a..294f7f42 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -77,6 +77,7 @@ in ''; }; + # Not in NixOS module nix.version = mkOption { type = types.str; default = ""; @@ -84,6 +85,7 @@ in description = "The version of nix. Used to determine what settings to configure in nix.conf"; }; + # Not in NixOS module nix.useDaemon = mkOption { type = types.bool; default = false; @@ -94,80 +96,6 @@ in "; }; - nix.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). - ''; - }; - - nix.settings.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. - ''; - }; - - nix.settings.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. - ''; - }; - - nix.settings.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. - ''; - }; - - nix.settings.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. - ''; - }; - - nix.extraOptions = mkOption { - type = types.lines; - default = ""; - example = '' - gc-keep-outputs = true - gc-keep-derivations = true - ''; - description = "Additional text appended to nix.conf."; - }; - nix.distributedBuilds = mkOption { type = types.bool; default = false; @@ -180,6 +108,7 @@ in ''; }; + # Not in NixOS module nix.daemonNiceLevel = mkOption { type = types.int; default = 0; @@ -189,6 +118,7 @@ in ''; }; + # Not in NixOS module nix.daemonIONice = mkOption { type = types.bool; default = false; @@ -263,83 +193,6 @@ in ''; }; - nix.settings.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. - ''; - }; - - nix.settings.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 - ) by passing - --option binary-caches to Nix commands. - ''; - }; - - nix.settings.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 - . 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. - ''; - }; - - nix.settings.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 - is enabled, - then Nix will use a binary from a binary cache if and only - if it is signed by any of the keys - listed here. By default, only the key for - cache.nixos.org is included. - ''; - }; - - nix.settings.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 - @; for instance, - @wheel means all users in the wheel - group. - ''; - }; - - nix.settings.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 - , you can specify groups by - prefixing them with @. Also, you can - allow all users by specifying *. The - default is *. Note that trusted users are - always allowed to connect. - ''; - }; - nix.nixPath = mkOption { type = mkOptionType { name = "nix path"; @@ -433,6 +286,157 @@ in A system-wide flake registry. ''; }; + + nix.extraOptions = mkOption { + type = types.lines; + default = ""; + example = '' + gc-keep-outputs = true + gc-keep-derivations = true + ''; + description = "Additional text appended to nix.conf."; + }; + + nix.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). + ''; + }; + + nix.settings.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. + ''; + }; + + nix.settings.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. + ''; + }; + + nix.settings.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. + ''; + }; + + nix.settings.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. + ''; + }; + + nix.settings.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. + ''; + }; + + nix.settings.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 + ) by passing + --option binary-caches to Nix commands. + ''; + }; + + nix.settings.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 + . 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. + ''; + }; + + nix.settings.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 + is enabled, + then Nix will use a binary from a binary cache if and only + if it is signed by any of the keys + listed here. By default, only the key for + cache.nixos.org is included. + ''; + }; + + nix.settings.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 + @; for instance, + @wheel means all users in the wheel + group. + ''; + }; + + nix.settings.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 + , you can specify groups by + prefixing them with @. Also, you can + allow all users by specifying *. The + default is *. Note that trusted users are + always allowed to connect. + ''; + }; }; config = { From 490ef804858936eab2def7b0564f68a2e777d7d9 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 12:49:34 -0700 Subject: [PATCH 03/18] Reindent/format `nix` module to more closely match NixOS module --- modules/nix/default.nix | 714 ++++++++++++++++++++-------------------- 1 file changed, 364 insertions(+), 350 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 294f7f42..38e66e7a 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -3,6 +3,7 @@ with lib; let + cfg = config.nix; isNix20 = versionAtLeast (cfg.version or "") "1.12pre"; @@ -56,6 +57,7 @@ let allowedUsers = "allowed-users"; # systemFeatures = "system-features"; }; + in { @@ -63,382 +65,393 @@ in mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ] ) legacyConfMappings; + ###### interface + options = { - nix.package = mkOption { - type = types.either types.package types.path; - default = pkgs.nix; - defaultText = "pkgs.nix"; - example = literalExpression "pkgs.nixUnstable"; - description = '' - This option specifies the package or profile that contains the version of Nix to use throughout the system. - To keep the version of nix originally installed the default profile can be used. - eg. /nix/var/nix/profiles/default - ''; - }; + nix = { - # Not in NixOS module - nix.version = mkOption { - type = types.str; - default = ""; - example = "1.11.6"; - description = "The version of nix. Used to determine what settings to configure in nix.conf"; - }; + package = mkOption { + type = types.either types.package types.path; + default = pkgs.nix; + defaultText = "pkgs.nix"; + example = literalExpression "pkgs.nixUnstable"; + description = '' + This option specifies the package or profile that contains the version of Nix to use throughout the system. + To keep the version of nix originally installed the default profile can be used. - # Not in NixOS module - nix.useDaemon = mkOption { - type = types.bool; - default = false; - description = " - If set, Nix will use the daemon to perform operations. - Use this instead of services.nix-daemon.enable if you don't wan't the - daemon service to be managed for you. - "; - }; - - nix.distributedBuilds = mkOption { - type = types.bool; - default = false; - description = '' - Whether to distribute builds to the machines listed in - . - - NOTE: This requires services.nix-daemon.enable for a - multi-user install. - ''; - }; - - # Not in NixOS module - nix.daemonNiceLevel = mkOption { - type = types.int; - default = 0; - description = '' - Nix daemon process priority. This priority propagates to build processes. - 0 is the default Unix process priority, 19 is the lowest. - ''; - }; - - # Not in NixOS module - nix.daemonIONice = mkOption { - type = types.bool; - default = false; - description = '' - Whether the Nix daemon process should considered to be low priority when - doing file system I/O. - ''; - }; - - nix.buildMachines = mkOption { - type = types.listOf types.attrs; - default = []; - example = [ - { hostName = "voila.labs.cs.uu.nl"; - sshUser = "nix"; - sshKey = "/root/.ssh/id_buildfarm"; - system = "powerpc-darwin"; - maxJobs = 1; - } - { hostName = "linux64.example.org"; - sshUser = "buildfarm"; - sshKey = "/root/.ssh/id_buildfarm"; - system = "x86_64-linux"; - maxJobs = 2; - supportedFeatures = [ "kvm" ]; - mandatoryFeatures = [ "perf" ]; - } - ]; - description = '' - This option lists the machines to be used if distributed - builds are enabled (see - ). Nix will perform - derivations on those machines via SSH by copying the inputs - to the Nix store on the remote machine, starting the build, - then copying the output back to the local Nix store. Each - element of the list should be an attribute set containing - the machine's host name (hostname), the - user name to be used for the SSH connection - (sshUser), the Nix system type - (system, e.g., - "i686-linux"), the maximum number of - jobs to be run in parallel on that machine - (maxJobs), the path to the SSH private - key to be used to connect (sshKey), a - list of supported features of the machine - (supportedFeatures) and a list of - mandatory features of the machine - (mandatoryFeatures). The SSH private key - should not have a passphrase, and the corresponding public - key should be added to - ~sshUser/authorized_keys - on the remote machine. - ''; - }; - - # Environment variables for running Nix. - nix.envVars = mkOption { - type = types.attrs; - internal = true; - default = {}; - description = "Environment variables used by Nix."; - }; - - nix.readOnlyStore = mkOption { - type = types.bool; - default = true; - description = '' - If set, NixOS will enforce the immutability of the Nix store - by making /nix/store a read-only bind - mount. Nix will automatically make the store writable when - needed. - ''; - }; - - nix.nixPath = mkOption { - type = mkOptionType { - name = "nix path"; - merge = loc: defs: - let - values = flatten (map (def: - (map (x: - if isAttrs x then (mapAttrsToList nameValuePair x) - else if isString x then x - else throw "The option value `${showOption loc}` in `${def.file}` is not a attset or string.") - (if isList def.value then def.value else [def.value]))) defs); - - namedPaths = mapAttrsToList (n: v: "${n}=${(head v).value}") - (zipAttrs - (map (x: { "${x.name}" = { inherit (x) value; }; }) - (filter isAttrs values))); - - searchPaths = unique - (filter isString values); - in - namedPaths ++ searchPaths; + eg. /nix/var/nix/profiles/default + ''; }; - default = - [ # Include default path . - { darwin-config = "${config.environment.darwinConfig}"; } - "/nix/var/nix/profiles/per-user/root/channels" - "$HOME/.nix-defexpr/channels" + + # Not in NixOS module + version = mkOption { + type = types.str; + default = ""; + example = "1.11.6"; + description = "The version of nix. Used to determine what settings to configure in nix.conf"; + }; + + # Not in NixOS module + useDaemon = mkOption { + type = types.bool; + default = false; + description = " + If set, Nix will use the daemon to perform operations. + Use this instead of services.nix-daemon.enable if you don't wan't the + daemon service to be managed for you. + "; + }; + + distributedBuilds = mkOption { + type = types.bool; + default = false; + description = '' + Whether to distribute builds to the machines listed in + . + + NOTE: This requires services.nix-daemon.enable for a + multi-user install. + ''; + }; + + # Not in NixOS module + daemonNiceLevel = mkOption { + type = types.int; + default = 0; + description = '' + Nix daemon process priority. This priority propagates to build processes. + 0 is the default Unix process priority, 19 is the lowest. + ''; + }; + + # Not in NixOS module + daemonIONice = mkOption { + type = types.bool; + default = false; + description = '' + Whether the Nix daemon process should considered to be low priority when + doing file system I/O. + ''; + }; + + buildMachines = mkOption { + type = types.listOf types.attrs; + default = []; + example = [ + { hostName = "voila.labs.cs.uu.nl"; + sshUser = "nix"; + sshKey = "/root/.ssh/id_buildfarm"; + system = "powerpc-darwin"; + maxJobs = 1; + } + { hostName = "linux64.example.org"; + sshUser = "buildfarm"; + sshKey = "/root/.ssh/id_buildfarm"; + system = "x86_64-linux"; + maxJobs = 2; + supportedFeatures = [ "kvm" ]; + mandatoryFeatures = [ "perf" ]; + } ]; - example = - [ { trunk = "/src/nixpkgs"; } - ]; - description = '' - The default Nix expression search path, used by the Nix - evaluator to look up paths enclosed in angle brackets - (e.g. <nixpkgs>). + description = '' + This option lists the machines to be used if distributed + builds are enabled (see + ). Nix will perform + derivations on those machines via SSH by copying the inputs + to the Nix store on the remote machine, starting the build, + then copying the output back to the local Nix store. Each + element of the list should be an attribute set containing + the machine's host name (hostname), the + user name to be used for the SSH connection + (sshUser), the Nix system type + (system, e.g., + "i686-linux"), the maximum number of + jobs to be run in parallel on that machine + (maxJobs), the path to the SSH private + key to be used to connect (sshKey), a + list of supported features of the machine + (supportedFeatures) and a list of + mandatory features of the machine + (mandatoryFeatures). The SSH private key + should not have a passphrase, and the corresponding public + key should be added to + ~sshUser/authorized_keys + on the remote machine. + ''; + }; - Named entries can be specified using an attribute set, if an - entry is configured multiple times the value with the lowest - ordering will be used. - ''; - }; + # Environment variables for running Nix. + envVars = mkOption { + type = types.attrs; + internal = true; + default = {}; + description = "Environment variables used by Nix."; + }; - nix.registry = mkOption { - type = types.attrsOf (types.submodule ( - let - inputAttrs = types.attrsOf (types.oneOf [types.str types.int types.bool types.package]); - in - { config, name, ... }: - { options = { - from = mkOption { - type = inputAttrs; - example = { type = "indirect"; id = "nixpkgs"; }; - description = "The flake reference to be rewritten."; + readOnlyStore = mkOption { + type = types.bool; + default = true; + description = '' + If set, NixOS will enforce the immutability of the Nix store + by making /nix/store a read-only bind + mount. Nix will automatically make the store writable when + needed. + ''; + }; + + nixPath = mkOption { + type = mkOptionType { + name = "nix path"; + merge = loc: defs: + let + values = flatten (map (def: + (map (x: + if isAttrs x then (mapAttrsToList nameValuePair x) + else if isString x then x + else throw "The option value `${showOption loc}` in `${def.file}` is not a attset or string.") + (if isList def.value then def.value else [def.value]))) defs); + + namedPaths = mapAttrsToList (n: v: "${n}=${(head v).value}") + (zipAttrs + (map (x: { "${x.name}" = { inherit (x) value; }; }) + (filter isAttrs values))); + + searchPaths = unique + (filter isString values); + in + namedPaths ++ searchPaths; + }; + default = + [ # Include default path . + { darwin-config = "${config.environment.darwinConfig}"; } + "/nix/var/nix/profiles/per-user/root/channels" + "$HOME/.nix-defexpr/channels" + ]; + example = + [ { trunk = "/src/nixpkgs"; } + ]; + description = '' + The default Nix expression search path, used by the Nix + evaluator to look up paths enclosed in angle brackets + (e.g. <nixpkgs>). + + Named entries can be specified using an attribute set, if an + entry is configured multiple times the value with the lowest + ordering will be used. + ''; + }; + + registry = mkOption { + type = types.attrsOf (types.submodule ( + let + inputAttrs = types.attrsOf (types.oneOf [types.str types.int types.bool types.package]); + in + { config, name, ... }: + { options = { + from = mkOption { + type = inputAttrs; + example = { type = "indirect"; id = "nixpkgs"; }; + description = "The flake reference to be rewritten."; + }; + to = mkOption { + type = inputAttrs; + example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; }; + description = "The flake reference to which is to be rewritten."; + }; + flake = mkOption { + type = types.unspecified; + default = null; + example = literalExpression "nixpkgs"; + description = '' + The flake input to which is to be rewritten. + ''; + }; + exact = mkOption { + type = types.bool; + default = true; + description = '' + Whether the reference needs to match exactly. If set, + a reference like nixpkgs does not + match with a reference like nixpkgs/nixos-20.03. + ''; + }; }; - to = mkOption { - type = inputAttrs; - example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; }; - description = "The flake reference to which is to be rewritten."; + config = { + from = mkDefault { type = "indirect"; id = name; }; + to = mkIf (config.flake != null) + ({ type = "path"; + path = config.flake.outPath; + } // lib.filterAttrs + (n: v: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash") + config.flake); }; - flake = mkOption { - type = types.unspecified; - default = null; - example = literalExpression "nixpkgs"; - description = '' - The flake input to which is to be rewritten. - ''; - }; - exact = mkOption { - type = types.bool; - default = true; - description = '' - Whether the reference needs to match exactly. If set, - a reference like nixpkgs does not - match with a reference like nixpkgs/nixos-20.03. - ''; - }; - }; - config = { - from = mkDefault { type = "indirect"; id = name; }; - to = mkIf (config.flake != null) - ({ type = "path"; - path = config.flake.outPath; - } // lib.filterAttrs - (n: v: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash") - config.flake); - }; - } - )); - default = {}; - description = '' - A system-wide flake registry. - ''; - }; + } + )); + default = {}; + description = '' + A system-wide flake registry. + ''; + }; - nix.extraOptions = mkOption { - type = types.lines; - default = ""; - example = '' - gc-keep-outputs = true - gc-keep-derivations = true - ''; - description = "Additional text appended to nix.conf."; - }; + extraOptions = mkOption { + type = types.lines; + default = ""; + example = '' + gc-keep-outputs = true + gc-keep-derivations = true + ''; + description = "Additional text appended to nix.conf."; + }; - nix.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 = { + 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). + ''; + }; - nix.settings.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. + ''; + }; - nix.settings.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. + ''; + }; - nix.settings.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. + ''; + }; - nix.settings.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. + ''; + }; - nix.settings.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. + ''; + }; - nix.settings.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 - ) by passing - --option binary-caches 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 + ) by passing + --option binary-caches to Nix commands. + ''; + }; - nix.settings.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 - . 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 + . 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. + ''; + }; - nix.settings.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 - is enabled, - then Nix will use a binary from a binary cache if and only - if it is signed by any of the keys - listed here. By default, only the key for - cache.nixos.org 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 + is enabled, + then Nix will use a binary from a binary cache if and only + if it is signed by any of the keys + listed here. By default, only the key for + cache.nixos.org is included. + ''; + }; - nix.settings.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 - @; for instance, - @wheel 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 + @; for instance, + @wheel means all users in the wheel + group. + ''; + }; - nix.settings.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 - , you can specify groups by - prefixing them with @. Also, you can - allow all users by specifying *. The - default is *. Note that trusted users are - always allowed to connect. - ''; + 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 + , you can specify groups by + prefixing them with @. Also, you can + allow all users by specifying *. The + default is *. Note that trusted users are + always allowed to connect. + ''; + }; + }; }; }; + + ###### implementation + config = { warnings = [ @@ -527,4 +540,5 @@ in ''; }; + } From 5f141365afa8fcdd7fc7aee65031b850118f1bc0 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 14:17:44 -0700 Subject: [PATCH 04/18] Update def and implementation of `nix.package` to match NixOS module Also remove `nix.version` option since it's no longer being used anywhere, old irrelevant `nix-info` module, and all support for legacy `nix.profile` option. --- modules/alias.nix | 6 +----- modules/module-list.nix | 1 - modules/nix/default.nix | 41 ++++++++++++++-------------------------- modules/nix/nix-info.nix | 15 --------------- 4 files changed, 15 insertions(+), 48 deletions(-) delete mode 100644 modules/nix/nix-info.nix diff --git a/modules/alias.nix b/modules/alias.nix index d495d2fe..cd7140fd 100644 --- a/modules/alias.nix +++ b/modules/alias.nix @@ -10,7 +10,6 @@ in options = { networking.networkservices = mkOption { internal = true; default = null; }; - nix.profile = mkOption { internal = true; default = null; }; security.enableAccessibilityAccess = mkOption { internal = true; default = null; }; security.accessibilityPrograms = mkOption { internal = true; default = null; }; @@ -19,8 +18,7 @@ in config = { assertions = - [ { assertion = config.nix.profile == null; message = "nix.profile was renamed to nix.package"; } - { assertion = config.security.enableAccessibilityAccess == null; message = "security.enableAccessibilityAccess was removed, it's broken since 10.12 because of SIP"; } + [ { assertion = config.security.enableAccessibilityAccess == null; message = "security.enableAccessibilityAccess was removed, it's broken since 10.12 because of SIP"; } { assertion = config.system.activationScripts.extraPostActivation.text == ""; message = "system.activationScripts.extraPostActivation was renamed to system.activationScripts.postActivation"; } { assertion = config.system.activationScripts.extraUserPostActivation.text == ""; message = "system.activationScripts.extraUserPostActivation was renamed to system.activationScripts.postUserActivation"; } ]; @@ -31,8 +29,6 @@ in networking.knownNetworkServices = mkIf (config.networking.networkservices != null) config.networking.networkservices; - nix.package = mkIf (config.nix.profile != null) config.nix.profile; - system.activationScripts.extraPostActivation.text = mkDefault ""; system.activationScripts.extraUserPostActivation.text = mkDefault ""; diff --git a/modules/module-list.nix b/modules/module-list.nix index d4c1b35b..f8ec8ddf 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -34,7 +34,6 @@ ./networking ./nix ./nix/nix-darwin.nix - ./nix/nix-info.nix ./nix/nixpkgs.nix ./environment ./fonts diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 38e66e7a..92b7d175 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -6,7 +6,7 @@ let cfg = config.nix; - isNix20 = versionAtLeast (cfg.version or "") "1.12pre"; + nixPackage = cfg.package.out; nixConf = let @@ -61,9 +61,10 @@ let in { - imports = mapAttrsToList (oldConf: newConf: - mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ] - ) legacyConfMappings; + imports = [ + (mkRemovedOptionModule [ "nix" "profile" ] "Use `nix.package` instead.") + (mkRemovedOptionModule [ "nix" "version" ] "Consider using `nix.package.version` instead.") + ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings; ###### interface @@ -72,26 +73,14 @@ in nix = { package = mkOption { - type = types.either types.package types.path; + type = types.package; default = pkgs.nix; - defaultText = "pkgs.nix"; - example = literalExpression "pkgs.nixUnstable"; + defaultText = literalExpression "pkgs.nix"; description = '' - This option specifies the package or profile that contains the version of Nix to use throughout the system. - To keep the version of nix originally installed the default profile can be used. - - eg. /nix/var/nix/profiles/default + This option specifies the Nix package instance to use throughout the system. ''; }; - # Not in NixOS module - version = mkOption { - type = types.str; - default = ""; - example = "1.11.6"; - description = "The version of nix. Used to determine what settings to configure in nix.conf"; - }; - # Not in NixOS module useDaemon = mkOption { type = types.bool; @@ -475,14 +464,12 @@ in ])) ]; - - nix.package = mkIf (config.system.stateVersion < 3) - (mkDefault "/nix/var/nix/profiles/default"); - - nix.version = mkIf (isDerivation cfg.package) cfg.package.version or ""; - - environment.systemPackages = mkIf (isDerivation cfg.package) - [ cfg.package ]; + environment.systemPackages = + [ + nixPackage + pkgs.nix-info + ] + ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions; environment.etc."nix/nix.conf".source = nixConf; diff --git a/modules/nix/nix-info.nix b/modules/nix/nix-info.nix deleted file mode 100644 index 146a08c0..00000000 --- a/modules/nix/nix-info.nix +++ /dev/null @@ -1,15 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - nix-info = pkgs.nix-info or null; -in - -{ - config = { - - environment.systemPackages = mkIf (nix-info != null) [ nix-info ]; - - }; -} From a00b3836a5c60efc652bcbed83393bae13fab2af Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 15:11:58 -0700 Subject: [PATCH 05/18] Update `nix.settings` def and implementation to match NixOS module --- modules/nix/default.nix | 434 +++++++++++++++++++++++++--------------- 1 file changed, 273 insertions(+), 161 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 92b7d175..6735ac0b 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 <nix.settings.substituters) by passing - --option binary-caches to Nix commands. - ''; - }; + By default https://cache.nixos.org/ is added. + ''; + }; - 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 - . 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-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 + ) by passing + --option binary-caches to Nix commands. + ''; + }; - 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 - is enabled, - then Nix will use a binary from a binary cache if and only - if it is signed by any of the keys - listed here. By default, only the key for - cache.nixos.org is included. - ''; - }; + 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 + . 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-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 - @; for instance, - @wheel means all users in the wheel - group. - ''; - }; + 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 + is enabled, + then Nix will use a binary from a binary cache if and only + if it is signed by any of the keys + listed here. By default, only the key for + cache.nixos.org is included. + ''; + }; - 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 - , you can specify groups by - prefixing them with @. Also, you can - allow all users by specifying *. The - default is *. Note that trusted users are - always allowed to connect. - ''; + 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 + @; for instance, + @wheel means all users in the wheel + group. + ''; + }; + + # 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 + # requiredSystemFeatures attribute. + + # By default, pseudo-features nixos-test, benchmark, + # and big-parallel used in Nixpkgs are set, kvm + # 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 + , you can specify groups by + prefixing them with @. Also, you can + allow all users by specifying *. The + default is *. 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 + or + + nix.conf + 5 + for avalaible options. + The value declared here will be translated directly to the key-value pairs Nix expects. + + + You can use nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings + to view the current value. By default it is empty. + + + Nix configurations defined under will be translated and applied to this + option. In addition, configuration specified in 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"; }) + ]; + }; } From 5786c079f8c095a77d6c8fb72d06a093bfdfa9d3 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 15:32:29 -0700 Subject: [PATCH 06/18] Make `nix.settings` docs specific to (nix-)darwin where applicable --- modules/nix/default.nix | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 6735ac0b..62bf941a 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -35,8 +35,7 @@ let 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! + # your nix-darwin configuration. Do not edit it! ${mkKeyValuePairs cfg.settings} ${cfg.extraOptions} ''; @@ -327,8 +326,8 @@ in type = types.lines; default = ""; example = '' - gc-keep-outputs = true - gc-keep-derivations = true + keep-outputs = true + keep-derivations = true ''; description = "Additional text appended to nix.conf."; }; @@ -384,9 +383,7 @@ in 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 + store by using network and mount namespaces in a chroot environment. It doesn't affect derivation hashes, so changing this option will not trigger a rebuild of packages. ''; @@ -452,14 +449,14 @@ in trusted-users = mkOption { type = types.listOf types.str; default = [ "root" ]; - example = [ "root" "alice" "@wheel" ]; + example = [ "root" "alice" "@admin" ]; 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 @; for instance, - @wheel means all users in the wheel + @admin means all users in the wheel group. ''; }; @@ -482,7 +479,7 @@ in allowed-users = mkOption { type = types.listOf types.str; default = [ "*" ]; - example = [ "@wheel" "@builders" "alice" "bob" ]; + example = [ "@admin" "@builders" "alice" "bob" ]; description = '' A list of names of users (separated by whitespace) that are allowed to connect to the Nix daemon. As with @@ -496,29 +493,13 @@ in }; }; 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 - or - - nix.conf - 5 - for avalaible options. + + for avalaible options. The value declared here will be translated directly to the key-value pairs Nix expects. - You can use nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings - to view the current value. By default it is empty. - - Nix configurations defined under will be translated and applied to this option. In addition, configuration specified in which will be appended verbatim to the resulting config file. From d44b8be38ce5e021bf3a280fa63087b4d79c26ee Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 15:43:54 -0700 Subject: [PATCH 07/18] Reorder `nix` module implementation to better match order of NixOS module --- modules/nix/default.nix | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 62bf941a..db1d40fa 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -512,25 +512,12 @@ in ###### implementation config = { - + # Not in NixOS module warnings = [ (mkIf (!config.services.activate-system.enable && cfg.distributedBuilds) "services.activate-system is not enabled, a reboot could cause distributed builds to stop working.") (mkIf (!cfg.distributedBuilds && cfg.buildMachines != []) "nix.distributedBuilds is not enabled, build machines won't be configured.") ]; - nix.nixPath = mkMerge [ - (mkIf (config.system.stateVersion < 2) (mkDefault - [ "darwin=$HOME/.nix-defexpr/darwin" - "darwin-config=$HOME/.nixpkgs/darwin-configuration.nix" - "/nix/var/nix/profiles/per-user/root/channels" - ])) - (mkIf (config.system.stateVersion > 3) (mkOrder 1200 - [ { darwin-config = "${config.environment.darwinConfig}"; } - "/nix/var/nix/profiles/per-user/root/channels" - "$HOME/.nix-defexpr/channels" - ])) - ]; - environment.systemPackages = [ nixPackage @@ -570,6 +557,24 @@ in ) cfg.buildMachines; }; + # Not in NixOS module + nix.nixPath = mkMerge [ + (mkIf (config.system.stateVersion < 2) (mkDefault + [ "darwin=$HOME/.nix-defexpr/darwin" + "darwin-config=$HOME/.nixpkgs/darwin-configuration.nix" + "/nix/var/nix/profiles/per-user/root/channels" + ])) + (mkIf (config.system.stateVersion > 3) (mkOrder 1200 + [ { darwin-config = "${config.environment.darwinConfig}"; } + "/nix/var/nix/profiles/per-user/root/channels" + "$HOME/.nix-defexpr/channels" + ])) + ]; + + # Set up the environment variables for running Nix. + environment.variables = cfg.envVars // { NIX_PATH = concatStringsSep ":" cfg.nixPath; }; + + # Unreladed to use in NixOS module environment.extraInit = '' # Set up secure multi-user builds: non-root users build through the # Nix daemon. @@ -578,11 +583,7 @@ in fi ''; - # Set up the environment variables for running Nix. - environment.variables = cfg.envVars // - { NIX_PATH = concatStringsSep ":" cfg.nixPath; - }; - + # Unreladed to use in NixOS module system.activationScripts.nix-daemon.text = mkIf cfg.useDaemon '' if ! diff /etc/nix/nix.conf /run/current-system/etc/nix/nix.conf &> /dev/null; then echo "reloading nix-daemon..." >&2 From 39cf1e6fbe24c1e8fce9d9618ca964b4ef486ed2 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 15:49:25 -0700 Subject: [PATCH 08/18] Minor tweaks to `nix` module options defs --- modules/nix/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index db1d40fa..8d05cf84 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -204,7 +204,7 @@ in envVars = mkOption { type = types.attrs; internal = true; - default = {}; + default = { }; description = "Environment variables used by Nix."; }; @@ -212,7 +212,7 @@ in type = types.bool; default = true; description = '' - If set, NixOS will enforce the immutability of the Nix store + If set, Nix will enforce the immutability of the Nix store by making /nix/store a read-only bind mount. Nix will automatically make the store writable when needed. From c3bdd6d95f605a8248768ba43338ef8269173d57 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 15:59:31 -0700 Subject: [PATCH 09/18] Update `nix.buildMachines` def and implementation to match NixOS module --- modules/nix/default.nix | 204 +++++++++++++++++++++++++++++----------- 1 file changed, 148 insertions(+), 56 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 8d05cf84..7a4bdae2 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -155,48 +155,120 @@ in }; buildMachines = mkOption { - type = types.listOf types.attrs; - default = []; - example = [ - { hostName = "voila.labs.cs.uu.nl"; - sshUser = "nix"; - sshKey = "/root/.ssh/id_buildfarm"; - system = "powerpc-darwin"; - maxJobs = 1; - } - { hostName = "linux64.example.org"; - sshUser = "buildfarm"; - sshKey = "/root/.ssh/id_buildfarm"; - system = "x86_64-linux"; - maxJobs = 2; - supportedFeatures = [ "kvm" ]; - mandatoryFeatures = [ "perf" ]; - } - ]; + type = types.listOf (types.submodule { + options = { + hostName = mkOption { + type = types.str; + example = "nixbuilder.example.org"; + description = '' + The hostname of the build machine. + ''; + }; + system = mkOption { + type = types.nullOr types.str; + default = null; + example = "x86_64-linux"; + description = '' + The system type the build machine can execute derivations on. + Either this attribute or systems must be + present, where system takes precedence if + both are set. + ''; + }; + systems = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "x86_64-linux" "aarch64-linux" ]; + description = '' + The system types the build machine can execute derivations on. + Either this attribute or system must be + present, where system takes precedence if + both are set. + ''; + }; + sshUser = mkOption { + type = types.nullOr types.str; + default = null; + example = "builder"; + description = '' + The username to log in as on the remote host. This user must be + able to log in and run nix commands non-interactively. It must + also be privileged to build derivations, so must be included in + . + ''; + }; + sshKey = mkOption { + type = types.nullOr types.str; + default = null; + example = "/root/.ssh/id_buildhost_builduser"; + description = '' + The path to the SSH private key with which to authenticate on + the build machine. The private key must not have a passphrase. + If null, the building user (root on NixOS machines) must have an + appropriate ssh configuration to log in non-interactively. + + Note that for security reasons, this path must point to a file + in the local filesystem, *not* to the nix store. + ''; + }; + maxJobs = mkOption { + type = types.int; + default = 1; + description = '' + The number of concurrent jobs the build machine supports. The + build machine will enforce its own limits, but this allows hydra + to schedule better since there is no work-stealing between build + machines. + ''; + }; + speedFactor = mkOption { + type = types.int; + default = 1; + description = '' + The relative speed of this builder. This is an arbitrary integer + that indicates the speed of this builder, relative to other + builders. Higher is faster. + ''; + }; + mandatoryFeatures = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "big-parallel" ]; + description = '' + A list of features mandatory for this builder. The builder will + be ignored for derivations that don't require all features in + this list. All mandatory features are automatically included in + supportedFeatures. + ''; + }; + supportedFeatures = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "kvm" "big-parallel" ]; + description = '' + A list of features supported by this builder. The builder will + be ignored for derivations that require features not in this + list. + ''; + }; + publicHostKey = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The (base64-encoded) public host key of this builder. The field + is calculated via base64 -w0 /etc/ssh/ssh_host_type_key.pub. + If null, SSH will use its regular known-hosts file when connecting. + ''; + }; + }; + }); + default = [ ]; description = '' - This option lists the machines to be used if distributed - builds are enabled (see - ). Nix will perform - derivations on those machines via SSH by copying the inputs - to the Nix store on the remote machine, starting the build, - then copying the output back to the local Nix store. Each - element of the list should be an attribute set containing - the machine's host name (hostname), the - user name to be used for the SSH connection - (sshUser), the Nix system type - (system, e.g., - "i686-linux"), the maximum number of - jobs to be run in parallel on that machine - (maxJobs), the path to the SSH private - key to be used to connect (sshKey), a - list of supported features of the machine - (supportedFeatures) and a list of - mandatory features of the machine - (mandatoryFeatures). The SSH private key - should not have a passphrase, and the corresponding public - key should be added to - ~sshUser/authorized_keys - on the remote machine. + This option lists the machines to be used if distributed builds are + enabled (see ). + Nix will perform derivations on those machines via SSH by copying the + inputs to the Nix store on the remote machine, starting the build, + then copying the output back to the local Nix store. ''; }; @@ -540,22 +612,42 @@ in }; # List of machines for distributed Nix builds in the format - # expected by build-remote. - environment.etc."nix/machines" = - { enable = cfg.buildMachines != []; - text = - concatMapStrings (machine: - "${if machine ? sshUser then "${machine.sshUser}@" else ""}${machine.hostName} " - + machine.system or (concatStringsSep "," machine.systems) - + " ${machine.sshKey or "-"} ${toString machine.maxJobs or 1} " - + toString (machine.speedFactor or 1) - + " " - + concatStringsSep "," (machine.mandatoryFeatures or [] ++ machine.supportedFeatures or []) - + " " - + concatStringsSep "," machine.mandatoryFeatures or [] + # expected by build-remote.pl. + environment.etc."nix/machines" = mkIf (cfg.buildMachines != [ ]) { + text = + concatMapStrings + (machine: + (concatStringsSep " " ([ + "${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}" + (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-") + (if machine.sshKey != null then machine.sshKey else "-") + (toString machine.maxJobs) + (toString machine.speedFactor) + (concatStringsSep "," (machine.supportedFeatures ++ machine.mandatoryFeatures)) + (concatStringsSep "," machine.mandatoryFeatures) + ] + ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-"))) + "\n" - ) cfg.buildMachines; - }; + ) + cfg.buildMachines; + }; + + assertions = + let badMachine = m: m.system == null && m.systems == [ ]; + in + [ + { + assertion = !(any badMachine cfg.buildMachines); + message = '' + At least one system type (via system or + systems) must be set for every build machine. + Invalid machine specifications: + '' + " " + + (concatStringsSep "\n " + (map (m: m.hostName) + (filter (badMachine) cfg.buildMachines))); + } + ]; # Not in NixOS module nix.nixPath = mkMerge [ From 7648c9befcc011091eccdf48a61a819cc835f2f8 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 16:41:43 -0700 Subject: [PATCH 10/18] Refactor `nix.nixPath` to make diff easier to compare with NixOS module --- modules/nix/default.nix | 55 +++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 7a4bdae2..60f7b4ba 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -88,6 +88,29 @@ let in attrsOf (either confAtom (listOf confAtom)); + # Not in NixOS module + nixPathType = mkOptionType { + name = "nix path"; + merge = loc: defs: + let + values = flatten (map (def: + (map (x: + if isAttrs x then (mapAttrsToList nameValuePair x) + else if isString x then x + else throw "The option value `${showOption loc}` in `${def.file}` is not a attset or string.") + (if isList def.value then def.value else [def.value]))) defs); + + namedPaths = mapAttrsToList (n: v: "${n}=${(head v).value}") + (zipAttrs + (map (x: { "${x.name}" = { inherit (x) value; }; }) + (filter isAttrs values))); + + searchPaths = unique + (filter isString values); + in + namedPaths ++ searchPaths; + }; + in { @@ -291,37 +314,15 @@ in ''; }; + # Definition differs substantially from NixOS module nixPath = mkOption { - type = mkOptionType { - name = "nix path"; - merge = loc: defs: - let - values = flatten (map (def: - (map (x: - if isAttrs x then (mapAttrsToList nameValuePair x) - else if isString x then x - else throw "The option value `${showOption loc}` in `${def.file}` is not a attset or string.") - (if isList def.value then def.value else [def.value]))) defs); - - namedPaths = mapAttrsToList (n: v: "${n}=${(head v).value}") - (zipAttrs - (map (x: { "${x.name}" = { inherit (x) value; }; }) - (filter isAttrs values))); - - searchPaths = unique - (filter isString values); - in - namedPaths ++ searchPaths; - }; - default = - [ # Include default path . + type = nixPathType; + default = [ + # Include default path . { darwin-config = "${config.environment.darwinConfig}"; } "/nix/var/nix/profiles/per-user/root/channels" "$HOME/.nix-defexpr/channels" ]; - example = - [ { trunk = "/src/nixpkgs"; } - ]; description = '' The default Nix expression search path, used by the Nix evaluator to look up paths enclosed in angle brackets @@ -664,7 +665,7 @@ in ]; # Set up the environment variables for running Nix. - environment.variables = cfg.envVars // { NIX_PATH = concatStringsSep ":" cfg.nixPath; }; + environment.variables = cfg.envVars // { NIX_PATH = cfg.nixPath; }; # Unreladed to use in NixOS module environment.extraInit = '' From f88286eda079b404da179efa86b907b166b878e3 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 16:51:25 -0700 Subject: [PATCH 11/18] Update `nix.registry` definition to match NixOS module --- modules/nix/default.nix | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 60f7b4ba..5911edf6 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -346,26 +346,32 @@ in registry = mkOption { type = types.attrsOf (types.submodule ( let - inputAttrs = types.attrsOf (types.oneOf [types.str types.int types.bool types.package]); + referenceAttrs = with types; attrsOf (oneOf [ + str + int + bool + package + ]); in { config, name, ... }: - { options = { + { + options = { from = mkOption { - type = inputAttrs; + type = referenceAttrs; example = { type = "indirect"; id = "nixpkgs"; }; description = "The flake reference to be rewritten."; }; to = mkOption { - type = inputAttrs; + type = referenceAttrs; example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; }; - description = "The flake reference to which is to be rewritten."; + description = "The flake reference is rewritten to."; }; flake = mkOption { - type = types.unspecified; + type = types.nullOr types.attrs; default = null; example = literalExpression "nixpkgs"; description = '' - The flake input to which is to be rewritten. + The flake input is rewritten to. ''; }; exact = mkOption { @@ -380,16 +386,17 @@ in }; config = { from = mkDefault { type = "indirect"; id = name; }; - to = mkIf (config.flake != null) - ({ type = "path"; - path = config.flake.outPath; - } // lib.filterAttrs - (n: v: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash") - config.flake); + to = mkIf (config.flake != null) (mkDefault + { + type = "path"; + path = config.flake.outPath; + } // filterAttrs + (n: _: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash") + config.flake); }; } )); - default = {}; + default = { }; description = '' A system-wide flake registry. ''; From 7e74c1c9fbb19638d95933b8bcac1757a184519e Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sat, 13 Aug 2022 19:18:48 -0700 Subject: [PATCH 12/18] Move build user options to `nix` module to improve overlap with NixOS Also add `config.ids` like in NixOS. --- modules/examples/lnl.nix | 4 +- modules/misc/ids.nix | 50 +++++++++++++++ modules/module-list.nix | 2 +- modules/nix/default.nix | 81 ++++++++++++++++++++++--- modules/system/checks.nix | 2 +- modules/users/nixbld/default.nix | 70 --------------------- pkgs/darwin-installer/configuration.nix | 2 +- 7 files changed, 129 insertions(+), 82 deletions(-) create mode 100644 modules/misc/ids.nix delete mode 100644 modules/users/nixbld/default.nix diff --git a/modules/examples/lnl.nix b/modules/examples/lnl.nix index a0dd0ba5..dac393ff 100644 --- a/modules/examples/lnl.nix +++ b/modules/examples/lnl.nix @@ -357,6 +357,6 @@ # path = /etc/per-user/lnl/gitconfig # environment.etc."per-user/lnl/gitconfig".text = builtins.readFile "${inputs.dotfiles}/git/gitconfig"; - users.nix.configureBuildUsers = true; - users.nix.nrBuildUsers = 32; + nix.configureBuildUsers = true; + nix.nrBuildUsers = 32; } diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix new file mode 100644 index 00000000..07f1240b --- /dev/null +++ b/modules/misc/ids.nix @@ -0,0 +1,50 @@ +# Based on: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/misc/ids.nix + +# This module defines the global list of uids and gids. We keep a +# central list to prevent id collisions. + +# IMPORTANT! +# We only add static uids and gids for services where it is not feasible +# to change uids/gids on service start, in example a service with a lot of +# files. + +{ lib, ... }: + +let + inherit (lib) types; +in +{ + options = { + + ids.uids = lib.mkOption { + internal = true; + description = '' + The user IDs used in NixOS. + ''; + type = types.attrsOf types.int; + }; + + ids.gids = lib.mkOption { + internal = true; + description = '' + The group IDs used in NixOS. + ''; + type = types.attrsOf types.int; + }; + + }; + + + config = { + + ids.uids = { + nixbld = 300; + }; + + ids.gids = { + nixbld = 30000; + }; + + }; + +} diff --git a/modules/module-list.nix b/modules/module-list.nix index f8ec8ddf..fc27ff05 100644 --- a/modules/module-list.nix +++ b/modules/module-list.nix @@ -1,6 +1,7 @@ [ ./alias.nix ./documentation + ./misc/ids.nix ./misc/lib.nix ./security/pki ./security/sandbox @@ -76,5 +77,4 @@ ./programs/zsh ./homebrew.nix ./users - ./users/nixbld ] diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 5911edf6..edc8d4ff 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -10,6 +10,23 @@ let isNixAtLeast = versionAtLeast (getVersion nixPackage); + makeNixBuildUser = nr: { + name = "_nixbld${toString nr}"; + value = { + description = "Nix build user ${toString nr}"; + + /* + For consistency with the setgid(2), setuid(2), and setgroups(2) + calls in `libstore/build.cc', don't add any supplementary group + here except "nixbld". + */ + uid = builtins.add config.ids.uids.nixbld nr; + gid = config.ids.gids.nixbld; + }; + }; + + nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers)); + nixConf = assert isNixAtLeast "2.2"; let @@ -117,6 +134,8 @@ in imports = [ (mkRemovedOptionModule [ "nix" "profile" ] "Use `nix.package` instead.") (mkRemovedOptionModule [ "nix" "version" ] "Consider using `nix.package.version` instead.") + (mkRenamedOptionModule [ "users" "nix" "configureBuildUsers" ] [ "nix" "configureBuildUsers" ]) + (mkRenamedOptionModule [ "users" "nix" "nrBuildUsers" ] [ "nix" "nrBuildUsers" ]) ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings; ###### interface @@ -303,6 +322,25 @@ in description = "Environment variables used by Nix."; }; + # Not in NixOS module + configureBuildUsers = mkOption { + type = types.bool; + default = false; + description = '' + Enable configuration for nixbld group and users. + ''; + }; + + nrBuildUsers = mkOption { + type = types.int; + description = '' + Number of nixbld user accounts created to + perform secure concurrent builds. If you receive an error + message saying that “all build users are currently in use”, + you should increase this value. + ''; + }; + readOnlyStore = mkOption { type = types.bool; default = true; @@ -592,12 +630,6 @@ in ###### implementation config = { - # Not in NixOS module - warnings = [ - (mkIf (!config.services.activate-system.enable && cfg.distributedBuilds) "services.activate-system is not enabled, a reboot could cause distributed builds to stop working.") - (mkIf (!cfg.distributedBuilds && cfg.buildMachines != []) "nix.distributedBuilds is not enabled, build machines won't be configured.") - ]; - environment.systemPackages = [ nixPackage @@ -641,7 +673,12 @@ in }; assertions = - let badMachine = m: m.system == null && m.systems == [ ]; + let + badMachine = m: m.system == null && m.systems == [ ]; + + # Not in NixOS module + createdGroups = mapAttrsToList (n: v: v.name) config.users.groups; + createdUsers = mapAttrsToList (n: v: v.name) config.users.users; in [ { @@ -655,8 +692,19 @@ in (map (m: m.hostName) (filter (badMachine) cfg.buildMachines))); } + + # Not in NixOS module + { assertion = elem "nixbld" config.users.knownGroups -> elem "nixbld" createdGroups; message = "refusing to delete group nixbld in users.knownGroups, this would break nix"; } + { assertion = elem "_nixbld1" config.users.knownGroups -> elem "_nixbld1" createdUsers; message = "refusing to delete user _nixbld1 in users.knownUsers, this would break nix"; } + { assertion = config.users.groups ? "nixbld" -> config.users.groups.nixbld.members != []; message = "refusing to remove all members from nixbld group, this would break nix"; } ]; + # Not in NixOS module + warnings = [ + (mkIf (!config.services.activate-system.enable && cfg.distributedBuilds) "services.activate-system is not enabled, a reboot could cause distributed builds to stop working.") + (mkIf (!cfg.distributedBuilds && cfg.buildMachines != []) "nix.distributedBuilds is not enabled, build machines won't be configured.") + ]; + # Not in NixOS module nix.nixPath = mkMerge [ (mkIf (config.system.stateVersion < 2) (mkDefault @@ -683,6 +731,25 @@ in fi ''; + nix.nrBuildUsers = mkDefault (max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)); + + users.users = mkIf cfg.configureBuildUsers nixbldUsers; + + # Not in NixOS module + users.groups.nixbld = mkIf cfg.configureBuildUsers { + description = "Nix build group for nix-daemon"; + gid = config.ids.gids.nixbld; + members = attrNames nixbldUsers; + }; + users.knownUsers = + let nixbldUserNames = attrNames nixbldUsers; + in + mkIf cfg.configureBuildUsers (mkMerge [ + nixbldUserNames + (map (removePrefix "_") nixbldUserNames) # delete old style nixbld users + ]); + users.knownGroups = mkIf cfg.configureBuildUsers [ "nixbld" ]; + # Unreladed to use in NixOS module system.activationScripts.nix-daemon.text = mkIf cfg.useDaemon '' if ! diff /etc/nix/nix.conf /run/current-system/etc/nix/nix.conf &> /dev/null; then diff --git a/modules/system/checks.nix b/modules/system/checks.nix index 3500e913..2af25c8f 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -54,7 +54,7 @@ let echo >&2 echo "or enable to automatically manage the users" >&2 echo >&2 - echo " users.nix.configureBuildUsers = true;" >&2 + echo " nix.configureBuildUsers = true;" >&2 echo >&2 fi ''; diff --git a/modules/users/nixbld/default.nix b/modules/users/nixbld/default.nix deleted file mode 100644 index 8dadd562..00000000 --- a/modules/users/nixbld/default.nix +++ /dev/null @@ -1,70 +0,0 @@ -{ config, lib, pkgs, ... }: - -with lib; - -let - cfg = config.users; - - named = xs: listToAttrs (map (x: { name = x.name; value = x; }) xs); - - createdGroups = mapAttrsToList (n: v: v.name) cfg.groups; - createdUsers = mapAttrsToList (n: v: v.name) cfg.users; - - mkUsers = f: genList (x: f (x + 1)) cfg.nix.nrBuildUsers; - - buildUsers = mkUsers (i: { - name = "_nixbld${toString i}"; - uid = 300 + i; - gid = 300; - description = "Nix build user ${toString i}"; - }); - - buildGroups = [{ - name = "nixbld"; - gid = 30000; - description = "Nix build group for nix-daemon"; - members = map (v: v.name) buildUsers; - }]; -in - -{ - options = { - users.nix.configureBuildUsers = mkOption { - type = types.bool; - default = false; - description = '' - Configuration for nixbld group and users. - NOTE: This does not work unless knownGroups/knownUsers is set. - ''; - }; - - users.nix.nrBuildUsers = mkOption { - type = mkOptionType { - name = "integer"; - check = t: isInt t && t > 1; - }; - default = 32; - description = "Number of nixbld user accounts created to perform secure concurrent builds."; - }; - }; - - config = { - - assertions = [ - { assertion = elem "nixbld" cfg.knownGroups -> elem "nixbld" createdGroups; message = "refusing to delete group nixbld in users.knownGroups, this would break nix"; } - { assertion = elem "_nixbld1" cfg.knownUsers -> elem "_nixbld1" createdUsers; message = "refusing to delete user _nixbld1 in users.knownUsers, this would break nix"; } - { assertion = cfg.groups ? "nixbld" -> cfg.groups.nixbld.members != []; message = "refusing to remove all members from nixbld group, this would break nix"; } - ]; - - users.groups = mkIf cfg.nix.configureBuildUsers (named buildGroups); - users.users = mkIf cfg.nix.configureBuildUsers (named buildUsers); - - users.knownGroups = mkIf cfg.nix.configureBuildUsers [ "nixbld" ]; - users.knownUsers = mkIf cfg.nix.configureBuildUsers (mkMerge [ - (mkUsers (i: "_nixbld${toString i}")) - (mkUsers (i: "nixbld${toString i}")) # delete old style nixbld users - ]); - - }; -} - diff --git a/pkgs/darwin-installer/configuration.nix b/pkgs/darwin-installer/configuration.nix index 7aafbfd4..a0e58a16 100644 --- a/pkgs/darwin-installer/configuration.nix +++ b/pkgs/darwin-installer/configuration.nix @@ -5,6 +5,6 @@ with lib; { imports = [ ./installer.nix ]; - users.nix.configureBuildUsers = true; + nix.configureBuildUsers = true; users.knownGroups = [ "nixbld" ]; } From 08edc0e19ac33435bd2b5dede373a2bea9f13b49 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sun, 14 Aug 2022 13:38:11 -0700 Subject: [PATCH 13/18] Update/adapt daemon CPU/IO priority options in `nix` module Stop using `nice` related options like NixOS, and because `launchd` recommends using `ProcessType` instead. Note this commit also changes the default `ProcessType` for the `nix-daemon` from `Interactive` to `Standard`. --- modules/nix/default.nix | 43 ++++++++++++++++++++++++--------- modules/services/nix-daemon.nix | 5 ++-- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index edc8d4ff..c816648a 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -131,12 +131,26 @@ let in { - imports = [ - (mkRemovedOptionModule [ "nix" "profile" ] "Use `nix.package` instead.") - (mkRemovedOptionModule [ "nix" "version" ] "Consider using `nix.package.version` instead.") - (mkRenamedOptionModule [ "users" "nix" "configureBuildUsers" ] [ "nix" "configureBuildUsers" ]) - (mkRenamedOptionModule [ "users" "nix" "nrBuildUsers" ] [ "nix" "nrBuildUsers" ]) - ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings; + imports = + let + altOption = alt: "No `nix-darwin` equivilant to this NixOS option, consider using `${alt}` instead."; + consider = alt: "Consider using `${alt}` instead."; + in + [ + # Only ever in NixOS + (mkRemovedOptionModule [ "nix" "enable" ] "No `nix-darwin` equivilant to this NixOS option.") + (mkRemovedOptionModule [ "nix" "daemonCPUSchedPolicy" ] (altOption "nix.daemonProcessType")) + (mkRemovedOptionModule [ "nix" "daemonIOSchedClass" ] (altOption "nix.daemonProcessType")) + (mkRemovedOptionModule [ "nix" "daemonIOSchedPriority" ] (altOption "nix.daemonIOLowPriority")) + + # Option changes in `nix-darwin` + (mkRemovedOptionModule [ "nix" "profile" ] "Use `nix.package` instead.") + (mkRemovedOptionModule [ "nix" "version" ] (consider "nix.package.version")) + (mkRenamedOptionModule [ "users" "nix" "configureBuildUsers" ] [ "nix" "configureBuildUsers" ]) + (mkRenamedOptionModule [ "users" "nix" "nrBuildUsers" ] [ "nix" "nrBuildUsers" ]) + (mkRenamedOptionModule [ "nix" "daemonIONice" ] [ "nix" "daemonIOLowPriority" ]) + (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] (consider "nix.daemonProcessType")) + ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings; ###### interface @@ -177,17 +191,22 @@ in }; # Not in NixOS module - daemonNiceLevel = mkOption { - type = types.int; - default = 0; + daemonProcessType = mkOption { + type = types.enum [ "Background" "Standard" "Adaptive" "Interactive" ]; + default = "Standard"; description = '' - Nix daemon process priority. This priority propagates to build processes. - 0 is the default Unix process priority, 19 is the lowest. + Nix daemon process resource limits class. These limits propagate to + build processes. Standard is the default process type + and will apply light resource limits, throttling its CPU usage and I/O + bandwidth. + + See man launchd.plist for explanation of other + process types. ''; }; # Not in NixOS module - daemonIONice = mkOption { + daemonIOLowPriority = mkOption { type = types.bool; default = false; description = '' diff --git a/modules/services/nix-daemon.nix b/modules/services/nix-daemon.nix index 735d92c9..5e87e513 100644 --- a/modules/services/nix-daemon.nix +++ b/modules/services/nix-daemon.nix @@ -48,9 +48,8 @@ in "/bin/sh" "-c" "/bin/wait4path ${config.nix.package}/bin/nix-daemon && exec ${config.nix.package}/bin/nix-daemon" ]; - serviceConfig.ProcessType = mkDefault "Interactive"; - serviceConfig.LowPriorityIO = config.nix.daemonIONice; - serviceConfig.Nice = config.nix.daemonNiceLevel; + serviceConfig.ProcessType = config.nix.daemonProcessType; + serviceConfig.LowPriorityIO = config.nix.daemonIOLowPriority; serviceConfig.Label = "org.nixos.nix-daemon"; # must match daemon installed by Nix regardless of the launchd label Prefix serviceConfig.SoftResourceLimits.NumberOfFiles = mkDefault 4096; serviceConfig.StandardErrorPath = cfg.logFile; From ffc8ec5c9ae6cf7b3bb95866432e30e46e7cc731 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sun, 14 Aug 2022 14:04:20 -0700 Subject: [PATCH 14/18] Add .nix-defexpr to NIX_PATH the way the NixOS module does --- modules/nix/default.nix | 24 ++++++++++++++---------- modules/system/checks.nix | 8 +++++--- pkgs/darwin-installer/default.nix | 4 ++-- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/modules/nix/default.nix b/modules/nix/default.nix index c816648a..6b32caa7 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -378,7 +378,6 @@ in # Include default path . { darwin-config = "${config.environment.darwinConfig}"; } "/nix/var/nix/profiles/per-user/root/channels" - "$HOME/.nix-defexpr/channels" ]; description = '' The default Nix expression search path, used by the Nix @@ -734,21 +733,26 @@ in (mkIf (config.system.stateVersion > 3) (mkOrder 1200 [ { darwin-config = "${config.environment.darwinConfig}"; } "/nix/var/nix/profiles/per-user/root/channels" - "$HOME/.nix-defexpr/channels" ])) ]; # Set up the environment variables for running Nix. environment.variables = cfg.envVars // { NIX_PATH = cfg.nixPath; }; - # Unreladed to use in NixOS module - environment.extraInit = '' - # Set up secure multi-user builds: non-root users build through the - # Nix daemon. - if [ ! -w /nix/var/nix/db ]; then - export NIX_REMOTE=daemon - fi - ''; + environment.extraInit = + '' + if [ -e "$HOME/.nix-defexpr/channels" ]; then + export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}" + fi + '' + + # Not in NixOS module + '' + # Set up secure multi-user builds: non-root users build through the + # Nix daemon. + if [ ! -w /nix/var/nix/db ]; then + export NIX_REMOTE=daemon + fi + ''; nix.nrBuildUsers = mkDefault (max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs)); diff --git a/modules/system/checks.nix b/modules/system/checks.nix index 2af25c8f..4ce69912 100644 --- a/modules/system/checks.nix +++ b/modules/system/checks.nix @@ -125,7 +125,9 @@ let ''; nixPath = '' - darwinConfig=$(NIX_PATH=${concatStringsSep ":" config.nix.nixPath} nix-instantiate --find-file darwin-config) || true + nixPath=${concatStringsSep ":" config.nix.nixPath}:$HOME/.nix-defexpr/channels + + darwinConfig=$(NIX_PATH=$nixPath nix-instantiate --find-file darwin-config) || true if ! test -e "$darwinConfig"; then echo "error: Changed but target does not exist, aborting activation" >&2 echo "Create ''${darwinConfig:-~/.nixpkgs/darwin-configuration.nix} or set environment.darwinConfig:" >&2 @@ -139,7 +141,7 @@ let exit 2 fi - darwinPath=$(NIX_PATH=${concatStringsSep ":" config.nix.nixPath} nix-instantiate --find-file darwin) || true + darwinPath=$(NIX_PATH=$nixPath nix-instantiate --find-file darwin) || true if ! test -e "$darwinPath"; then echo "error: Changed but target does not exist, aborting activation" >&2 echo "Add the darwin repo as a channel or set nix.nixPath:" >&2 @@ -153,7 +155,7 @@ let exit 2 fi - nixpkgsPath=$(NIX_PATH=${concatStringsSep ":" config.nix.nixPath} nix-instantiate --find-file nixpkgs) || true + nixpkgsPath=$(NIX_PATH=$nixPath nix-instantiate --find-file nixpkgs) || true if ! test -e "$nixpkgsPath"; then echo "error: Changed but target does not exist, aborting activation" >&2 echo "Add a nixpkgs channel or set nix.nixPath:" >&2 diff --git a/pkgs/darwin-installer/default.nix b/pkgs/darwin-installer/default.nix index cf1c7058..496aa4f0 100644 --- a/pkgs/darwin-installer/default.nix +++ b/pkgs/darwin-installer/default.nix @@ -145,13 +145,13 @@ stdenv.mkDerivation { env -i USER=john HOME=/Users/john bash -li -c 'echo $PATH' env -i USER=john HOME=/Users/john bash -li -c 'echo $PATH' | grep /Users/john/.nix-profile/bin:/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin env -i USER=john HOME=/Users/john bash -li -c 'echo $NIX_PATH' - env -i USER=john HOME=/Users/john bash -li -c 'echo $NIX_PATH' | grep darwin-config=/Users/john/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels:/Users/john/.nix-defexpr/channels + env -i USER=john HOME=/Users/john bash -li -c 'echo $NIX_PATH' | grep darwin-config=/Users/john/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels echo >&2 "checking zsh environment" env -i USER=john HOME=/Users/john zsh -l -c 'echo $PATH' env -i USER=john HOME=/Users/john zsh -l -c 'echo $PATH' | grep /Users/john/.nix-profile/bin:/run/current-system/sw/bin:/nix/var/nix/profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin - env -i USER=john HOME=/Users/john zsh -l -c 'echo $NIX_PATH' | grep darwin-config=/Users/john/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels:/Users/john/.nix-defexpr/channels env -i USER=john HOME=/Users/john zsh -l -c 'echo $NIX_PATH' + env -i USER=john HOME=/Users/john zsh -l -c 'echo $NIX_PATH' | grep darwin-config=/Users/john/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels echo >&2 ok exit From f75b461ae2da5de249359b17996805199e919ca7 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sun, 14 Aug 2022 14:16:56 -0700 Subject: [PATCH 15/18] Fix tests failing due to Nix version check --- tests/checks-nix-gc.nix | 2 +- tests/services-nix-daemon.nix | 2 +- tests/services-nix-gc.nix | 2 +- tests/sockets-nix-daemon.nix | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/checks-nix-gc.nix b/tests/checks-nix-gc.nix index fde6211e..75700ccb 100644 --- a/tests/checks-nix-gc.nix +++ b/tests/checks-nix-gc.nix @@ -1,7 +1,7 @@ { config, pkgs, ... }: let - nix = pkgs.runCommand "nix-0.0.0" {} "mkdir -p $out"; + nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out"; in { diff --git a/tests/services-nix-daemon.nix b/tests/services-nix-daemon.nix index 6c972df2..5405d01f 100644 --- a/tests/services-nix-daemon.nix +++ b/tests/services-nix-daemon.nix @@ -2,7 +2,7 @@ let cacert = pkgs.runCommand "cacert-0.0.0" {} "mkdir -p $out"; - nix = pkgs.runCommand "nix-0.0.0" { version = "1.11.6"; } "mkdir -p $out"; + nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out"; in { diff --git a/tests/services-nix-gc.nix b/tests/services-nix-gc.nix index 915d1622..e28c3df2 100644 --- a/tests/services-nix-gc.nix +++ b/tests/services-nix-gc.nix @@ -1,7 +1,7 @@ { config, pkgs, ... }: let - nix = pkgs.runCommand "nix-0.0.0" {} "mkdir -p $out"; + nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out"; in { diff --git a/tests/sockets-nix-daemon.nix b/tests/sockets-nix-daemon.nix index d1b2827b..0eb09a77 100644 --- a/tests/sockets-nix-daemon.nix +++ b/tests/sockets-nix-daemon.nix @@ -1,7 +1,7 @@ { config, pkgs, ... }: let - nix = pkgs.runCommand "nix-0.0.0" {} "mkdir -p $out"; + nix = pkgs.runCommand "nix-2.2" {} "mkdir -p $out"; in { From c027fb5ee5df3c33f9a2ce088b30100cdf3fa028 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sun, 14 Aug 2022 14:44:59 -0700 Subject: [PATCH 16/18] Update `nix.gc` module with same indenting/formatting as NixOS module --- modules/services/nix-gc/default.nix | 66 +++++++++++++++++------------ 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/modules/services/nix-gc/default.nix b/modules/services/nix-gc/default.nix index 57b3e22d..d7b90da6 100644 --- a/modules/services/nix-gc/default.nix +++ b/modules/services/nix-gc/default.nix @@ -1,4 +1,6 @@ -{ config, lib, pkgs, ... }: +# Based off: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/nix-gc.nix +# When making changes please try to keep it in sync. +{ config, lib, ... }: with lib; @@ -7,36 +9,48 @@ let in { + + ###### interface + options = { - nix.gc.automatic = mkOption { - type = types.bool; - default = false; - description = "Automatically run the garbage collector at a specific time."; + + nix.gc = { + + automatic = mkOption { + type = types.bool; + default = false; + description = "Automatically run the garbage collector at a specific time."; + }; + + user = mkOption { + type = types.nullOr types.str; + default = null; + description = "User that runs the garbage collector."; + }; + + interval = mkOption { + type = types.attrs; + default = { Hour = 3; Minute = 15; }; + description = "The time interval at which the garbage collector will run."; + }; + + options = mkOption { + type = types.str; + default = ""; + example = "--max-freed $((64 * 1024**3))"; + description = '' + Options given to nix-collect-garbage when the + garbage collector is run automatically. + ''; + }; + }; - nix.gc.user = mkOption { - type = types.nullOr types.str; - default = null; - description = "User that runs the garbage collector."; - }; - - nix.gc.interval = mkOption { - type = types.attrs; - default = { Hour = 3; Minute = 15; }; - description = "The time interval at which the garbage collector will run."; - }; - - nix.gc.options = mkOption { - type = types.str; - default = ""; - example = "--max-freed $((64 * 1024**3))"; - description = '' - Options given to nix-collect-garbage when the - garbage collector is run automatically. - ''; - }; }; + + ###### implementation + config = mkIf cfg.automatic { launchd.daemons.nix-gc = { From 8e2c71d1ca85461c6295dba31481eadb07fdbb19 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sun, 14 Aug 2022 14:57:12 -0700 Subject: [PATCH 17/18] Tweak `nix.gc` module to more closely match NixOS module --- modules/services/nix-gc/default.nix | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/services/nix-gc/default.nix b/modules/services/nix-gc/default.nix index d7b90da6..fca68037 100644 --- a/modules/services/nix-gc/default.nix +++ b/modules/services/nix-gc/default.nix @@ -9,6 +9,11 @@ let in { + imports = [ + (mkRemovedOptionModule [ "nix" "gc" "dates" ] "Use `nix.gc.interval` instead.") + (mkRemovedOptionModule [ "nix" "gc" "randomizedDelaySec" ] "No `nix-darwin` equivilant to this NixOS option.") + (mkRemovedOptionModule [ "nix" "gc" "persistent" ] "No `nix-darwin` equivilant to this NixOS option.") + ]; ###### interface @@ -17,11 +22,12 @@ in nix.gc = { automatic = mkOption { - type = types.bool; default = false; + type = types.bool; description = "Automatically run the garbage collector at a specific time."; }; + # Not in NixOS module user = mkOption { type = types.nullOr types.str; default = null; @@ -35,9 +41,9 @@ in }; options = mkOption { - type = types.str; default = ""; example = "--max-freed $((64 * 1024**3))"; + type = types.str; description = '' Options given to nix-collect-garbage when the garbage collector is run automatically. From 796a72f0fe2c8df0e37f0febda3b6aad3b351a68 Mon Sep 17 00:00:00 2001 From: Malo Bourgon Date: Sun, 14 Aug 2022 17:52:52 -0700 Subject: [PATCH 18/18] Update changelog --- CHANGELOG | 23 +++++++++++++++++++++++ modules/nix/default.nix | 2 ++ 2 files changed, 25 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 1675b3e0..b4f5cb10 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,26 @@ +2022-08-14 +- nix module updated to bring it back in sync with it's NixOS counterpart + It should now be much more fiesable to share code for this module between + `nix-darwin` and NixOS configs. + + `nix-darwin` now requires Nix >= 2.2. + + `nix.package` can no longer be a path to a profile. + + `nix.version` option has been removed. Use `nix.package.version` if you want + to reference the version Nix installed/used by your config. + + Many options moved/renamed from `nix.*` to `nix.settings.*`. For example + `nix.binaryCaches` is now `nix.settings.substituters`. + + You can use `nix.settings` to set any option in `nix.conf`. + + `users.nix.*` options moved to `nix.*`. + + `nix.daemonIONice` was renamed to `nix.daemonIOLowPriority`, and + `nix.daemonNiceLevel` was removed in favor a new option + `nix.nix.daemonProcessType`. + 2021-01-16 - Added `homebrew` module, to manage formulas installed by Homebrew via `brew bundle`. diff --git a/modules/nix/default.nix b/modules/nix/default.nix index 6b32caa7..2588d3be 100644 --- a/modules/nix/default.nix +++ b/modules/nix/default.nix @@ -1,3 +1,5 @@ +# Based off: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/nix-daemon.nix +# When making changes please try to keep it in sync and keep the diff NixOS module clean. { config, lib, pkgs, ... }: with lib;