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

Add top-level/overrides.nix for package overrides #39515

Closed
wants to merge 108 commits into from

Conversation

matthewbauer
Copy link
Member

@matthewbauer matthewbauer commented Apr 26, 2018

This is some work cleaning up all-packages.nix. The big and maybe controversial change is adding pkgs/top-level/overrides.nix. This file works similarly to pkgs/top-level/aliases.nix does. The main difference is that it holds "overrides" that used to be in Nixpkgs. These were put in as convenience for users like aliases. Hopefully will make it easier for someone to implement #12877.

We get rid of >800 lines in all-packages so hopefully this is well received. I'll wait a little bit for feedback but remember that these kind of changes will get outdated fairly quickly (I can always rebase though). This shouldn't change any hashes hopefully.

/cc @oxij

xurei and others added 30 commits February 20, 2018 17:56
Semi-automatic update. These checks were performed:

- built on NixOS
- found 0.7.5 with grep in /nix/store/7y3a77lh1w5ghqlmy5l00bsx90dpwyy4-thin-provisioning-tools-0.7.5
- found 0.7.5 in filename of file in /nix/store/7y3a77lh1w5ghqlmy5l00bsx90dpwyy4-thin-provisioning-tools-0.7.5

cc "@globin"
Semi-automatic update generated by https://github.com/ryantm/nixpkgs-update tools.

This update was made based on information from https://repology.org/metapackage/xpra/versions.

These checks were done:

- built on NixOS
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/xpra -h’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/xpra --help’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/udev_product_version -h’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/udev_product_version --help’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/udev_product_version help’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/.xpra_launcher-wrapped -h’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/.xpra_launcher-wrapped --help’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/xpra_launcher -h’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/xpra_launcher --help’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/..xpra-wrapped-wrapped -h’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/..xpra-wrapped-wrapped --help’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/.xpra-wrapped -h’ got 0 exit code
- ran ‘/nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6/bin/.xpra-wrapped --help’ got 0 exit code
- found 2.2.6 with grep in /nix/store/yh7iwzli0pcqnhm2vdcc2ha5ifig1ix0-xpra-2.2.6
- directory tree listing: https://gist.github.com/01ffc3c415200e59fd7469357044a87a
Officially both python2 and 3 are supported.
Additionally, some settings based on NixOS configuation is set via defaultConfig
which is then merged with the user provided configration.

For now that just means http port and time zone but others can easily be added.
HA doesn't mind the configuration being JSON instead of YAML but since YAML is
the official language, use that as it allows users to easily exchange config
data with other parties in the community.
as there are none
@matthewbauer
Copy link
Member Author

matthewbauer commented Apr 27, 2018

Yes, so once it's established that the default attribute (say, imagemagick) should refer to a version with "reasonable" amount of support, and let's say now your personal project needs a minimal imagemagick with only PNG support for your Docker container or whatever...

So I think this is a good example of premature optimization. Unless your project will break with a larger version of imagemagick, it should just refer to imagemagick.override { enablePNG = true; }. The problem is going to come up when there's another package in your Docker container that needs to have a bigger imagemagick. Nix doesn't know that your package could have used the larger version of imagemagick so you'll wind up with BOTH imagemagick-light and imagemagick-full. I suppose we could add some concept of "replaceable" overrides in Nix but I don't think anything like that has been proposed.

If you want your docker container to avoid the "big" version of imagemagick because of space constraints, etc., you should do that in an override. This will only work correctly if you're sure that nothing in your closure needs the larger version of imagemagick (otherwise you'll get double like the above). I'm also in favor of having a flag to "imagemagick" that is something like "light" if the code duplication mentioned is too much. My main objection is putting "light" in the attribute name.

So I definitely think this PR is the right way to go - but I understand that people feel uncomfortable with it. Importantly, though, this won't break overrides right now but just try to contain some of the ugliness in one place.

A key insight to all of this is each top-level attribute in all-packages.nix should have a unique "src" attribute. This policy IMO would remove lots of the ugliness in all-packages.nix. The on exception I see is in bootstrapping where things like fetchurlBoot and utillinuxMinimal are probably unavoidable (though perhaps can be hidden). I'd like to make this an policy official.

@@ -126,7 +127,8 @@ let
trivialBuilders
splice
allPackages
aliases
(if (config.quickEval or false) then (self: super: {}) else defaultOverrides)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nbp Does this flag make sense to you? My main goal is to get rid of overrides and aliases in Nixpkgs. Making their overlays optional seems like a straightforward way to do that (of course it will break eval currently, but give us a way to find where their used).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are interested in drawing the graph of dependencies between various attributes, in order to remove the unused one?

I think this might make sense for the "soon to be removed", in which case this could give a grace period for people to move these to their own overlays. Maybe config.enableObsoleteOverrides would be more explicit.

Otherwise to detect which one can be moved to this list, I suggest to make an overlay which does something like:

self: super:

super.lib.mapAttrs (n: v: __trace n) super

Then evaluate the whole list of packages you are interested in, and pipe the error output into sort -Ru which should give you the list of top-level packages / overrrides which are used directly or indirectly.

@dezgeg
Copy link
Contributor

dezgeg commented Apr 28, 2018

So I think this is a good example of premature optimization. Unless your project will break with a larger version of imagemagick, it should just refer to imagemagick.override { enablePNG = true; }

