NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18k stars 14.01k forks source link

buildStackProject: fails downloading resolver #32005

Closed infinisil closed 4 years ago

infinisil commented 6 years ago

Issue description

According to #30072 it should now be possible to use nix-build to build a buildStackProject derivation. This however doesn't seem to work due to stack failing to download the resolver build plan:

Downloading lts-9.14 build plan ...
HttpExceptionRequest Request {
  host                 = "raw.githubusercontent.com"
  port                 = 443
  secure               = True
  requestHeaders       = []
  path                 = "/fpco/lts-haskell/master//lts-9.14.yaml"
  queryString          = ""
  method               = "GET"
  proxy                = Nothing
  rawBody              = False
  redirectCount        = 10
  responseTimeout      = ResponseTimeoutDefault
  requestVersion       = HTTP/1.1
}
 (ConnectionFailure Network.BSD.getProtocolByName: does not exist (no such protocol name: tcp))
builder for ‘/nix/store/yg3yi8655dmazr072f1pww8rvfa8zyd2-Test.drv’ failed with exit code 1

This is the same error as in #19526 from before the new buildStackProject, which was closed without a solution.

Pinging the participants of these two issues @ElvishJerricco @peti @mboes @vaibhavsagar @wizzup and @vklquevs

Steps to reproduce

Technical details

ElvishJerricco commented 6 years ago

Related? https://github.com/bos/wreq/issues/5#issuecomment-108086543

infinisil commented 6 years ago

I guess it makes sense: The nix sandbox doesn't allow networking for non-fixed-output derivations. As expected, turning off sandboxing makes it work: nix-build --option build-use-sandbox false

The resolver build dependencies should be downloaded with a fixed-output derivation instead, but I'm not sure how to do that. Will tinker with it though.

ElvishJerricco commented 6 years ago

@peti I'd say this issue is valid. I believe the stack home can be a fixed output derivation, which would actually be enough to change the preferLocalBuild thing.

ElvishJerricco commented 6 years ago

Er, actually no. Though I bet Stack's build plan is 100% deterministic, GHC is not. So the libraries Stack builds won't be fixed. Ugh.

ElvishJerricco commented 6 years ago

I wonder if you can get stack to do the 100% deterministic build plan as a fixed output derivation, do the actual Haskell dependency building as another derivation, and finally have the stack project on top of all that.

EDIT: wording

peti commented 6 years ago

Though I bet Stack's build plan is 100% deterministic ...

Unfortunately, stack's build plan is not 100% deterministic due to the wonders of destructive editing on Hackage. New revisions of a published package can modify the version constraints on dependencies and therefore affect the set of packages required for the build.

ElvishJerricco commented 6 years ago

I thought Stackage had a bunch of stuff to deal with that? I don’t have a source; just vaguely remember some rants on Stack issue pages about this stuff.

peti commented 6 years ago

If it does, then I am not aware of it.

ElvishJerricco commented 6 years ago

@peti So newer resolvers do pin revisions, but older ones do not. Also I believe that extra-deps never have their revisions pinned

Nevertheless, I think we can fix all of this by pinning the Hackage DB version that stack looks at.

infinisil commented 5 years ago

I'm going to reopen this issue because this should at least be documented in the manual.

peti commented 5 years ago

Please don't keep this issue open. If you feel like there should be documentation of the status quo, then please don't hesitate to submit a PR that extends the documentation. Keeping old issues open that nobody has acted upon for 1+ years is no good way to accomplish anything. Doing it is a good way to accomplish things you are about.

infinisil commented 5 years ago

This issue is not resolved and the issue description is still as valid as it was when I opened it, as already mentioned by @ElvishJerricco a while ago. I've reopened this because I just had to explain to a user on IRC how buildStackProject doesn't work with the sandbox. We can't just close issues because nobody has currently time to work on it. We're all busy here, but issues don't go away because of that.

peti commented 5 years ago

No-one disputes that this issue exists. It does. But that does not mean that we need to track it in the Nixpkgs bugtracker as an open issue. We cannot possibly have an open bug in here for every single use case that some person somewhere in the world might think of. It's too much noise and it drowns out that issues that are more important.

infinisil commented 5 years ago

This isn't a random usecase though, it's the way to have a Nix build for a stack project. By keeping it open it serves as a ToDo item, for nixpkgs maintainers and myself, this gets forgotten otherwise, and indeed I did already forget about this because you closed this a while ago, yet the problem is still not solved or even remedied. Closed issues are for "won't fix" or "not an issue" or "issue is fixed", and not "don't want to fix right now".

infinisil commented 5 years ago

Some excerpts from #nixos:

2017-11-24:

