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

Feature request: Display Nixpkgs revs for prior package versions #636

Open
zmitchell opened this issue Mar 12, 2023 · 15 comments
Open

Feature request: Display Nixpkgs revs for prior package versions #636

zmitchell opened this issue Mar 12, 2023 · 15 comments

Comments

@zmitchell
Copy link

Knowing the Nixpkgs revision to use to pin a version of a package is a useful piece of information to surface in the search results.

There is prior art on this:

The author there is @lazamar. Marcelo, could you lay out what you would be willing to contribute to support this effort?

@lazamar
Copy link

lazamar commented Mar 18, 2023

Cool. I'm willing to help implementing things but I'm not very familiar with how the search is architected nowadays.
Last I remember it used to download a large JSON of package infos and search on that from the client side.
The JSON I believe came directly from Hydra builds. So the search was just an attachment to the recurrent package building process.
Now it is querying a proper ElasticSearch backend. How is that updated?

How nix-package-versions works

It's a very simple premise, I looked-up the command that generated the large JSON that was powering search at the time (it is nix-env -qaP --json with a few options), ran that for different commits on different branches of NixOS/nixpkgs and saved the result in an SQLite database. Searches are just case-insensitive queries on the package name.

Currently I update that database manually by running a script every few weeks. It takes a few minutes.

How could it work?

I imagine people might search for a package as usual and see a button to "see more versions" somewhere in this highlighted area below.
Then the frontend could make an http request and show the results inline in the search page.

image

What would be required

Something very similar to my current setup.

  • A db to store the data. I'm not sure if ElasticSearch can do for this bit.
  • A recurring job to download new versions
  • An endpoint to query the db.

This could take various forms, from implementing this in the backend to nixos-search to directly using the code from nix-package-versions.
I'd need to hear a bit more from you about what a suitable solution would look like.

@SuperSandro2000
Copy link
Member

to use to pin a version of a package

We should not do this because it encourages people to use old version of nixpkgs which may have bugs and security issues of variety severity. Mixing different glibc versions through LD_LIBRARY_PATH is always a bad idea and a very common problem and there are other problems with other systems which are not fully pure. Also it makes reporting bugs harder because more people would pin older commits which obviously cannot receive bug fixes.

A better alternative would be to encourage people to use overlays to downgrade a package. But that is not always as easy as changing the downloaded source code. We are not keeping obsolete code to more sustainable maintain packages. Also old code paths would not be tested and bit rot pretty quickly.

@zmitchell
Copy link
Author

  • Being able to look up a package version is something people often want to do. This can be verified by just searching Discourse or Reddit.
  • Expecting people to be on the latest package versions at all times is unrealistic. We also shouldn't be dictating to people how they build their software. If they want to use old versions they accept the risks of doing so. Not every project is handling sensitive information and needs the latest security updates, etc.
  • This information is already available, we're just surfacing it in a more convenient way.

@lazamar
Copy link

lazamar commented Mar 19, 2023

@SuperSandro2000 For a lengthy discussion spanning more than 8 years about whether this is a good idea or not please see NixOS/nixpkgs#9682.

For what it's worth my take is that this is a feature of Nix and those who know how to use it already do. It's just a question of how easy it is for them to find the one liner that will do what they need.

For a bit of context here, this information is currently available at https://lazamar.co.uk/nix-versions/ and around 300+ people use it every month.
image

@SuperSandro2000
Copy link
Member

Being able to look up a package version is something people often want to do. This can be verified by just searching Discourse or Reddit.

Sure but there is no high quality, universal and low maintenance solution possible. Due to the nature of software we can only choose two. Right now we choose high quality and low maintenance, so we do not have universal multiple packages and also often remove them as soon as they are no longer necessary to reduce maintenance required.

Expecting people to be on the latest package versions at all times is unrealistic.

If we take a look at another distro, lets take Debian because I still know a few things about it, you can reverse an update for a single package quite easily if you still have the deb file cached or download it from the archive. That works quite reasonable for packages that got recent updates but as soon as I you want to use a version of a package 5 years ago that will not work. It will require a different libc version and different versions of dependencies. An option would be to start a container with an older Debian version which is essentially switching to a different nixos channel. The search already displays all currently supported NixOS versions and the general consensus is that mixing them kinda works until it doesn't and then you are on your own. Not every part of NixOS is fully pure, yet, so there are parts which are bound to currently not work.

We also shouldn't be dictating to people how they build their software.

We aren't that much as long as you are staying within the rules that nix is giving you. nixpkgs is build to be extensible and easily modifiable with overlays. It is already today super easy compared to any other distro to modify packages and up or downgrade them.

If they want to use old versions they accept the risks of doing so.

Then the warning must be so big that and red and flashy that we might as well not have an official way and leave that to out to some community project.

Not every project is handling sensitive information and needs the latest security updates, etc.

