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