diff --git a/flake.nix b/flake.nix index fa00bffcdf92fce..a9332719db92fd9 100644 --- a/flake.nix +++ b/flake.nix @@ -25,6 +25,7 @@ system.nixos.versionSuffix = ".${final.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}"; system.nixos.revision = final.mkIf (self ? rev) self.rev; + nixpkgs.flake.source = final.mkDefault (toString self); }]; } // lib.optionalAttrs (! args?system) { # Allow system to be set modularly in nixpkgs.system. diff --git a/nixos/doc/manual/release-notes/rl-2311.section.md b/nixos/doc/manual/release-notes/rl-2311.section.md index 20ffcb5ebd87391..6ddd46c9057e743 100644 --- a/nixos/doc/manual/release-notes/rl-2311.section.md +++ b/nixos/doc/manual/release-notes/rl-2311.section.md @@ -8,6 +8,12 @@ - LXD now supports virtual machine instances to complement the existing container support +- NIX_PATH and the system flake registry will be automatically set up for + flake-based NixOS configurations if + [nixpkgs.flake.setNixPath](#opt-nixpkgs.flake.setNixPath) and + [nixpkgs.flake.setFlakeRegistry](#opt-nixpkgs.flake.setFlakeRegistry) are + set, respectively. These will be made true by default in a future release. + ## New Services {#sec-release-23.11-new-services} - [MCHPRS](https://github.com/MCHPR/MCHPRS), a multithreaded Minecraft server built for redstone. Available as [services.mchprs](#opt-services.mchprs.enable). diff --git a/nixos/modules/config/nix.nix b/nixos/modules/config/nix.nix index cee4f54db0cb5f9..008bed2f9e197e2 100644 --- a/nixos/modules/config/nix.nix +++ b/nixos/modules/config/nix.nix @@ -332,6 +332,16 @@ in always allowed to connect. ''; }; + + flake-registry = mkOption { + type = types.str; + default = "https://channels.nixos.org/flake-registry.json"; + description = lib.mdDoc '' + Path or URI of the global flake registry. + + When empty, disables the global flake registry. + ''; + }; }; }; default = { }; diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix index f9d8bccea284359..f206d7b9681aae1 100644 --- a/nixos/modules/misc/nixpkgs.nix +++ b/nixos/modules/misc/nixpkgs.nix @@ -328,64 +328,122 @@ in Ignored when `nixpkgs.pkgs`, `nixpkgs.localSystem` or `nixpkgs.hostPlatform` is set. ''; }; - }; - config = { - _module.args = { - pkgs = - # We explicitly set the default override priority, so that we do not need - # to evaluate finalPkgs in case an override is placed on `_module.args.pkgs`. - # After all, to determine a definition priority, we need to evaluate `._type`, - # which is somewhat costly for Nixpkgs. With an explicit priority, we only - # evaluate the wrapper to find out that the priority is lower, and then we - # don't need to evaluate `finalPkgs`. - lib.mkOverride lib.modules.defaultOverridePriority - finalPkgs.__splicedPackages; - }; + flake = { + source = mkOption { + type = types.nullOr types.str; - assertions = let - # Whether `pkgs` was constructed by this module. This is false when any of - # nixpkgs.pkgs or _module.args.pkgs is set. - constructedByMe = - # We set it with default priority and it can not be merged, so if the - # pkgs module argument has that priority, it's from us. - (lib.modules.mergeAttrDefinitionsWithPrio options._module.args).pkgs.highestPrio - == lib.modules.defaultOverridePriority - # Although, if nixpkgs.pkgs is set, we did forward it, but we did not construct it. - && !opt.pkgs.isDefined; - in [ - ( - let - nixosExpectedSystem = - if config.nixpkgs.crossSystem != null - then config.nixpkgs.crossSystem.system or (lib.systems.parse.doubleFromSystem (lib.systems.parse.mkSystemFromString config.nixpkgs.crossSystem.config)) - else config.nixpkgs.localSystem.system or (lib.systems.parse.doubleFromSystem (lib.systems.parse.mkSystemFromString config.nixpkgs.localSystem.config)); - nixosOption = - if config.nixpkgs.crossSystem != null - then "nixpkgs.crossSystem" - else "nixpkgs.localSystem"; - pkgsSystem = finalPkgs.stdenv.targetPlatform.system; - in { - assertion = constructedByMe -> !hasPlatform -> nixosExpectedSystem == pkgsSystem; - message = "The NixOS nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but NixOS was configured for system ${nixosExpectedSystem} via NixOS option ${nixosOption}. The NixOS system settings must match the Nixpkgs target system."; - } - ) - { - assertion = constructedByMe -> hasPlatform -> legacyOptionsDefined == []; - message = '' - Your system configures nixpkgs with the platform parameter${optionalString hasBuildPlatform "s"}: - ${hostPlatformLine - }${buildPlatformLine - } - However, it also defines the legacy options: - ${concatMapStrings showOptionWithDefLocs legacyOptionsDefined} - For a future proof system configuration, we recommend to remove - the legacy definitions. + default = null; + + description = mdDoc '' + The derivation to the nixpkgs sources, as a string with context. This + is set up by the nixpkgs flake. + ''; + }; + + setNixPath = mkOption { + type = types.bool; + + default = false; + + description = mdDoc '' + Whether to create /etc/nix/inputs/nixpkgs as a symlink and set + NIX_PATH to include /etc/nix/inputs/nixpkgs. + + This will be true by default for flake-based configurations in a + future release. + ''; + }; + + setFlakeRegistry = mkOption { + type = types.bool; + + default = false; + + description = mdDoc '' + Whether to set nixpkgs in the local flake registry and disable the + external flake registry. + + This will be true by default for flake-based configurations in a + future release. ''; - } - ]; + }; + }; }; + config = mkMerge [ + { + _module.args = { + pkgs = + # We explicitly set the default override priority, so that we do not need + # to evaluate finalPkgs in case an override is placed on `_module.args.pkgs`. + # After all, to determine a definition priority, we need to evaluate `._type`, + # which is somewhat costly for Nixpkgs. With an explicit priority, we only + # evaluate the wrapper to find out that the priority is lower, and then we + # don't need to evaluate `finalPkgs`. + lib.mkOverride lib.modules.defaultOverridePriority + finalPkgs.__splicedPackages; + }; + + assertions = let + # Whether `pkgs` was constructed by this module. This is false when any of + # nixpkgs.pkgs or _module.args.pkgs is set. + constructedByMe = + # We set it with default priority and it can not be merged, so if the + # pkgs module argument has that priority, it's from us. + (lib.modules.mergeAttrDefinitionsWithPrio options._module.args).pkgs.highestPrio + == lib.modules.defaultOverridePriority + # Although, if nixpkgs.pkgs is set, we did forward it, but we did not construct it. + && !opt.pkgs.isDefined; + in [ + ( + let + nixosExpectedSystem = + if config.nixpkgs.crossSystem != null + then config.nixpkgs.crossSystem.system or (lib.systems.parse.doubleFromSystem (lib.systems.parse.mkSystemFromString config.nixpkgs.crossSystem.config)) + else config.nixpkgs.localSystem.system or (lib.systems.parse.doubleFromSystem (lib.systems.parse.mkSystemFromString config.nixpkgs.localSystem.config)); + nixosOption = + if config.nixpkgs.crossSystem != null + then "nixpkgs.crossSystem" + else "nixpkgs.localSystem"; + pkgsSystem = finalPkgs.stdenv.targetPlatform.system; + in { + assertion = constructedByMe -> !hasPlatform -> nixosExpectedSystem == pkgsSystem; + message = "The NixOS nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but NixOS was configured for system ${nixosExpectedSystem} via NixOS option ${nixosOption}. The NixOS system settings must match the Nixpkgs target system."; + } + ) + { + assertion = constructedByMe -> hasPlatform -> legacyOptionsDefined == []; + message = '' + Your system configures nixpkgs with the platform parameter${optionalString hasBuildPlatform "s"}: + ${hostPlatformLine + }${buildPlatformLine + } + However, it also defines the legacy options: + ${concatMapStrings showOptionWithDefLocs legacyOptionsDefined} + For a future proof system configuration, we recommend to remove + the legacy definitions. + ''; + } + ]; + } + (mkIf (cfg.flake.source != null) (mkMerge [ + (mkIf cfg.flake.setNixPath { + environment.etc."nix/inputs/nixpkgs".source = mkDefault cfg.flake.source; + nix.nixPath = mkDefault [ "nixpkgs=/etc/nix/inputs/nixpkgs" ]; + }) + (mkIf cfg.flake.setFlakeRegistry { + nix.registry.nixpkgs.to = mkDefault { + type = "path"; + path = cfg.flake.source; + }; + # This is set due to a Nix bug where the registry json is fetched on + # every `nix` invocation even if the requested flake is entirely local. + nix.settings.flake-registry = mkDefault ""; + }) + ])) + ]; + # needs a full nixpkgs path to import nixpkgs meta.buildDocsInSandbox = false; }