about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyan Lahfa <masterancpp@gmail.com>2024-02-25 21:08:19 +0100
committerGitHub <noreply@github.com>2024-02-25 21:08:19 +0100
commit5337ff6a805900a9b2efb9bd2c0252561a79da82 (patch)
tree70fac2619e2dd1ba7c4b257adeb23b58bd266346
parent5a7e08cd83dc81cd10fb8b021109329d68b53e5d (diff)
parente456032addae76701eb17e6c03fc515fd78ad74f (diff)
downloadnixlib-5337ff6a805900a9b2efb9bd2c0252561a79da82.tar
nixlib-5337ff6a805900a9b2efb9bd2c0252561a79da82.tar.gz
nixlib-5337ff6a805900a9b2efb9bd2c0252561a79da82.tar.bz2
nixlib-5337ff6a805900a9b2efb9bd2c0252561a79da82.tar.lz
nixlib-5337ff6a805900a9b2efb9bd2c0252561a79da82.tar.xz
nixlib-5337ff6a805900a9b2efb9bd2c0252561a79da82.tar.zst
nixlib-5337ff6a805900a9b2efb9bd2c0252561a79da82.zip
Merge pull request #254405 from lf-/jade/nix-path-flakes
nixos/flake: set up NIX_PATH and system flake registry automatically
-rw-r--r--flake.nix14
-rw-r--r--nixos/doc/manual/release-notes/rl-2405.section.md8
-rw-r--r--nixos/modules/misc/nixpkgs-flake.nix105
-rw-r--r--nixos/modules/module-list.nix1
4 files changed, 127 insertions, 1 deletions
diff --git a/flake.nix b/flake.nix
index 580f572ff32c..d920d5d0ddda 100644
--- a/flake.nix
+++ b/flake.nix
@@ -27,7 +27,19 @@
               # We set it to null, to remove the "legacy" entrypoint's
               # non-hermetic default.
               system = null;
-            } // args
+
+              modules = args.modules ++ [
+                # This module is injected here since it exposes the nixpkgs self-path in as
+                # constrained of contexts as possible to avoid more things depending on it and
+                # introducing unnecessary potential fragility to changes in flakes itself.
+                #
+                # See: failed attempt to make pkgs.path not copy when using flakes:
+                # https://github.com/NixOS/nixpkgs/pull/153594#issuecomment-1023287913
+                ({ config, pkgs, lib, ... }: {
+                  config.nixpkgs.flake.source = self.outPath;
+                })
+              ];
+            } // builtins.removeAttrs args [ "modules" ]
           );
       });
 
diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md
index ef7085d84967..b5973c19a2c4 100644
--- a/nixos/doc/manual/release-notes/rl-2405.section.md
+++ b/nixos/doc/manual/release-notes/rl-2405.section.md
@@ -20,6 +20,14 @@ In addition to numerous new and upgraded packages, this release has the followin
    - This can be disabled through the `environment.stub-ld.enable` option.
    - If you use `programs.nix-ld.enable`, no changes are needed. The stub will be disabled automatically.
 
