NixOS / nixos-search

Search NixOS packages and options
https://search.nixos.org
MIT License
422 stars 109 forks source link

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

Open zmitchell opened 1 year ago

zmitchell commented 1 year ago

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 commented 1 year ago

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.

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 commented 1 year ago

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 commented 1 year ago
lazamar commented 1 year ago

@SuperSandro2000 For a lengthy discussion spanning more than 8 years about whether this is a good idea or not please see https://github.com/NixOS/nixpkgs/issues/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 commented 1 year ago

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 commented 1 year ago

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:

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 commented 1 year ago

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 commented 1 year ago

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

zmitchell commented 1 year ago

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:

Pinning nixpkgs:

zmitchell commented 1 year ago

@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 commented 1 year ago

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

nixos-discourse commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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