nix icon indicating copy to clipboard operation
nix copied to clipboard

Locked registry entries

Open lheckemann opened this issue 3 years ago • 3 comments

Is your feature request related to a problem? Please describe. I want to pin nixpkgs on my NixOS machine to the version used to build the system.

I can currently set nix.registry.nixpkgs.flake = inputs.nixpkgs;. However, this discards some important metadata:

nix-repl> (builtins.getFlake "nixpkgs").sourceInfo
{ outPath = /nix/store/wxn6cfj8p7kf720jyz3r3xfw3xvn6kdh-source/; }

nix-repl> (builtins.getFlake "github:nixos/nixpkgs/nixos-22.05").sourceInfo
{ lastModified = 1665328694; lastModifiedDate = "20221009151814"; outPath = https://github.com/nixos/nixpkgs/blob/9282141c8bc05568ec0e342eac39df72603aa9fa/; rev = "9282141c8bc05568ec0e342eac39df72603aa9fa"; shortRev = "9282141"; }

Describe the solution you'd like The registry should support all the attributes of a locked input. Ideally, it should also preserve where the input came from (the original flake reference? I'm not sure if this is possible, but it would be good if it were) and correspondingly (though this is a nixpkgs issue) nix.registry.*.flake should pass these through from a given input.

Describe alternatives you've considered The current situation discards metadata like the last modified date and the revision. This results in version strings being different when building a NixOS from the locally registered flake.

lheckemann avatar Oct 11 '22 12:10 lheckemann

I'm thinking about improving pinning by decoupling pinning a registry entry from pre-caching a store path.

The pinning can be done in the same way as nix registry pin, i.e. by creating a system-wide registry entry

    {
      "from": {
        "id": "nixpkgs",
        "type": "indirect"
      },
      "to": {
        "lastModified": 1665492574,
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "a830a677c02b7bbdb7e4ec49ca5ed873f4df5847",
        "type": "github"
      }
    }

Then, separately and optionally, we can have a mapping from locked flakerefs to store paths, e.g.

    {
      "ref": {
        "lastModified": 1665492574,
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "a830a677c02b7bbdb7e4ec49ca5ed873f4df5847",
        "type": "github"
      },
      "storePath": "/nix/store/abcdef..."
    }

This way, you can lock nixpkgs to the version used to build the system, without making nixpkgs part of the system closure. (I.e. it will be fetched on demand if it has been garbage-collected.)

The legacy NIX_PATH can already be handled by doing:

nix.nixPath = [ "nixpkgs=flake:nixpkgs" ];

i.e. it no longer requires the store path to be part of the system closure - it will be fetched on demand if it isn't.

edolstra avatar Oct 11 '22 13:10 edolstra

What if I do want to prefetch, so that I can use it when I don't have a good internet connection? On-demand fetching can be very convenient, but it's quite annoying when I have to wait for a download of something that I should already have lying around.

lheckemann avatar Oct 14 '22 15:10 lheckemann

This has been such a pain point for me. I have been using nix for half a decade, and still haven't found a way to pin nixpkgs to such that it pre-fetches on nixos build and avoids refetches. I have in my nixos config:

nix.registry.nixpkgs.to = {
  owner = "NixOS";
  repo = "nixpkgs";
  rev = inputs.nixpkgs.rev;
  type = "github";
};

which works to pin but nixpkgs still gets refetched after tarball-ttl (via Pinned nixpkgs keeps getting garbage-collected - Help - NixOS Discourse) . I just want to work on applications but I spend all my time in tooling hell :sob:.

edit: I just tried @lheckemann's config line above (nix.registry.nixpkgs.flake = inputs.nixpkgs;) and the resulting registry entry points at a store path, which was fetched on build. I think this may actually solve my pain point, which is amazing. Where to document to spread this knowledge around...

edrex avatar May 29 '24 23:05 edrex