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

meta: Don't bypass unsupported platforms with allowBroken. #38639

Merged
merged 3 commits into from Apr 17, 2018

Conversation

shlevy
Copy link
Member

@shlevy shlevy commented Apr 9, 2018

Our platforms are open-world oriented these days, and anyway there's allowUnsupportedSystem.

@shlevy shlevy requested review from LnL7 and Ericson2314 April 9, 2018 10:25
@shlevy shlevy mentioned this pull request Apr 9, 2018
8 tasks
@shlevy
Copy link
Member Author

shlevy commented Apr 9, 2018

Note that there may be a transition period of making various platform attributes more flexible in the wake of this change.

@7c6f434c
Copy link
Member

7c6f434c commented Apr 9, 2018

Maybe add $NIXPKGS_ALLOW_UNSUPPORTED_PLATFORMS?

@shlevy
Copy link
Member Author

shlevy commented Apr 9, 2018

That seems orthogonal, we already have the switch anyway.

@dezgeg
Copy link
Contributor

dezgeg commented Apr 9, 2018

What is the switch to do it on ad-hoc way from command line?

@7c6f434c
Copy link
Member

7c6f434c commented Apr 9, 2018

@shlevy not completely orthogonal: before the change, there is an environment variable that allows to experiment with platform support without changing any persistent configuration.

@shlevy
Copy link
Member Author

shlevy commented Apr 9, 2018

@dezgeg --arg config '{ allowUnsupportedPlatforms = true; }'

@7c6f434c Sure. I think the mac users are the most affected by this issue, I'll let them decide if they want it.

@dezgeg
Copy link
Contributor

dezgeg commented Apr 9, 2018

But --arg config {} overrides any other .nixpkgs/config.nix options, no?

@shlevy
Copy link
Member Author

shlevy commented Apr 9, 2018

Sure. You could import it from your command line... Why do we need an easy switch here exactly? allowUnsupportedPlatforms is not even something I think we should have, I'm just not removing it because it's unnecessary for what I want to do.

@7c6f434c
Copy link
Member

7c6f434c commented Apr 9, 2018

@shlevy I think your «should» is about the state where there is an actual tristate (but then we will need a variety of cheap overrides for allowUnknownPlatforms…)

@dezgeg
Copy link
Contributor

dezgeg commented Apr 9, 2018

As far as I know the primary use case is for Mac users to test if some package they want to use but depends on packages marked Linux-only happens to work by chance. Sounds pretty useful to me.

Also I personally do stuff like NIXPKGS_ALLOW_BROKEN=1 nix-build -A linux_rpi.src to compute source hashes of RPi-specific stuff on my main machine, but apparently that doesn't need NIXPKGS_ALLOW_BROKEN, I thought it did...

Copy link
Member

@LnL7 LnL7 left a comment

Choose a reason for hiding this comment

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

Maybe I'm missing something, but doesn't enableIfAvailable still have the same problem as before if this is used?

@shlevy
Copy link
Member Author

shlevy commented Apr 9, 2018

@LnL7 If you use allowUnsupportedPlatforms = true, IMO you're explicitly asking for things like the libseccomp Nix issue, no?

@LnL7
Copy link
Member

LnL7 commented Apr 9, 2018

While I kind of agree, the primary use-case for allowBroken on darwin is to bypass meta.platforms = stdenv.lib.platforms.linux for packages that work fine. It's pretty tricky to override platforms without allowing unsupported packages.

@shlevy
Copy link
Member Author

shlevy commented Apr 9, 2018

@LnL7 Right, but I think the right thing to do there is fix the platforms setting. Implicit in the open world nature of it these days is that we can't actually test on all valid platforms, so we shouldn't use it as an "I've tested this" flag any more.

@7c6f434c
Copy link
Member

7c6f434c commented Apr 9, 2018 via email

@Ericson2314
Copy link
Member

Ericson2314 commented Apr 9, 2018

Per what @shlevy said, hydraPlatforms is sort-of a the known-good list. That can be cleaned up later.

@Ericson2314
Copy link
Member

@7c6f434c if we have meta.knownBad and meta.knownGood. "known-broken but probably fixable" would be satisfying meta.knownBad and meta.platforms

@Ericson2314
Copy link
Member

Ericson2314 commented Apr 9, 2018

@7c6f434c Right now, the build platform is ignored entirely. I guess I figured it would be complex to go 2 dimensional, and hey if the cross stuff gets really good the build platform shouldn't ever matter 😂. In practice, the meta.broken thing can be used to add arbitrary boolean expressions.

@LnL7
Copy link
Member

LnL7 commented Apr 9, 2018

Agreed. We could add meta.broken = !stdenv.isLinux to packages like libseccomp for now, then allowing unsupported systems will mostly work as desired.

@Ericson2314
Copy link
Member

@LnL7 err wouldn't that be the other way around? The allowing broken shouldn't add extra libseccomp deps on Darwin, right? The idea would be to make a lot more things meta.platforms = lib.platforms.unix or whatever except for things like libseccomp, then builds that fail get the new meta.knownBad or whatever we want to call it.

