at 23.11-pre 33 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.nix; 8 9 nixPackage = cfg.package.out; 10 11 isNixAtLeast = versionAtLeast (getVersion nixPackage); 12 13 makeNixBuildUser = nr: { 14 name = "nixbld${toString nr}"; 15 value = { 16 description = "Nix build user ${toString nr}"; 17 18 /* 19 For consistency with the setgid(2), setuid(2), and setgroups(2) 20 calls in `libstore/build.cc', don't add any supplementary group 21 here except "nixbld". 22 */ 23 uid = builtins.add config.ids.uids.nixbld nr; 24 isSystemUser = true; 25 group = "nixbld"; 26 extraGroups = [ "nixbld" ]; 27 }; 28 }; 29 30 nixbldUsers = listToAttrs (map makeNixBuildUser (range 1 cfg.nrBuildUsers)); 31 32 nixConf = 33 assert isNixAtLeast "2.2"; 34 let 35 36 mkValueString = v: 37 if v == null then "" 38 else if isInt v then toString v 39 else if isBool v then boolToString v 40 else if isFloat v then floatToString v 41 else if isList v then toString v 42 else if isDerivation v then toString v 43 else if builtins.isPath v then toString v 44 else if isString v then v 45 else if strings.isConvertibleWithToString v then toString v 46 else abort "The nix conf value: ${toPretty {} v} can not be encoded"; 47 48 mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}"; 49 50 mkKeyValuePairs = attrs: concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs); 51 52 in 53 pkgs.writeTextFile { 54 name = "nix.conf"; 55 text = '' 56 # WARNING: this file is generated from the nix.* options in 57 # your NixOS configuration, typically 58 # /etc/nixos/configuration.nix. Do not edit it! 59 ${mkKeyValuePairs cfg.settings} 60 ${cfg.extraOptions} 61 ''; 62 checkPhase = lib.optionalString cfg.checkConfig ( 63 if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then '' 64 echo "Ignoring validation for cross-compilation" 65 '' 66 else '' 67 echo "Validating generated nix.conf" 68 ln -s $out ./nix.conf 69 set -e 70 set +o pipefail 71 NIX_CONF_DIR=$PWD \ 72 ${cfg.package}/bin/nix show-config ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \ 73 ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \ 74 |& sed -e 's/^warning:/error:/' \ 75 | (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}') 76 set -o pipefail 77 ''); 78 }; 79 80 legacyConfMappings = { 81 useSandbox = "sandbox"; 82 buildCores = "cores"; 83 maxJobs = "max-jobs"; 84 sandboxPaths = "extra-sandbox-paths"; 85 binaryCaches = "substituters"; 86 trustedBinaryCaches = "trusted-substituters"; 87 binaryCachePublicKeys = "trusted-public-keys"; 88 autoOptimiseStore = "auto-optimise-store"; 89 requireSignedBinaryCaches = "require-sigs"; 90 trustedUsers = "trusted-users"; 91 allowedUsers = "allowed-users"; 92 systemFeatures = "system-features"; 93 }; 94 95 semanticConfType = with types; 96 let 97 confAtom = nullOr 98 (oneOf [ 99 bool 100 int 101 float 102 str 103 path 104 package 105 ]) // { 106 description = "Nix config atom (null, bool, int, float, str, path or package)"; 107 }; 108 in 109 attrsOf (either confAtom (listOf confAtom)); 110 111in 112 113{ 114 imports = [ 115 (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; }) 116 (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; }) 117 (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; }) 118 (mkRenamedOptionModuleWith { sinceRelease = 2211; from = [ "nix" "readOnlyStore" ]; to = [ "boot" "readOnlyNixStore" ]; }) 119 (mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.") 120 ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" oldConf ]; to = [ "nix" "settings" newConf ]; }) legacyConfMappings; 121 122 ###### interface 123 124 options = { 125 126 nix = { 127 128 enable = mkOption { 129 type = types.bool; 130 default = true; 131 description = lib.mdDoc '' 132 Whether to enable Nix. 133 Disabling Nix makes the system hard to modify and the Nix programs and configuration will not be made available by NixOS itself. 134 ''; 135 }; 136 137 package = mkOption { 138 type = types.package; 139 default = pkgs.nix; 140 defaultText = literalExpression "pkgs.nix"; 141 description = lib.mdDoc '' 142 This option specifies the Nix package instance to use throughout the system. 143 ''; 144 }; 145 146 distributedBuilds = mkOption { 147 type = types.bool; 148 default = false; 149 description = lib.mdDoc '' 150 Whether to distribute builds to the machines listed in 151 {option}`nix.buildMachines`. 152 ''; 153 }; 154 155 daemonCPUSchedPolicy = mkOption { 156 type = types.enum [ "other" "batch" "idle" ]; 157 default = "other"; 158 example = "batch"; 159 description = lib.mdDoc '' 160 Nix daemon process CPU scheduling policy. This policy propagates to 161 build processes. `other` is the default scheduling 162 policy for regular tasks. The `batch` policy is 163 similar to `other`, but optimised for 164 non-interactive tasks. `idle` is for extremely 165 low-priority tasks that should only be run when no other task 166 requires CPU time. 167 168 Please note that while using the `idle` policy may 169 greatly improve responsiveness of a system performing expensive 170 builds, it may also slow down and potentially starve crucial 171 configuration updates during load. 172 173 `idle` may therefore be a sensible policy for 174 systems that experience only intermittent phases of high CPU load, 175 such as desktop or portable computers used interactively. Other 176 systems should use the `other` or 177 `batch` policy instead. 178 179 For more fine-grained resource control, please refer to 180 {manpage}`systemd.resource-control(5)` and adjust 181 {option}`systemd.services.nix-daemon` directly. 182 ''; 183 }; 184 185 daemonIOSchedClass = mkOption { 186 type = types.enum [ "best-effort" "idle" ]; 187 default = "best-effort"; 188 example = "idle"; 189 description = lib.mdDoc '' 190 Nix daemon process I/O scheduling class. This class propagates to 191 build processes. `best-effort` is the default 192 class for regular tasks. The `idle` class is for 193 extremely low-priority tasks that should only perform I/O when no 194 other task does. 195 196 Please note that while using the `idle` scheduling 197 class can improve responsiveness of a system performing expensive 198 builds, it might also slow down or starve crucial configuration 199 updates during load. 200 201 `idle` may therefore be a sensible class for 202 systems that experience only intermittent phases of high I/O load, 203 such as desktop or portable computers used interactively. Other 204 systems should use the `best-effort` class. 205 ''; 206 }; 207 208 daemonIOSchedPriority = mkOption { 209 type = types.int; 210 default = 4; 211 example = 1; 212 description = lib.mdDoc '' 213 Nix daemon process I/O scheduling priority. This priority propagates 214 to build processes. The supported priorities depend on the 215 scheduling policy: With idle, priorities are not used in scheduling 216 decisions. best-effort supports values in the range 0 (high) to 7 217 (low). 218 ''; 219 }; 220 221 buildMachines = mkOption { 222 type = types.listOf (types.submodule { 223 options = { 224 hostName = mkOption { 225 type = types.str; 226 example = "nixbuilder.example.org"; 227 description = lib.mdDoc '' 228 The hostname of the build machine. 229 ''; 230 }; 231 protocol = mkOption { 232 type = types.enum [ null "ssh" "ssh-ng" ]; 233 default = "ssh"; 234 example = "ssh-ng"; 235 description = lib.mdDoc '' 236 The protocol used for communicating with the build machine. 237 Use `ssh-ng` if your remote builder and your 238 local Nix version support that improved protocol. 239 240 Use `null` when trying to change the special localhost builder 241 without a protocol which is for example used by hydra. 242 ''; 243 }; 244 system = mkOption { 245 type = types.nullOr types.str; 246 default = null; 247 example = "x86_64-linux"; 248 description = lib.mdDoc '' 249 The system type the build machine can execute derivations on. 250 Either this attribute or {var}`systems` must be 251 present, where {var}`system` takes precedence if 252 both are set. 253 ''; 254 }; 255 systems = mkOption { 256 type = types.listOf types.str; 257 default = [ ]; 258 example = [ "x86_64-linux" "aarch64-linux" ]; 259 description = lib.mdDoc '' 260 The system types the build machine can execute derivations on. 261 Either this attribute or {var}`system` must be 262 present, where {var}`system` takes precedence if 263 both are set. 264 ''; 265 }; 266 sshUser = mkOption { 267 type = types.nullOr types.str; 268 default = null; 269 example = "builder"; 270 description = lib.mdDoc '' 271 The username to log in as on the remote host. This user must be 272 able to log in and run nix commands non-interactively. It must 273 also be privileged to build derivations, so must be included in 274 {option}`nix.settings.trusted-users`. 275 ''; 276 }; 277 sshKey = mkOption { 278 type = types.nullOr types.str; 279 default = null; 280 example = "/root/.ssh/id_buildhost_builduser"; 281 description = lib.mdDoc '' 282 The path to the SSH private key with which to authenticate on 283 the build machine. The private key must not have a passphrase. 284 If null, the building user (root on NixOS machines) must have an 285 appropriate ssh configuration to log in non-interactively. 286 287 Note that for security reasons, this path must point to a file 288 in the local filesystem, *not* to the nix store. 289 ''; 290 }; 291 maxJobs = mkOption { 292 type = types.int; 293 default = 1; 294 description = lib.mdDoc '' 295 The number of concurrent jobs the build machine supports. The 296 build machine will enforce its own limits, but this allows hydra 297 to schedule better since there is no work-stealing between build 298 machines. 299 ''; 300 }; 301 speedFactor = mkOption { 302 type = types.int; 303 default = 1; 304 description = lib.mdDoc '' 305 The relative speed of this builder. This is an arbitrary integer 306 that indicates the speed of this builder, relative to other 307 builders. Higher is faster. 308 ''; 309 }; 310 mandatoryFeatures = mkOption { 311 type = types.listOf types.str; 312 default = [ ]; 313 example = [ "big-parallel" ]; 314 description = lib.mdDoc '' 315 A list of features mandatory for this builder. The builder will 316 be ignored for derivations that don't require all features in 317 this list. All mandatory features are automatically included in 318 {var}`supportedFeatures`. 319 ''; 320 }; 321 supportedFeatures = mkOption { 322 type = types.listOf types.str; 323 default = [ ]; 324 example = [ "kvm" "big-parallel" ]; 325 description = lib.mdDoc '' 326 A list of features supported by this builder. The builder will 327 be ignored for derivations that require features not in this 328 list. 329 ''; 330 }; 331 publicHostKey = mkOption { 332 type = types.nullOr types.str; 333 default = null; 334 description = lib.mdDoc '' 335 The (base64-encoded) public host key of this builder. The field 336 is calculated via {command}`base64 -w0 /etc/ssh/ssh_host_type_key.pub`. 337 If null, SSH will use its regular known-hosts file when connecting. 338 ''; 339 }; 340 }; 341 }); 342 default = [ ]; 343 description = lib.mdDoc '' 344 This option lists the machines to be used if distributed builds are 345 enabled (see {option}`nix.distributedBuilds`). 346 Nix will perform derivations on those machines via SSH by copying the 347 inputs to the Nix store on the remote machine, starting the build, 348 then copying the output back to the local Nix store. 349 ''; 350 }; 351 352 # Environment variables for running Nix. 353 envVars = mkOption { 354 type = types.attrs; 355 internal = true; 356 default = { }; 357 description = lib.mdDoc "Environment variables used by Nix."; 358 }; 359 360 nrBuildUsers = mkOption { 361 type = types.int; 362 description = lib.mdDoc '' 363 Number of `nixbld` user accounts created to 364 perform secure concurrent builds. If you receive an error 365 message saying that all build users are currently in use, 366 you should increase this value. 367 ''; 368 }; 369 370 nixPath = mkOption { 371 type = types.listOf types.str; 372 default = [ 373 "nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos" 374 "nixos-config=/etc/nixos/configuration.nix" 375 "/nix/var/nix/profiles/per-user/root/channels" 376 ]; 377 description = lib.mdDoc '' 378 The default Nix expression search path, used by the Nix 379 evaluator to look up paths enclosed in angle brackets 380 (e.g. `<nixpkgs>`). 381 ''; 382 }; 383 384 checkConfig = mkOption { 385 type = types.bool; 386 default = true; 387 description = lib.mdDoc '' 388 If enabled, checks that Nix can parse the generated nix.conf. 389 ''; 390 }; 391 392 checkAllErrors = mkOption { 393 type = types.bool; 394 default = true; 395 description = lib.mdDoc '' 396 If enabled, checks the nix.conf parsing for any kind of error. When disabled, checks only for unknown settings. 397 ''; 398 }; 399 400 registry = mkOption { 401 type = types.attrsOf (types.submodule ( 402 let 403 referenceAttrs = with types; attrsOf (oneOf [ 404 str 405 int 406 bool 407 path 408 package 409 ]); 410 in 411 { config, name, ... }: 412 { 413 options = { 414 from = mkOption { 415 type = referenceAttrs; 416 example = { type = "indirect"; id = "nixpkgs"; }; 417 description = lib.mdDoc "The flake reference to be rewritten."; 418 }; 419 to = mkOption { 420 type = referenceAttrs; 421 example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; }; 422 description = lib.mdDoc "The flake reference {option}`from` is rewritten to."; 423 }; 424 flake = mkOption { 425 type = types.nullOr types.attrs; 426 default = null; 427 example = literalExpression "nixpkgs"; 428 description = lib.mdDoc '' 429 The flake input {option}`from` is rewritten to. 430 ''; 431 }; 432 exact = mkOption { 433 type = types.bool; 434 default = true; 435 description = lib.mdDoc '' 436 Whether the {option}`from` reference needs to match exactly. If set, 437 a {option}`from` reference like `nixpkgs` does not 438 match with a reference like `nixpkgs/nixos-20.03`. 439 ''; 440 }; 441 }; 442 config = { 443 from = mkDefault { type = "indirect"; id = name; }; 444 to = mkIf (config.flake != null) (mkDefault ( 445 { 446 type = "path"; 447 path = config.flake.outPath; 448 } // filterAttrs 449 (n: _: n == "lastModified" || n == "rev" || n == "revCount" || n == "narHash") 450 config.flake 451 )); 452 }; 453 } 454 )); 455 default = { }; 456 description = lib.mdDoc '' 457 A system-wide flake registry. 458 ''; 459 }; 460 461 extraOptions = mkOption { 462 type = types.lines; 463 default = ""; 464 example = '' 465 keep-outputs = true 466 keep-derivations = true 467 ''; 468 description = lib.mdDoc "Additional text appended to {file}`nix.conf`."; 469 }; 470 471 settings = mkOption { 472 type = types.submodule { 473 freeformType = semanticConfType; 474 475 options = { 476 max-jobs = mkOption { 477 type = types.either types.int (types.enum [ "auto" ]); 478 default = "auto"; 479 example = 64; 480 description = lib.mdDoc '' 481 This option defines the maximum number of jobs that Nix will try to 482 build in parallel. The default is auto, which means it will use all 483 available logical cores. It is recommend to set it to the total 484 number of logical cores in your system (e.g., 16 for two CPUs with 4 485 cores each and hyper-threading). 486 ''; 487 }; 488 489 auto-optimise-store = mkOption { 490 type = types.bool; 491 default = false; 492 example = true; 493 description = lib.mdDoc '' 494 If set to true, Nix automatically detects files in the store that have 495 identical contents, and replaces them with hard links to a single copy. 496 This saves disk space. If set to false (the default), you can still run 497 nix-store --optimise to get rid of duplicate files. 498 ''; 499 }; 500 501 cores = mkOption { 502 type = types.int; 503 default = 0; 504 example = 64; 505 description = lib.mdDoc '' 506 This option defines the maximum number of concurrent tasks during 507 one build. It affects, e.g., -j option for make. 508 The special value 0 means that the builder should use all 509 available CPU cores in the system. Some builds may become 510 non-deterministic with this option; use with care! Packages will 511 only be affected if enableParallelBuilding is set for them. 512 ''; 513 }; 514 515 sandbox = mkOption { 516 type = types.either types.bool (types.enum [ "relaxed" ]); 517 default = true; 518 description = lib.mdDoc '' 519 If set, Nix will perform builds in a sandboxed environment that it 520 will set up automatically for each build. This prevents impurities 521 in builds by disallowing access to dependencies outside of the Nix 522 store by using network and mount namespaces in a chroot environment. 523 This is enabled by default even though it has a possible performance 524 impact due to the initial setup time of a sandbox for each build. It 525 doesn't affect derivation hashes, so changing this option will not 526 trigger a rebuild of packages. 527 ''; 528 }; 529 530 extra-sandbox-paths = mkOption { 531 type = types.listOf types.str; 532 default = [ ]; 533 example = [ "/dev" "/proc" ]; 534 description = lib.mdDoc '' 535 Directories from the host filesystem to be included 536 in the sandbox. 537 ''; 538 }; 539 540 substituters = mkOption { 541 type = types.listOf types.str; 542 description = lib.mdDoc '' 543 List of binary cache URLs used to obtain pre-built binaries 544 of Nix packages. 545 546 By default https://cache.nixos.org/ is added. 547 ''; 548 }; 549 550 trusted-substituters = mkOption { 551 type = types.listOf types.str; 552 default = [ ]; 553 example = [ "https://hydra.nixos.org/" ]; 554 description = lib.mdDoc '' 555 List of binary cache URLs that non-root users can use (in 556 addition to those specified using 557 {option}`nix.settings.substituters`) by passing 558 `--option binary-caches` to Nix commands. 559 ''; 560 }; 561 562 require-sigs = mkOption { 563 type = types.bool; 564 default = true; 565 description = lib.mdDoc '' 566 If enabled (the default), Nix will only download binaries from binary caches if 567 they are cryptographically signed with any of the keys listed in 568 {option}`nix.settings.trusted-public-keys`. If disabled, signatures are neither 569 required nor checked, so it's strongly recommended that you use only 570 trustworthy caches and https to prevent man-in-the-middle attacks. 571 ''; 572 }; 573 574 trusted-public-keys = mkOption { 575 type = types.listOf types.str; 576 example = [ "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs=" ]; 577 description = lib.mdDoc '' 578 List of public keys used to sign binary caches. If 579 {option}`nix.settings.trusted-public-keys` is enabled, 580 then Nix will use a binary from a binary cache if and only 581 if it is signed by *any* of the keys 582 listed here. By default, only the key for 583 `cache.nixos.org` is included. 584 ''; 585 }; 586 587 trusted-users = mkOption { 588 type = types.listOf types.str; 589 default = [ "root" ]; 590 example = [ "root" "alice" "@wheel" ]; 591 description = lib.mdDoc '' 592 A list of names of users that have additional rights when 593 connecting to the Nix daemon, such as the ability to specify 594 additional binary caches, or to import unsigned NARs. You 595 can also specify groups by prefixing them with 596 `@`; for instance, 597 `@wheel` means all users in the wheel 598 group. 599 ''; 600 }; 601 602 system-features = mkOption { 603 type = types.listOf types.str; 604 example = [ "kvm" "big-parallel" "gccarch-skylake" ]; 605 description = lib.mdDoc '' 606 The set of features supported by the machine. Derivations 607 can express dependencies on system features through the 608 `requiredSystemFeatures` attribute. 609 610 By default, pseudo-features `nixos-test`, `benchmark`, 611 and `big-parallel` used in Nixpkgs are set, `kvm` 612 is also included if it is available. 613 ''; 614 }; 615 616 allowed-users = mkOption { 617 type = types.listOf types.str; 618 default = [ "*" ]; 619 example = [ "@wheel" "@builders" "alice" "bob" ]; 620 description = lib.mdDoc '' 621 A list of names of users (separated by whitespace) that are 622 allowed to connect to the Nix daemon. As with 623 {option}`nix.settings.trusted-users`, you can specify groups by 624 prefixing them with `@`. Also, you can 625 allow all users by specifying `*`. The 626 default is `*`. Note that trusted users are 627 always allowed to connect. 628 ''; 629 }; 630 }; 631 }; 632 default = { }; 633 example = literalExpression '' 634 { 635 use-sandbox = true; 636 show-trace = true; 637 638 system-features = [ "big-parallel" "kvm" "recursive-nix" ]; 639 sandbox-paths = { "/bin/sh" = "''${pkgs.busybox-sandbox-shell.out}/bin/busybox"; }; 640 } 641 ''; 642 description = lib.mdDoc '' 643 Configuration for Nix, see 644 <https://nixos.org/manual/nix/stable/#sec-conf-file> or 645 {manpage}`nix.conf(5)` for available options. 646 The value declared here will be translated directly to the key-value pairs Nix expects. 647 648 You can use {command}`nix-instantiate --eval --strict '<nixpkgs/nixos>' -A config.nix.settings` 649 to view the current value. By default it is empty. 650 651 Nix configurations defined under {option}`nix.*` will be translated and applied to this 652 option. In addition, configuration specified in {option}`nix.extraOptions` which will be appended 653 verbatim to the resulting config file. 654 ''; 655 }; 656 }; 657 }; 658 659 660 ###### implementation 661 662 config = mkIf cfg.enable { 663 environment.systemPackages = 664 [ 665 nixPackage 666 pkgs.nix-info 667 ] 668 ++ optional (config.programs.bash.enableCompletion) pkgs.nix-bash-completions; 669 670 environment.etc."nix/nix.conf".source = nixConf; 671 672 environment.etc."nix/registry.json".text = builtins.toJSON { 673 version = 2; 674 flakes = mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry; 675 }; 676 677 # List of machines for distributed Nix builds in the format 678 # expected by build-remote.pl. 679 environment.etc."nix/machines" = mkIf (cfg.buildMachines != [ ]) { 680 text = 681 concatMapStrings 682 (machine: 683 (concatStringsSep " " ([ 684 "${optionalString (machine.protocol != null) "${machine.protocol}://"}${optionalString (machine.sshUser != null) "${machine.sshUser}@"}${machine.hostName}" 685 (if machine.system != null then machine.system else if machine.systems != [ ] then concatStringsSep "," machine.systems else "-") 686 (if machine.sshKey != null then machine.sshKey else "-") 687 (toString machine.maxJobs) 688 (toString machine.speedFactor) 689 (let res = (machine.supportedFeatures ++ machine.mandatoryFeatures); 690 in if (res == []) then "-" else (concatStringsSep "," res)) 691 (let res = machine.mandatoryFeatures; 692 in if (res == []) then "-" else (concatStringsSep "," machine.mandatoryFeatures)) 693 ] 694 ++ optional (isNixAtLeast "2.4pre") (if machine.publicHostKey != null then machine.publicHostKey else "-"))) 695 + "\n" 696 ) 697 cfg.buildMachines; 698 }; 699 700 assertions = 701 let badMachine = m: m.system == null && m.systems == [ ]; 702 in 703 [ 704 { 705 assertion = !(any badMachine cfg.buildMachines); 706 message = '' 707 At least one system type (via <varname>system</varname> or 708 <varname>systems</varname>) must be set for every build machine. 709 Invalid machine specifications: 710 '' + " " + 711 (concatStringsSep "\n " 712 (map (m: m.hostName) 713 (filter (badMachine) cfg.buildMachines))); 714 } 715 ]; 716 717 systemd.packages = [ nixPackage ]; 718 719 # Will only work once https://github.com/NixOS/nix/pull/6285 is merged 720 # systemd.tmpfiles.packages = [ nixPackage ]; 721 722 # Can be dropped for Nix > https://github.com/NixOS/nix/pull/6285 723 systemd.tmpfiles.rules = [ 724 "d /nix/var/nix/daemon-socket 0755 root root - -" 725 ]; 726 727 systemd.sockets.nix-daemon.wantedBy = [ "sockets.target" ]; 728 729 systemd.services.nix-daemon = 730 { 731 path = [ nixPackage pkgs.util-linux config.programs.ssh.package ] 732 ++ optionals cfg.distributedBuilds [ pkgs.gzip ]; 733 734 environment = cfg.envVars 735 // { CURL_CA_BUNDLE = "/etc/ssl/certs/ca-certificates.crt"; } 736 // config.networking.proxy.envVars; 737 738 unitConfig.RequiresMountsFor = "/nix/store"; 739 740 serviceConfig = 741 { 742 CPUSchedulingPolicy = cfg.daemonCPUSchedPolicy; 743 IOSchedulingClass = cfg.daemonIOSchedClass; 744 IOSchedulingPriority = cfg.daemonIOSchedPriority; 745 LimitNOFILE = 1048576; 746 }; 747 748 restartTriggers = [ nixConf ]; 749 750 # `stopIfChanged = false` changes to switch behavior 751 # from stop -> update units -> start 752 # to update units -> restart 753 # 754 # The `stopIfChanged` setting therefore controls a trade-off between a 755 # more predictable lifecycle, which runs the correct "version" of 756 # the `ExecStop` line, and on the other hand the availability of 757 # sockets during the switch, as the effectiveness of the stop operation 758 # depends on the socket being stopped as well. 759 # 760 # As `nix-daemon.service` does not make use of `ExecStop`, we prefer 761 # to keep the socket up and available. This is important for machines 762 # that run Nix-based services, such as automated build, test, and deploy 763 # services, that expect the daemon socket to be available at all times. 764 # 765 # Notably, the Nix client does not retry on failure to connect to the 766 # daemon socket, and the in-process RemoteStore instance will disable 767 # itself. This makes retries infeasible even for services that are 768 # aware of the issue. Failure to connect can affect not only new client 769 # processes, but also new RemoteStore instances in existing processes, 770 # as well as existing RemoteStore instances that have not saturated 771 # their connection pool. 772 # 773 # Also note that `stopIfChanged = true` does not kill existing 774 # connection handling daemons, as one might wish to happen before a 775 # breaking Nix upgrade (which is rare). The daemon forks that handle 776 # the individual connections split off into their own sessions, causing 777 # them not to be stopped by systemd. 778 # If a Nix upgrade does require all existing daemon processes to stop, 779 # nix-daemon must do so on its own accord, and only when the new version 780 # starts and detects that Nix's persistent state needs an upgrade. 781 stopIfChanged = false; 782 783 }; 784 785 # Set up the environment variables for running Nix. 786 environment.sessionVariables = cfg.envVars // { NIX_PATH = cfg.nixPath; }; 787 788 environment.extraInit = 789 '' 790 if [ -e "$HOME/.nix-defexpr/channels" ]; then 791 export NIX_PATH="$HOME/.nix-defexpr/channels''${NIX_PATH:+:$NIX_PATH}" 792 fi 793 ''; 794 795 nix.nrBuildUsers = mkDefault ( 796 if cfg.settings.auto-allocate-uids or false then 0 797 else max 32 (if cfg.settings.max-jobs == "auto" then 0 else cfg.settings.max-jobs) 798 ); 799 800 users.users = nixbldUsers; 801 802 services.xserver.displayManager.hiddenUsers = attrNames nixbldUsers; 803 804 system.activationScripts.nix = stringAfter [ "etc" "users" ] 805 '' 806 install -m 0755 -d /nix/var/nix/{gcroots,profiles}/per-user 807 808 # Subscribe the root user to the NixOS channel by default. 809 if [ ! -e "/root/.nix-channels" ]; then 810 echo "${config.system.defaultChannel} nixos" > "/root/.nix-channels" 811 fi 812 ''; 813 814 # Legacy configuration conversion. 815 nix.settings = mkMerge [ 816 { 817 trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" ]; 818 substituters = mkAfter [ "https://cache.nixos.org/" ]; 819 820 system-features = mkDefault ( 821 [ "nixos-test" "benchmark" "big-parallel" "kvm" ] ++ 822 optionals (pkgs.stdenv.hostPlatform ? gcc.arch) ( 823 # a builder can run code for `gcc.arch` and inferior architectures 824 [ "gccarch-${pkgs.stdenv.hostPlatform.gcc.arch}" ] ++ 825 map (x: "gccarch-${x}") (systems.architectures.inferiors.${pkgs.stdenv.hostPlatform.gcc.arch} or []) 826 ) 827 ); 828 } 829 830 (mkIf (!cfg.distributedBuilds) { builders = null; }) 831 832 (mkIf (isNixAtLeast "2.3pre") { sandbox-fallback = false; }) 833 ]; 834 835 }; 836 837}