NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.51k stars 1.5k forks source link

Nix flake metadata gives a hashed input URL which makes Nix crash if I use it #9303

Open puffnfresh opened 11 months ago

puffnfresh commented 11 months ago

Describe the bug

Nix flake metadata gives a narHash input URL which makes it crash if I feed it back into the inputs.

Steps To Reproduce

Given a non-flake input in my flake.nix:

{
  inputs.example = {
    flake = false;
    url = "https://raw.githubusercontent.com/NixOS/nix/master/README.md";
  };

  outputs = { self, example }:
    { example = example.outPath; };
}

Nix gives back a URL with a narHash (which I think represents a locked URL) when I ask for the metadata:

$ nix flake metadata
Resolved URL:  git+file:///tmp/example
Locked URL:    git+file:///tmp/example
Path:          /nix/store/nwwscyv86ilp9p22n92zbplrbmgsmq1p-source
Last modified: 1970-01-01 11:00:00
Inputs:
└───example: https://raw.githubusercontent.com/NixOS/nix/master/README.md?narHash=sha256-KD/GlrKc53UFs%2BYo8WxGL0jXV1laNFgqOcdAEWJJark%3D

I assume I can put that (locked, hopefully) URL back into my flake.nix:

{
  inputs.example = {
    flake = false;
    url = "https://raw.githubusercontent.com/NixOS/nix/master/README.md?narHash=sha256-KD/GlrKc53UFs%2BYo8WxGL0jXV1laNFgqOcdAEWJJark%3D";
  };

  outputs = { self, example }:
    { example = example.outPath; };
}

But when evaluating, I get:

using cache entry '{"name":"source","type":"file","url":"https://raw.githubusercontent.com/NixOS/nix/master/README.md?narHash=sha256-KD/GlrKc53UFs%2BYo8WxGL0jXV1laNFgqOcdAEWJJark%3D"}' -> '{"etag":"W/\"e2018b86bcbeac881e733adc60cfafc4285e3b368225cd8beec3deded0ad8977\"","url":"https://raw.githubusercontent.com/NixOS/nix/master/README.md?narHash=sha256-KD/GlrKc53UFs%2BYo8WxGL0jXV1laNFgqOcdAEWJJark%3D"}', '/nix/store/zfz5ziac7kbab6zyv9n1a0n3c69m7nsw-source'
performing daemon worker op: 26
got tree '/nix/store/zfz5ziac7kbab6zyv9n1a0n3c69m7nsw-source' from 'https://raw.githubusercontent.com/NixOS/nix/master/README.md?narHash=sha256-KD/GlrKc53UFs%2BYo8WxGL0jXV1laNFgqOcdAEWJJark%3D'
nix: src/libexpr/flake/flake.cc:70: std::tuple<nix::fetchers::Tree, nix::FlakeRef, nix::FlakeRef> nix::flake::fetchOrSubstituteTree(nix::EvalState&, const nix::FlakeRef&, bool, FlakeCache&): Assertion `!originalRef.input.getNarHash() || tree.storePath == originalRef.input.computeStorePath(*state.store)' failed.
Aborted (core dumped)

Expected behavior

Nix does not crash. It either gives a error saying this is intentionally unsupported for a given reason, or it successfully accepts the narHash URL it spits out.

nix-env --version output

Happens with both nix and nixUnstable from nixpkgs.

nix-env (Nix) 2.17.1
nix-env (Nix) 2.18.1
puffnfresh commented 11 months ago

I can't figure out why the !getNarHash assert was added:

https://github.com/NixOS/nix/commit/950b46821f644eb3f92725460584a3102f356179#diff-d4441d6156ea52c005e1517d6da41bdf989cff029b61d5f3e9f662a51861f5f2R100

puffnfresh commented 11 months ago

Adding an explicit type of "file" makes things work as expected:

{
  inputs.example = {
    flake = false;
    type = "file";
    url = "https://raw.githubusercontent.com/NixOS/nix/master/README.md?narHash=sha256-KD/GlrKc53UFs%2BYo8WxGL0jXV1laNFgqOcdAEWJJark%3D";
  };

  outputs = { self, example }:
    { example = builtins.readFile example.outPath; };
}
bolives-hax commented 1 month ago

when instead trying to specify narHash as an attribute instead as part of the url like

{  # ... 
    inputTxt = {
      url = "https://raw.some.pastethingy/paste.txt";
      narHash="sha256-Om0SdmB7o11zKDXCab7WSl0jyt/FVF92NA766FOuvXI=";
      type = "file";
      flake = false;
    };
}; 
# outputs {....}: {};

results in :

downloading https://raw.some.pastethingy/paste.txt
nix: src/libexpr/flake/flake.cc:71: std::tuple<nix::fetchers::Tree, nix::FlakeRef, nix::FlakeRef> nix::flake::fetchOrSubstituteTree
(nix::EvalState&, const nix::FlakeRef&, bool, FlakeCache&): Assertion `!originalRef.input.getNarHash() || tree.storePath == origina
lRef.input.computeStorePath(*state.store)' failed.
[1]    50190 abort (core dumped)  nix flake update`

while however :

{  # ... 
    inputTxt = {
      url = "https://raw.some.pastethingy/paste.txt?narHash="sha256-Om0SdmB7o11zKDXCab7WSl0jyt/FVF92NA766FOuvXI=";
      type = "file";
      flake = false;
    };
}; 

i get a happy updated input and everything behaves like intended. appending the narHash behind the url using ?narHash=.... while setting the type to file works fine and just like intended.

If I find the time after finish my nixos-s390x overlay I could look at why specifically this is happening and maybe propose a fix. If someone else is faster than me feel free to do it as I will check this issue once more before id actually look into fixing it

While I don't know yet why its happening I think it should be rather simple to fix. I think I will look into this once I finish my nixos-on-s390x overlays. If someone else gets to it before I begun (will write that here then) thats maybe even better as I can focus on other things thing :) For now this hack should do the job