Sure! An air gaped system that is never connected to the internet and does not handle untrusted input data does not necessarily need the latest security patches but if you are connecting to the internet with openssl you generally want them.

For what it's worth my take is that this is a feature of Nix and those who know how to use it already do.

Yes, those are experienced nix users who hopefully know what they are doing and are using that on their own risk.

It's just a question of how easy it is for them to find the one liner that will do what they need.

That is the problem. It will not just do what they need but can also bring a whole lot of problems which are not fixable. How are we supposed to have an official feature in the search where we cannot fix problems?! and people must accept that some parts are just inherently unfixable broken.


Right now we are removing EOL versions of NixOS as soon as their are unsupported. A step into the direction you are requesting would be to bring all the EOL NixOS releases back.


For a bit of context here, this information is currently available at lazamar.co.uk/nix-versions and around 300+ people use it every month.

I also found a bit confusing wording.

Find all versions of a package that were available in a channel and the revision you can download it from.

From this line I would expect to only list packages that where at some point available on that channel but when I search for firefox it will always show the minimum version as 26 which is available in the git history of nixos-22.11 but was never available on the channel itself.


Let me demonstrate my point that it is not always just working:
I tried to run a somewhat older firefox version I found here https://lazamar.co.uk/nix-versions/?package=firefox&version=75.0&fullName=firefox-75.0&keyName=firefox-wayland&revision=4426104c8c900fbe048c33a0e6f68a006235ac50&channel=nixpkgs-unstable#instructions

and immediately hit a road block:

 ➜ nix run nixpkgs/4426104c8c900fbe048c33a0e6f68a006235ac50#firefox
error: flake 'github:NixOS/nixpkgs/4426104c8c900fbe048c33a0e6f68a006235ac50' has an unsupported attribute 'edition', at /nix/store/03ij5lf9nc0bkn7a2mzkqah9yvy7ny72-source/flake.nix:4:3

okay, that's not fair, flakes are a newer feature and changed in the last 3 years. Lets choose a newer version, maybe 90:

That starts after pointing firefox to a different profile directory but libEGL is unhappy, so some graphics parts like hardware acceleration might now work like they should. There are some things we could do about this but if they are implement they will not be fixed in the past leaving programs a little bit broken forever. Not the quality of packaging I would expect from a distro and an official way to use old packages where we cannot fix anything no matter how severely it is broken because people are using more or less random commits in the past from some EOL branch.

 ➜ nix run nixpkgs/05ae01fcea6c7d270cc15374b0a806b09f548a9a#firefox -- --profile tmp
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: glxtest: libEGL no display (t=0.512776) [GFX1-]: glxtest: libEGL no display
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: glxtest: libEGL no display (t=0.512776) |[1][GFX1-]: glxtest: No visuals found (t=0.5128) [GFX1-]: glxtest: No visuals found
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: glxtest: libEGL no display (t=0.512776) |[1][GFX1-]: glxtest: No visuals found (t=0.5128) |[2][GFX1-]: glxtest: libEGL no display (t=0.512807) [GFX1-]: glxtest: libEGL no display
JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can't find profile directory.
JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can't find profile directory.
JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can't find profile directory.
JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can't find profile directory.
JavaScript error: resource://gre/modules/XULStore.jsm, line 66: Error: Can't find profile directory.
Crash Annotation GraphicsCriticalError: |[0][GFX1-]: glxtest: libEGL no display (t=0.512776) |[1][GFX1-]: glxtest: No visuals found (t=0.5128) |[2][GFX1-]: glxtest: libEGL no display (t=0.512807) |[3][GFX1-]: Unrecognized feature VIDEO_OVERLAY (t=1.59674) [GFX1-]: Unrecognized feature VIDEO_OVERLAY

@lazamar
Copy link

lazamar commented Mar 20, 2023

How are we supposed to have an official feature in the search where we cannot fix problems?!

I definitely see your point here. I agree that putting this feature in the official Nix search tool would make it seem like an encouraged and supported way of using older packages and that's not a good thing given the result may or may not work.

It is still the case though that needing package versions that are no longer part of the latest revision is a common need and it is currently very difficult to find information about how to do it or why not to do it.

Maybe a suitable solution here would be to improve documentation to address this use case directly.
The documentation could explain:

  • How to use supported methods like overlays and flakes to access older supported package versions
  • Why although it is possible to use pinning to satisfy this need this is neither encouraged nor officially supported.
  • Then with a warning that people would be on their own and with no support, point them to how to do it (in a third-party application or otherwise).

when I search for firefox it will always show the minimum version as 26 which is available in the git history of nixos-22.11 but was never available on the channel itself.

The tool is quite dumb and it's just following the commit hierarchy. Given all channels branched from the same tree they all meet somewhere.

it is broken because people are using more or less random commits in the past from some EOL branch.

The tool currently picks commits in set intervals, but it could just as well use the official 6-monthly release commits. I think that would be good enough as well and might increase the chances of packages working.