+- On flake-based NixOS configurations using `nixpkgs.lib.nixosSystem`, NixOS will automatically set `NIX_PATH` and the system-wide flake registry (`/etc/nix/registry.json`) to point `<nixpkgs>` and the unqualified flake path `nixpkgs` to the version of nixpkgs used to build the system.
+
+  This makes `nix run nixpkgs#hello` and `nix-build '<nixpkgs>' -A hello` work out of the box with no added configuration, reusing dependencies already on the system.
+
+  This may be undesirable if nix commands are not going to be run on the built system since it adds nixpkgs to the system closure. For such closure-size-constrained non-interactive systems, this setting should be disabled.
+
+  To disable this, set [nixpkgs.flake.setNixPath](#opt-nixpkgs.flake.setNixPath) and [nixpkgs.flake.setFlakeRegistry](#opt-nixpkgs.flake.setFlakeRegistry) to false.
+
 - Julia environments can now be built with arbitrary packages from the ecosystem using the `.withPackages` function. For example: `julia.withPackages ["Plots"]`.
 
 - A new option `systemd.sysusers.enable` was added. If enabled, users and
diff --git a/nixos/modules/misc/nixpkgs-flake.nix b/nixos/modules/misc/nixpkgs-flake.nix
new file mode 100644
index 000000000000..8bfe05ca1994
--- /dev/null
+++ b/nixos/modules/misc/nixpkgs-flake.nix
@@ -0,0 +1,105 @@
+{ config, options, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.nixpkgs.flake;
+in
+{
+  options.nixpkgs.flake = {
+    source = mkOption {
+      # In newer Nix versions, particularly with lazy trees, outPath of
+      # flakes becomes a Nix-language path object. We deliberately allow this
+      # to gracefully come through the interface in discussion with @roberth.
+      #
+      # See: https://github.com/NixOS/nixpkgs/pull/278522#discussion_r1460292639
+      type = types.nullOr (types.either types.str types.path);
+
+      default = null;
+      defaultText = "if (using nixpkgsFlake.lib.nixosSystem) then self.outPath else null";
+
+      example = ''builtins.fetchTarball { name = "source"; sha256 = "${lib.fakeHash}"; url = "https://github.com/nixos/nixpkgs/archive/somecommit.tar.gz"; }'';
+
+      description = mdDoc ''
+        The path to the nixpkgs sources used to build the system. This is automatically set up to be
+        the store path of the nixpkgs flake used to build the system if using
+        `nixpkgs.lib.nixosSystem`, and is otherwise null by default.
+
+        This can also be optionally set if the NixOS system is not built with a flake but still uses
+        pinned sources: set this to the store path for the nixpkgs sources used to build the system,
+        as may be obtained by `builtins.fetchTarball`, for example.
+
+        Note: the name of the store path must be "source" due to
+        <https://github.com/NixOS/nix/issues/7075>.
+      '';
+    };
+
+    setNixPath = mkOption {
+      type = types.bool;
+
+      default = cfg.source != null;
+      defaultText = "config.nixpkgs.flake.source != null";
+
+      description = mdDoc ''
+        Whether to set {env}`NIX_PATH` to include `nixpkgs=flake:nixpkgs` such that `<nixpkgs>`
+        lookups receive the version of nixpkgs that the system was built with, in concert with
+        {option}`nixpkgs.flake.setFlakeRegistry`.
+
+        This is on by default for NixOS configurations built with flakes.
+
+        This makes {command}`nix-build '<nixpkgs>' -A hello` work out of the box on flake systems.
+
+        Note that this option makes the NixOS closure depend on the nixpkgs sources, which may add
+        undesired closure size if the system will not have any nix commands run on it.
+      '';
+    };
+
+    setFlakeRegistry = mkOption {
+      type = types.bool;
+
+      default = cfg.source != null;
+      defaultText = "config.nixpkgs.flake.source != null";
+
+      description = mdDoc ''
+        Whether to pin nixpkgs in the system-wide flake registry (`/etc/nix/registry.json`) to the
+        store path of the sources of nixpkgs used to build the NixOS system.
+
+        This is on by default for NixOS configurations built with flakes.
+
+        This option makes {command}`nix run nixpkgs#hello` reuse dependencies from the system, avoid
+        refetching nixpkgs, and have a consistent result every time.
+
+        Note that this option makes the NixOS closure depend on the nixpkgs sources, which may add
+        undesired closure size if the system will not have any nix commands run on it.
+      '';
+    };
+  };
+
+  config = mkIf (cfg.source != null) (mkMerge [
+    {
+      assertions = [
+        {
+          assertion = cfg.setNixPath -> cfg.setFlakeRegistry;
+          message = ''
+            Setting `nixpkgs.flake.setNixPath` requires that `nixpkgs.flake.setFlakeRegistry` also
+            be set, since it is implemented in terms of indirection through the flake registry.
+          '';
+        }
+      ];
+    }
+    (mkIf cfg.setFlakeRegistry {
+      nix.registry.nixpkgs.to = mkDefault {
+        type = "path";
+        path = cfg.source;
+      };
+    })
+    (mkIf cfg.setNixPath {
+      # N.B. This does not include nixos-config in NIX_PATH unlike modules/config/nix-channel.nix
+      # because we would need some kind of evil shim taking the *calling* flake's self path,
+      # perhaps, to ever make that work (in order to know where the Nix expr for the system came
+      # from and how to call it).
+      nix.nixPath = mkDefault ([ "nixpkgs=flake:nixpkgs" ]
+        ++ optional config.nix.channel.enable "/nix/var/nix/profiles/per-user/root/channels");
+    })
+  ]);
+}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index d9e95b8207f2..8683af5ed439 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -133,6 +133,7 @@
   ./misc/meta.nix
   ./misc/nixops-autoluks.nix
   ./misc/nixpkgs.nix
+  ./misc/nixpkgs-flake.nix
   ./misc/passthru.nix
   ./misc/version.nix
   ./misc/wordlist.nix