about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/misc/nixpkgs-flake.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/misc/nixpkgs-flake.nix')
-rw-r--r--nixpkgs/nixos/modules/misc/nixpkgs-flake.nix105
1 files changed, 105 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/misc/nixpkgs-flake.nix b/nixpkgs/nixos/modules/misc/nixpkgs-flake.nix
new file mode 100644
index 000000000000..8bfe05ca1994
--- /dev/null
+++ b/nixpkgs/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");
+    })
+  ]);
+}