14:55 <infinisil> How am I supposed to build a haskell stack project with Nix? I get this error: https://github.com/NixOS/nixpkgs/issues/19526 and I'm using the new supposedly nix-buildable thing: https://github.com/NixOS/nixpkgs/pull/30072
15:05 <elvishjerricco> infinisil: That probably has something to do with the fact that Stack has to fetch an lts. I’ve only ever used it for blank GHC “resolvers” so that I could just use Nix’s GHC and package set
15:07 <elvishjerricco> infinisil: I wouldn’t be terribly surprised if you need to add some networking component to the definition of buildStackProject
15:07 <elvishjerricco> And FYI, you shouldn’t need to add stack to your buildInputs
15:08 <infinisil> elvishjerricco: Yeah not doing that
15:08 <infinisil> elvishjerricco: I guess I'll try to use nix's dependencies instead, although not sure what stack's good for then
15:09 <elvishjerricco> I only ever wanted it so I could get multi package projects easily
15:09 <vaibhavsagar> infinisil: can you share your project?
15:11 <infinisil> vaibhavsagar: yes, hold on
15:12 <infinisil> vaibhavsagar: https://github.com/greensn/CardGame/tree/stm/Server
15:12 <infinisil> (Code is ugly as hell, it's my first Haskell project ever :P)
15:20 <infinisil> vaibhavsagar: (if you happen to try it out, i just committed a version with latest nixos-unstable pinned)
15:52 <infinisil> vaibhavsagar: elvishjerricco: I opened an issue for it: https://github.com/NixOS/nixpkgs/issues/32005
15:53 <infinisil> Would be nice if somebody could add the Topic: Haskell label to it ^^
15:53 <elvishjerricco> infinisil: Actually I think I might know the cause of that.
15:54 <elvishjerricco> Let me see if I can find it again...
15:59 <infinisil> elvishjerricco: That would be nice :)
15:59 <elvishjerricco> infinisil: Left a comment pointing at a similar thing. I believe it's just that the environment doesn't have that `/etc/protocols` thing.
16:00 <infinisil> elvishjerricco: Hmm, I don't know how to do that in nix though
16:01 <elvishjerricco> infinisil: Me either. I'm actually surprised it was an error. It's probably because you used the Nix sandboxing. Not sure how to fix it in the sandbox...
16:02 <infinisil> elvishjerricco: Yeah, turning off sandbox makes it work
16:03 <elvishjerricco> infinisil: Ok. Still, probably needs to be fixed to make it work in the sandbox
16:03 <infinisil> elvishjerricco: Hmm right, and you can't download stuff with non-fixed-output derivations
16:05 <elvishjerricco> infinisil: I think the right solution is that the stack home needs to be a fixed output derivation, and then stack builds depend on the home. This would also help by caching all of stack's Haskell builds
16:06 <infinisil> elvishjerricco: Yeah, well damn :( 

2019-03-03:

02:27 <suzu> ok im completely fucking stumped
02:27 <suzu> i can't get nix to build a stack project
02:28 <clever> suzu: what is the error?
02:28 <suzu> i'm using buildStackProject and it just dies with no good error
02:28 <suzu> Configuring GHC ...
02:28 <suzu> Received ExitFailure 1 when running
[...]
02:33 <suzu> clever: do you know why haskell.lib.buildStackProject wont work in the first place?
02:33 <clever> suzu: not really
02:33 <suzu> lol ok
02:33 <suzu> i have spent several hours ripping my hair out
02:33 <suzu> :(( 

2019-05-26:

19:09 <chris_> infinisil: Ah that is so useful. I tried `.` and it came up with a syntax error so assume it wasn't possible. Well I've managed to run into another error but I guess I'll start googling. However if it's an easy fix, when stack appears to build it fails with ` (ConnectionFailure Network.BSD.getProtocolByName: does not exist (no such protocol name: tcp)))
19:10 <infinisil> chris_: You need to disable the sandbox to be able to do buildStackProject builds unfortunately..
19:10 <infinisil> chris_: --option sandbox false
19:11 <infinisil> Huh, this isn't even mentioned in the manual though :/
19:16 <infinisil> Heh, couldn't even remember, but apparently I opened an issue regarding this a while ago: #32005
19:16 <{^_^}> https://github.com/NixOS/nixpkgs/issues/32005 (by Infinisil, 1 year ago, open): buildStackProject: fails downloading resolver
[...]
19:26 <chris_> infinisil: That explains it, thank you! 

That's at least 4 known people (with the person in https://github.com/NixOS/nixpkgs/issues/19526, which you also closed) to have had this issue. And I think it's fair to double this to include instances I couldn't find. That's a significant number. Do we close issues for [insert random software here] because the single person using it encounters an issue with it? No. Then we also shouldn't close this issue which is a problem for an order of magnitude more people.

jkarni commented 5 years ago

Would a good approach be to have buildStackProject take a hash for the stackage snapshot (like fetchgit etc), in which case we can allow ourselves impure downloads?

ElvishJerricco commented 4 years ago

@jkarni The issue is in determining what exactly to hash. Stack needs to download info from Hackage to build a plan, but this info is ever-changing, as the Hackage index changes. So you have to somehow hash the plan that Stack comes up with, and that plan needs to be 100% deterministic (unclear whether it really is, given extra-deps). This fixed-output derivation also needs to include all the package source tarballs you'll need, since those need to be downloaded and hashed as well. And you have to do all that without allowing Stack to build any of the libraries, because GHC is nondeterministic and would ruin the hash.

The simplest thing for the plan part would be somehow controlling the Hackage index tarfile that Stack uses. This tarfile is append-only, with new entries having a later date, so simply truncating it on a date set in the recent past can make a fixed-output derivation. If Stack can be told to use this tarfile, the plan can be constructed without internet access. But this doesn't include source hashes, so you'd need either IFD, or a separate derivation with a separate user-supplied hash to represent all the required sources.

It's a mess.

infinisil commented 4 years ago

Reopening so I can close it with a PR that actually addresses this..