@LnL7
Copy link
Member

LnL7 commented Apr 9, 2018

@Ericson2314 allow broken isn't really used to allow broken packages AFAIK 😄

@Ericson2314
Copy link
Member

Ericson2314 commented Apr 9, 2018

@LnL7 Exactly. But with this change it would be. We'd sort of get today's allowBroken by default (minus the new libsecomp problems), and then add more blacklist and shrink the whitelist as needed.

Copy link
Member

@Ericson2314 Ericson2314 left a comment

Choose a reason for hiding this comment

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

@LnL7 and I talked more, and this only seems better and better :)

@shlevy
Copy link
Member Author

shlevy commented Apr 9, 2018

@dezgeg @7c6f434c @LnL7 OK with merging this and iterating from here?

@dezgeg
Copy link
Contributor

dezgeg commented Apr 9, 2018

I think the error message still refers to enabling allowBroken, this needs fixing first:

error: Package ‘uboot-jetson-tk1_defconfig-2018.03’ in /home/tmtynkky/opt/nixpkgs/pkgs/misc/uboot/default.nix:88 is not supported on ‘x86_64-unknown-linux-gnu’, refusing to evaluate.
 
a) For `nixos-rebuild` you can set
  { nixpkgs.config.allowBroken = true; }
in configuration.nix to override this.

b) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
  { allowBroken = true; }
to ~/.config/nixpkgs/config.nix.

(use '--show-trace' to show detailed location information)

@shlevy
Copy link
Member Author

shlevy commented Apr 9, 2018

@dezgeg updated

@periklis
Copy link
Contributor

So which is the current recommendation to work with this configuration:

  • allowBroken to true to get linux-pinned packages built on other platforms, e.g. try to fix those and enable unix
  • allowUnsupportedPlatform to true for stuff like libseccomp

@shlevy Can we have a hint in the documentation please.

@shlevy
Copy link
Member Author

shlevy commented Apr 10, 2018

Yeah, I'll update the docs before merging this, just want to make sure the outstanding objections have been addressed.

@Ericson2314
Copy link
Member

@dezgeg's other concern in IRC over accidental optional/missing deps was resolved in that this one is even better about that than before. I hope that means we're in the clear but @dezgeg can confirm.

@dezgeg
Copy link
Contributor

dezgeg commented Apr 10, 2018

Hmm, does this enableIfAvailable work such that the result changes if the user sets allowUnsupportedPlatform?

@shlevy
Copy link
Member Author

shlevy commented Apr 10, 2018

@dezgeg Yes. IMO that's the only reasonable behavior, if you ask for unsupported platforms you should get them.

@dezgeg
Copy link
Contributor

dezgeg commented Apr 10, 2018

Now I'm utterly confused. I thought the point of the(se) change(s) to have separate options for allowing build of packages marked with meta.broken = true; and allowing build of packages with meta.platforms not containing the current system. That itself makes sense to me.

However, now (not necessarily due to this commit but whatever introduced this enableIfAvailable thing) if you set config.allowUnsupportedPlatform due to this use case @periklis mentioned ("to get linux-pinned packages built on other platforms, e.g. try to fix those and enable unix"), you also get as a a side effect some packages that used to build fine start breaking because now enableIfAvailable affects this package that used to work fine. And there's no way of opting out of that side-effect.

Did I understood this correctly? If so this sounds like a massive unsuspecting footgun.

@Ericson2314
Copy link
Member

Ericson2314 commented Apr 10, 2018

@dezgeg

@periklis's full quote is

  • allowBroken to true to get linux-pinned packages built on other platforms, e.g. try to fix those and enable unix

The idea is that if there's a package that should work on more than linux, first change it from meta.platforms = linux to meta.platforms = unix and allowBroken = !stdenv.hostPlatform.isLinux, and then use config.allowBroken = true;. config.allowUnsupportedPlatform shouldn't really be need to be used, and will indeed mess things up things like enabled optional libseccomp dependencies.

@dezgeg
Copy link
Contributor

dezgeg commented Apr 10, 2018

Uhh... but previously, if you were on Darwin and encountered some package that claims to be unsupported on Darwin, and if you had a theory that this was only due to the package (or its dependencies) having too strict platforms bounds (i.e. in practice, meta.platforms = linux;), you could test this theory with absolutely no code changes at all, just by doing NIXPKGS_ALLOW_BROKEN=1 nix-build '<nixpkgs>' -A foo, (i.e. adding a single environment variable or the equivalent --arg config incantation) and seeing how far you get. This exact workflow has been suggested on IRC several times.

After these changes, that workflow is no longer possible without those side-effects that I mentioned. Now you need to clone nixpkgs, start making those s/platforms.linux/platforms.unix/ edits before you even know if the end result is going to work or not. If it didn't all the effort of manually editing those files went to waste. To me this is a step backwards.

@Ericson2314
Copy link
Member