If I were to not care about the closure size, why would I be thinking about using overrides at all? First I would just write imagemagick (just like it's done in ~200 places in Nixpkgs already) and see if it includes the necessary stuff I need or not. If it does work and the closure size of that is already not too bad for my purposes I won't be concerning my mind of whether imagemagick even supports disabling various formats in the first place.

The problem is going to come up when there's another package in your Docker container that needs to have a bigger imagemagick. Nix doesn't know that your package could have used the larger version of imagemagick so you'll wind up with BOTH imagemagick-light and imagemagick-full.

But that problem becomes even more likely to happen when overrides are used instead of using things like imagemagickBig. E.g. if Nixpkgs has a package foo which needs say, imagemagick with ghostscript support and bar which needs imagemagick with ffmpeg support, and I have a personal project baz which needs both foo and bar, I would be better off if foo and bar both just depended on imagemagickBig instead each of them depending on imagemagick.override { ghostscriptSupport = true; } and imagemagick.override { ffmpegSupport = true; }.

My main objection is putting "light" in the attribute name. [..] A key insight to all of this is each top-level attribute in all-packages.nix should have a unique "src" attribute.

Why so? Even without this -light business and the ones you mentioned there are several other counterexamples. What about linux_hardened (not the copperhead variant)? What about ubootBeagleboneBlack and ubootRaspberryPi and other U-Boot builds made from the same upstream source? What about libopcodes and libbfd (IIRC)?

Also as mentioned, in the current state of Nixpkgs, the existence of things like imagemagickBig are discoverable with either nix-env or the Packages page on the website, while all those enableFoo flags are not except by reading the source. With things like emacs25-nox the user has a guarantee that they can get the package from the binary cache and don't need to compile the package from source, with .override there is no such guarantee. Until these issues are solved first, deprecating this -light business is a reduction in functionality and should not be done, IMO.

@matthewbauer
Copy link
Member Author

matthewbauer commented Apr 29, 2018

But that problem becomes even more likely to happen when overrides are used instead of using things like imagemagickBig. E.g. if Nixpkgs has a package foo which needs say, imagemagick with ghostscript support and bar which needs imagemagick with ffmpeg support, and I have a personal project baz which needs both foo and bar, I would be better off if foo and bar both just depended on imagemagickBig instead each of them depending on imagemagick.override { ghostscriptSupport = true; } and imagemagick.override { ffmpegSupport = true; }.

It's more likely at least when the default imagemagick doesn't have ffmpegSupport or ghostscriptSupport. But with package overrides we can change the default to optimize our closure:

{
  packageOverrides = pkgs: rec {
    imagemagick = pkgs.defaultOverrides.imagemagickBig;
  };
}

Our new imagemagick will be identical to imagemagick.override { ghostscriptSupport = true; } and imagemagick.override { ffmpegSupport = true; }. AFAICT this only works correctly when packages are being honest about what they really need from imagemagick and not trying to optimize with underspecified concepts like imagemagickMinimal and imagemagickFull.

Why so? Even without this -light business and the ones you mentioned there are several other counterexamples. What about linux_hardened (not the copperhead variant)? What about ubootBeagleboneBlack and ubootRaspberryPi and other U-Boot builds made from the same upstream source? What about libopcodes and libbfd (IIRC)?

So-

  • Because linux_hardened is derived from "Linux", it should not be used as a dependency directly. IMO putting multiple Linux derivatives in all-packages.nix invites users to depend on it in their packages and should probably be somewhere else.
  • Hopefully some day we can handle the uboot stuff entirely within cross compilation but it probably is not possible right now. Since no package depends on them directly they're probably fine to leave in for legacy purposes (although in principle they should be in their own attribute sets).
  • libopcodes and libbfd might have a legit reason for reusing binutils source. I'm not sure why they are packaged like that. From what I understand though, binutils already builds both of them so it should be possible to put them into a separate output under binutils (in theory at least- bootstrapping can get awfully complicated).

Also as mentioned, in the current state of Nixpkgs, the existence of things like imagemagickBig are discoverable with either nix-env or the Packages page on the website, while all those enableFoo flags are not except by reading the source. With things like emacs25-nox the user has a guarantee that they can get the package from the binary cache and don't need to compile the package from source, with .override there is no such guarantee. Until these issues are solved first, deprecating this -light business is a reduction in functionality and should not be done, IMO.

Yes, discoverability is definitely an issue with flags. I wouldn't necessarily say that the status quo is very discoverable either though (for the longest time, I thought emacs25-nox was somehow related to @madjar's nox). One thing that's important to realize though is that we can use things from the binary cache without referring to them directly. Nix's hashing means that it can't tell the difference between:

foo = callPackage ./foo {
  emacs = emac25-nox;
};

and

foo = callPackage ./foo {
  emacs = emacs25.override { withX = false; };
};

and substitution will occur in both.

Part of what is missing from all of this is a good way for Hydra to put overlays into the binary cache. I am looking into doing something like this in #39580 & I think something like a default "headless" overlay in the binary cache could be really useful. For now, though, this PR keeps our overrides in the binary cache (and we can certainly add more).

@matthewbauer
Copy link
Member Author

matthewbauer commented Apr 29, 2018

Ok closing for now. Definitely does not look like there is a consensus to do this. I still think it is worth doing but it could definitely break things.

I have split off parts of this into #39683 and #39686.

@infinisil infinisil added the significant Novel ideas, large API changes, notable refactorings, issues with RFC potential, etc. label Sep 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet