Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

top-level: add asOf helper #22058

Closed
wants to merge 1 commit into from
Closed

top-level: add asOf helper #22058

wants to merge 1 commit into from

Conversation

copumpkin
Copy link
Member

I discussed this on IRC a while back. It's currently using import-from-derivation which isn't ideal, but works fine in practice, and allows us to request specific versions of nixpkgs. I often use something like this inside local default.nix to guarantee that multiple developers are using the exact same versions of dependencies and to get fine-grained control over when we upgrade them. As I mention in the comment, fetchTarball would have nicer behavior here, but at least for my uses, I need to lock down the sha256, so I figured I'd stick with this until a new version of Nix that supports a locked-down fetchTarball is released.

I'd probably mandate that this not be used anywhere inside nixpkgs, but it can be really nice when depending on nixpkgs from external projects.

I wasn't sure which parameters to pass through (the inherit system config platform; thing I have right now). Just naming all the parameters we pass into top-level.nix and passing them in doesn't work, probably due to the factoring out of the fixed points and impurities that @Ericson2314's been doing recently. Open to suggestions on how to do that better.

cc @edolstra @shlevy @domenkozar

@shlevy
Copy link
Member

shlevy commented Jan 23, 2017

Why not just use the fetchTarball from nixUnstable and tell users to upgrade if they don't have it? It's not like this is going to be needed for core nixpkgs usage or anything.

@copumpkin
Copy link
Member Author

copumpkin commented Jan 23, 2017

Because I use it on a bunch of systems today and nobody's using nixUnstable (in part because there have been big warnings saying that nixUnstable is very unstable right now) 😛 I'd rather not force everyone to upgrade before this thing works, especially when there's little downside to this approach.

@shlevy
Copy link
Member

shlevy commented Jan 23, 2017

Eh, OK 👅 Fine by me

@Ericson2314
Copy link
Member

Hmm, as one would never use this within nixpkgs, I wish there was a more "out of band" location for it within the repo. Maybe /lib, which, while also the heart / deepest import, can be used to without nixpkgs so it makes some sense?

As to the arguments, they still in much flux----which makes pinning packages difficult anyways if one is pinning nixpkgs before and after my changes.

All in all, it seems like very little code to abstract over, shrugs. I assumed this is used in situations like https://github.com/reflex-frp/reflex-platform/blob/develop/nixpkgs/default.nix --- but in that specific example, this wouldn't exactly fit anyways?

@Ericson2314
Copy link
Member

In it's defence, there are number of instances of needing nixpkgs just to get another instances of nixpkgs---e.g. picking nixpkgs from the module system, or for the new command line in lieu of channels. Together, these constitute a good need for a general solution.

@edolstra
Copy link
Member

I'm not really seeing the use of this. This adds a function to Nixpkgs to fetch Nixpkgs, which presents an obvious chicken-and-egg problem. Indeed you're better off using fetchTarball, which in the next Nix release supports a sha256 attribute (NixOS/nix@06bbfb6).

Also the name asOf is very non-descriptive.

@copumpkin
Copy link
Member Author

copumpkin commented Jan 25, 2017

@edolstra I thought it was sort of cute to write pkgs.asOf { rev = "12345"; ... } 😄 Would you accept it with a better name? There doesn't seem to be much of a downside to adding something like this, to me, but having a name that people can agree on would also be nice.

The idea would be to be able to say, in my configuration.nix, services.postgresql.package = (pkgs.asOf { rev = "12345"; ... }).postgresql. Basically just gives me a simple and succinct way to reach into nixpkgs history and mix and match versions of nixpkgs, sometimes even in the same configuration. Sometimes I need a fix for one thing but then another unrelated thing gets upgraded in the same channel and that breaks something else.

I know that fetchTarball can do this in the unreleased version, but what's so bad about this one for the use case I describe above?

@Ericson2314
Copy link
Member

Ericson2314 commented Jan 25, 2017

The idea would be to be able to say, in my configuration.nix...

Should this be a NixOS helper then? Like in the NixOS Lib?

@copumpkin
Copy link
Member Author

copumpkin commented Jan 25, 2017 via email

@Ericson2314
Copy link
Member

@copumpkin just aesthetically trying to avoid the nixpkgs-fetches-nixpkgs scenario. Even though with NixOS being in the same repo, its hardly a practical improvement.

I'll not be a roadblock here, just wishing there was a more pleasing solution long term.

@copumpkin
Copy link
Member Author

copumpkin commented Jan 25, 2017

I'm not really seeing what's so fundamentally wrong with nixpkgs-fetches-nixpkgs. It seems like a reasonable place to stash up-to-date knowledge of a canonical place where nixpkgs lives and how to fetch particular versions of it.