@dezgeg Yes that's true. That wasn't free though, the cost was tons of manual boilerplate for optional deps. The thing that makes this less bad is the meta.platforms = unix and allowBroken = !stdenv.hostPlatform.isLinux change can be done ahead of anyone trying to debug the specific package. We do enough of that one-time speculative work, and the workflow is NIXPKGS_ALLOW_BROKEN=1 nix-build '<nixpkgs>' -A foo just like before.

@FRidh FRidh added the 6.topic: stdenv Standard environment label Apr 10, 2018
@dezgeg
Copy link
Contributor

dezgeg commented Apr 10, 2018

That wasn't free though, the cost was tons of manual boilerplate for optional deps.

How is changing say,

buildInputs = [ ... numactl ];

to:

buildInputs [ ... ] ++ lib.enableIfAvailable numactl;

"tons of less boilerplate" than:

buildInputs [ ... ] ++ lib.optional (stdenv.isLinux && !stdenv.isArm) numactl;

?

In both cases you had to modify the expression anyway, since there is no a priori way of knowing whether this specific package allows numactl to be optional or not (or whether it only allows it to be optional with some additional --without-numactl etc. flag). Sure, you save the one-time effort of writing the (stdenv.isLinux && !stdenv.isArm) part but now the tradeoff is everyone else who is reading the code won't know whether numactl will be included or not without looking at its expression and breaking this use-case in discussion.

The thing that makes this less bad is the meta.platforms = unix and allowBroken = !stdenv.hostPlatform.isLinux change can be done ahead of anyone trying to debug the specific package.

I don't understand. Who is supposed to be the one doing that change? The person who wanted to test their theory of the package's dependency closure having too strict platforms.linux? I somehow doubt most people want to be doing pull requests where the effective change is changing one error message to another.

@shlevy
Copy link
Member Author

shlevy commented Apr 10, 2018

I have to admit some serious fatigue with this issue. I think this change moves us in the right direction to reasonable semantics for the meta fields and lets us separate the question of what platforms make sense for a package (which belongs with that package) and which packages needn't depend on that package (which belongs downstream). But mostly I just want to be done with this back and forth. So if someone wants to take this on, great, if someone wants to revert enableIfAvailable, fine, just let me know what you decide at the end of the day.

@Ericson2314
Copy link
Member

Ericson2314 commented Apr 10, 2018

@dezgeg

buildInputs = [ ... numactl ];

OK we all agree this with the null trick is bad, right? Because the null trick means there is no acknowledgement of the optionalness of the dep which is awful.

Your two things are both valid. Maybe that will help:

buildInputs [ ... ] ++ lib.enableIfAvailable numactl;

This is for "purely optional bonus deps". You use this if you really don't care whether numactl is available, and just want to use it if possible. This is why it also respects the other parts of meta like allowUnfree.

If B enableIfAvailable depends on C, and A depends on B-with-C, it's A's responsibility to make sure B uses C, not B's. [One would probably do a withC ? c.meta.available or false argument to B.]

buildInputs [ ... ] ++ lib.optional (stdenv.isLinux && !stdenv.isArm) numactl;

This is for a deps that are mandatory under certain conditions. You use this if you sometimes need the dependency, not merely could use it.

So yeah, I again think this PR should be fine given your concerns, along with the "should work" vs "known good/bad" multi-state. Whether optional deps are far more often of the form 2 than 1 is a separate matter.


I don't understand. Who is supposed to be the one doing that change?

Think of it as a TODO tracking mechanism. Maintainers for a platform (as oppose to the package) might think some packages ought to work on their platform, so they can do this change.

@Ericson2314
Copy link
Member

Where would the documentation need to be changed @periklis?

@periklis
Copy link
Contributor

@Ericson2314 I think we need an extra section for allowUnsupportedPlatform in chapter 6

@Ericson2314
Copy link
Member

@dezgeg indicated that this PR itself is fine, or at least more fine than continued use of lib.enableIfAvailable. So let's write the docs (maybe I'll get to that), merge this, and continue deciding the fate of lib.enableIfAvailable somewhere else. I think this is is a good change on its own, whether or not lib.enableIfAvailable stays.

@shlevy
Copy link
Member Author

shlevy commented Apr 17, 2018

@Ericson2314 Thanks for picking this up!

shlevy and others added 2 commits April 17, 2018 16:02
Our platforms are open-world oriented these days, and anyway there's allowUnsupportedSystem.
@Ericson2314 Ericson2314 changed the title Don't bypass unsupported platforms with allowBroken. meta: Don't bypass unsupported platforms with allowBroken. Apr 17, 2018
@Ericson2314
Copy link
Member

OK documentation is added, clarifying division of labor between meta.platforms and meta.broken, and specifically not mentioning lib.enableIfAvailable in order to not blow by @dezgeg's lingering doubts. Merging momentarily.

@Ericson2314 Ericson2314 merged commit 9edda8a into NixOS:master Apr 17, 2018
shlevy referenced this pull request May 9, 2018
The isKexecable flag treated Linux without kexec as just a normal
variant, when it really should be treated as a special case incurring
complexity debt to support.
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

8 participants