Let me demonstrate my point that it is not always just working

Yep. It's easy to find cases where it fails, but for many common cases like using a relatively recent older version it works more often than not and this is often enough.

Right now we are removing EOL versions of NixOS as soon as their are unsupported. A step into the direction you are requesting would be to bring all the EOL NixOS releases back.

I'm not super into the workings of Nix to have a very solid opinion here, but it sounds like this would increase even more the burden to keep the latest packages not breaking each other. I'd argue that high quality latest packages are much more important than wide version availability and wouldn't choose the latter at the expense of the former.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/showing-previous-package-versions-in-package-search-results/26572/1

@Ma27
Copy link
Member

Ma27 commented Mar 21, 2023

@fricklerhandwerk what does "Prioritized" mean exactly in terms of implementing this? I think that's still in discussion?

@zmitchell
Copy link
Author

Surely there is a middle ground between "no prior versions listed" and "maintain all previous versions of all packages."

These are some of the solutions for pinning a specific version of a package:

Overlays:

  • You replace one package, everything else stays the same except for the dependencies of the replaced package
  • (+) You replace one package
  • (+) Less time to compile and run
  • (+) Smaller bundle size
  • (-) Replaced package may not compile with the latest build tools (gcc, etc)
  • (-) The package is replaced universally, so reverse dependencies of the replaced package may break

Pinning nixpkgs:

  • You rewind time in the nixpkgs repo to the time when the desired package version was latest and use all packages from that time
  • (+) You can avoid conflicts with latest packages
  • (+) Higher likelihood of the package building since it was in nixpkgs at this point
  • (-) Longer download and build times
  • (-) Explosion when multiple nixpkgs versions are used
  • (-) Driver conflicts can still occur

@zmitchell
Copy link
Author

@fricklerhandwerk what does "Prioritized" mean exactly in terms of implementing this? I think that's still in discussion?

It just means that it was prioritized in our discussion. No implementation at all.

@jtojnar
Copy link
Member

jtojnar commented Mar 21, 2023

Overlays:

* You replace one package, everything else stays the same except for the dependencies of the replaced package

You will most likely want to use both overlays and pinned Nixpgks, though they are more like orthogonal axes.

Use original derivation from old package set, put it into overlay

Overlays can be useful just to have the custom packages available in pkgs attibute of NixOS modules.

let
  oldPkgs = import (builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8.tar.gz";
  }) { };

  overlay = final: prev: {
    hello = oldPkgs.hello;
  };

  pkgs = import <nixpkgs> {
    overlays = [ overlay ];
  };
in
pkgs.hello

Use original derivation from old package set, directly

But they are not really necessary (if you do not need to recompute the fixed point of the attribute set):

let
  oldPkgs = import (builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8.tar.gz";
  }) { };
in
oldPkgs.hello

Build derivation using expression from old package set, put it into overlay

More prone to breakage but if it works, it will use latest dependencies.

let
  oldPkgs = import (builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8.tar.gz";
  }) { };

  overlay = final: prev: {
    hello = prev.callPackages "${oldPkgs}/pkgs/applications/misc/hello" { };
  };

  pkgs = import <nixpkgs> {
    overlays = [ overlay ];
  };
in
pkgs.hello

Build derivation using expression from old package set, directly

Again, overlays are just tool for extending existing package sets, you can do without:

let
  oldPkgs = import (builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/8ad5e8132c5dcf977e308e7bf5517cc6cc0bf7d8.tar.gz";
  }) { };

  pkgs = import <nixpkgs> { };
in
pkgs.callPackages "${oldPkgs}/pkgs/applications/misc/hello" { }

Other options

  • You do not need to use the same name in the overlay. If you use customHello, reverse dependencies will not be affected.
  • Copy the expression from older Nixpkgs into your tree so you can more easily adjust it.
  • Use system.replaceRuntimeDependencies to make rebuilds cheap by just replacing store paths. But it is impure and there is no guarantee it will not subtly break at runtime (e.g. when ABI changes).
  • packageOverrides are basically an overlay before they were a thing.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-03-21-documentation-team-meeting-notes-34/26619/1

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-03-23-documentation-team-meeting-notes-35/26651/1

@zmitchell
Copy link
Author

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2023-03-23-documentation-team-meeting-notes-35/26651/1

In this meeting @pennae mentioned that Arch has/had something called the Arch Rollback Machine: https://wiki.archlinux.org/title/Arch_Linux_Archive#top-page

Perhaps a better solution would be a resource like this. It still seems valuable to maintain a record of the revisions for package versions, be that inspiration/help when trying to package something similar or just throwing caution to the wind to try running it as-is today. I think making it clear that it's an archive and not a list of currently maintained software gets the point across that surfacing this information absolves maintainers of any responsibility for supporting it.

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/how-to-pin-a-single-software-to-a-specific-version-when-using-home-manager/34874/3

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

No branches or pull requests

6 participants