@Ericson2314
Copy link
Member

Ericson2314 commented Jan 25, 2017

@copumpkin Sorry I can't come up with a good argument---tbh in programming as everywhere else my design/aesthetic concerns are gut instincts only receiving a post-hoc rationalization. The best I could come up with was where the asOf happened to coincide with the current version, extra work would be needed, but in a post-channels world that may well be not the case.

This is why I don't want my concerns to actually block this :)

What would being a NixOS helper change though? I don't want to set it on a module level because then I can't control it in a fine-grained manner.

I think NixOS should definitely work with multiple nixpkgs---we can think about this separate from this patch though

@copumpkin
Copy link
Member Author

I think ultimately what I really want is super lightweight named channels that I can easily create/destroy/update on the fly 😄 I still don't have a good grasp of @edolstra's plans to abolish channels, but until we get that, I really find myself using something like this quite often.

Take e.g., @jwiegley who often complains (in the ##nix-darwin IRC channel) that the packages he uses in his shell environments break in master. Something like this allows him to lock particular ones that break in master to known-good versions, but to otherwise track master. If you use a lot of it, it becomes a bit of a maintenance pain, which is why we need to rethink how we do channels, but until then I think this at least gives us an "easy" way to hop across versions of nixpkgs without keeping half a dozen nixpkgs clones lying around.

@edolstra
Copy link
Member

Well, the idea is that you write your shell.nix like this:

with import (fetchTarball { 
  url = https://github.com/NixOS/nixpkgs/archive/2766a4b44ee6eafae03a042801270c7f6b8ed32a.tar.gz;
  sha256 = ...; # optional
}) {};
...

This involves only one version of Nixpkgs, namely the one you specify.

@copumpkin
Copy link
Member Author

Sure, and now people who want it have to remember the GitHub archive URL scheme (because any abstraction over that would need to live somewhere), and if they want that sha256 field they need to use unreleased software that just underwent a major refactor.

@copumpkin
Copy link
Member Author

Anyway, I give up. The amount of time that's going into justifying these 5 lines of code far exceeds what makes sense for me to argue for.

@copumpkin copumpkin closed this Jan 25, 2017
@Ericson2314
Copy link
Member

😢

@jwiegley
Copy link
Contributor

FWIW, the feature @copumpkin described would be amazing for my workflow. I build over 2,000 packages in my main environment, and it's very hard to keep all of these working when other Nixers don't do their primary testing on Darwin. Sure, Hydra catches it and eventually they get fixed, but much of the time, something in that set of 2,000 breaks, forcing me to delay updating until Hydra catches up. Thus, my complaints in ##nix-darwin.

If I could "freeze" the broken packages during an upgrade attempt, and then unfreeze them a few days later, it would be a much, much better solution than what I do now: which is to hack nixpkgs to undo whatever change broke those packages -- if I even can. Plus, if I have something important coming up, like a demo at work, I could freeze the relevant packages without having to freeze the entire system.

I would rank such a feature very high on my wishlist; but the tarball importing @edolstra suggests is not something I'd use. It sounds much too brittle and manual, compared to what @copumpkin has proposed.

@shlevy
Copy link
Member

shlevy commented Jan 26, 2017

@copumpkin What about having let nixpkgsAsOf = import (builtins.fetchurl "https://nixos.org/nixpkgs-as-of.nix"); in at the top of every file?

@edolstra
Copy link
Member

@jwiegley Eh, what's brittle or manual about it? It specifies exactly the same thing, except that it doesn't require evaluating a different version of Nixpkgs first.

@jwiegley
Copy link
Contributor

I may have misunderstood the usage of asOf. Here's what my ideal would be:

(asOf "fd7b74db" dovecot)

@copumpkin
Copy link
Member Author

@shlevy my goal is basically to be as close to 100% reproducible/auditable as I can be. the "https://nixos.org/nixpkgs-as-of.nix" thing would work except that it introduces an unhashed and unversioned middleman in all this. I could hash-check that but then I need to hash check the fetcher, and the actual version of nixpkgs I wanted, and then that ends up being more effort than the thing I was abstracting over.

@copumpkin
Copy link
Member Author

Anyway, it's not a big deal. I thought this would be a nice and useful thing for more people, since I don't think we have a good solution for mix-and-match workloads today. Yes, in principle someone can use fetchTarball, but nobody knows about it, and having an endorsed function for this feels like it's first-class support whereas just telling people to fetchTarball a URL that GitHub doesn't make very obvious doesn't feel like that. I acknowledge that the whole thing is a pretty thin abstraction. In retrospect I probably should've just pushed and nobody would've noticed 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants