nix
nix copied to clipboard
nix flake check breaks on IFD in multi-platform flake
Describe the bug
Given the following flake
{
description = "A very basic flake";
inputs.flake-utils.url = github:numtide/flake-utils;
outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system:
with nixpkgs.legacyPackages.${system}; {
checks.hello = import (writeText "hi" "hi");
});
}
nix flake check will fail with
error: --- Error --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
a 'aarch64-linux' with features {} is required to build '/nix/store/xqdq3nrw9s3f7vpn1zzsryhsqkh23634-hi.drv', but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test}
(use '--show-trace' to show detailed location information)
because while it does not build checks of foreign platforms, it still tries to evaluate them, which with IFDs can lead to building after all.
Expected behavior
nix flake check should catch uses of IFD and perhaps print a warning but continue to check other parts. Alternatively, there could be a check attribute or cmdline flag that disable evaluation on foreign platforms.
A hacky workaround is just to use nixpkgs.legacyPackages.x86_64-linux for evaluation and nixpkgs.legacyPackages.${system} for the actual derivation. Usually you're just doing some preprocessing so it works out to evaluate on one system and build on another.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/how-to-use-flakes-with-ifd/10300/2
FWIW, we have actually be using this "bug" to detect surprising or unwanted IFD in devos. Maybe, after fixing this we could make some sort of library or builtin function, such as isIFD, in order to continue detecting it in unwanted places :smile:
Or maybe a flag to nix flake check such as --fail-on-ifd that preserves the current behavior.
this problem also applies to nix flake show
Hmmm. It seems like IFD definitely needs to be allowed in e.g. defaultPackages. Does anyone have any ideas about what the right solution here is?
just for reference the iohk cardano-node flake also exhibits the same 'problem/issue/feature'.
nix flake show github:input-output-hk/cardano-node
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/nix-flake-show-fails-when-the-flake-provides-packages-for-other-platforms/18726/2
A hacky workaround is just to use nixpkgs.legacyPackages.x86_64-linux for evaluation and nixpkgs.legacyPackages.${system} for the actual derivation.
How can you know that the machine you're running on is x86_64-linux? Maybe you're on an aarch64-linux and evaluating a derivation for x86_64-linux.
I wish there was a way to say that an IFD is platform independent (probably necessitating a hash of the expected resulting nix expression). That way you could handle other platforms while still evaluating on the local platform. It could probably work somewhat similarly to other fixed output derivations like file downloads.
For haskell.nix users, I think the hacky workaround of wrapping nix in the nix-shell to avoid this error is much worse than the problems that IFD's cause:
https://github.com/purenix-org/purenix/issues/34#issuecomment-981290387
Given the following flake
{ description = "A very basic flake"; inputs.flake-utils.url = github:numtide/flake-utils; outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system: with nixpkgs.legacyPackages.${system}; { checks.hello = import (writeText "hi" "hi"); }); }
This example makes it harder to discuss about a solution, because import (writeText "hi" "hi") is not a valid nix derivation and therefore will never lead to a successful build. In order to allow us to evaluate different fixes for the issue, it would be best if a minimal example was provided that does build once the problem is fixed.
this problem also applies to nix flake show
This is not entirely true. nix flake show only evaluates a few attributes of the derivation (name, type) in order to list it. Therefore the issue can be fixed by constructing a derivation which does not draw name and type from an IFD operation.
Example implementation of a wrapper to make arbitrary derivations nix flake show friendly:
makeFlakeFriendly.nix
{
drv,
name,
}:
{
inherit name;
type = "derivation";
# due to laziness the `drv` will not be evaluated while listing the outputs
outPath = drv;
drvPath = drv.drvPath;
}
And here a working example that uses makeFlakeFriendly.nix.
nix flake show works fine on this one:
{
description = "A very basic flake";
inputs.flake-utils.url = github:numtide/flake-utils;
outputs = { self, nixpkgs, flake-utils }: flake-utils.lib.eachDefaultSystem (system:
with nixpkgs.legacyPackages.${system}; {
checks.hello =
let
drvFile = writeText "hi.nix" ''
derivation {
name = "hi";
system = "${system}";
builder = "/bin/sh";
args = ["-c" "echo hi > $out"];
}
'';
hi = import drvFile;
makeFlakeFriendly = import ./makeFlakeFriendly.nix;
in
makeFlakeFriendly {drv = hi; name = "hi";};
});
}
For checks actually a similar solution as implemented in #6988 could be of any use?
A hacky workaround is just to use nixpkgs.legacyPackages.x86_64-linux for evaluation and nixpkgs.legacyPackages.${system} for the actual derivation. Usually you're just doing some preprocessing so it works out to evaluate on one system and build on another.
Could you elaborate on this to a nix newb?
Could you elaborate on this to a nix newb?
Probably better to ask on the discourse, it will auto-link here for reference. Questions on GitHub distract from the technical discussion at hand, especially if you have follow-up questions.
Please give this a preliminary review: https://github.com/NixOS/nix/pull/7759
This changes the default behavior of nix flake check.
It copies https://github.com/NixOS/nix/pull/6988, as suggested https://github.com/NixOS/nix/issues/4265#issuecomment-1253970905
Will this change be an inconvenience on Nix systems with remote builders? These systems may be relying on the current behavior of nix flake check. Does the same apply to nix flake show?
Thanks
Can we discuss this: check all systems by default, or check only current system by default https://github.com/NixOS/nix/pull/7759#issuecomment-1420183744
Does anyone know when the Nix 2.14 release will be tagged? I assume the change for nix flake show will be included: https://github.com/NixOS/nix/pull/6988 IMO it would be great if the change for nix flake check were also included: https://github.com/NixOS/nix/pull/7759
https://github.com/NixOS/nix/pull/6988 and https://github.com/NixOS/nix/pull/7759 have been merged
I am using Nix 2.16, which includes those changes.
However, nix flake show continues to fail with cardano-node: https://github.com/NixOS/nix/issues/4265#issuecomment-959124625
$ nix flake show github:input-output-hk/cardano-node
...
error: a 'aarch64-darwin' with features {} is required to build
'/nix/store/yvzpxhwhsw40mymnfxvdhrbrfp0swqnv-cabal.project.drv',
but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test, uid-range}
nix flake check continues to fail with plutus:
$ nix flake check github:input-output-hk/plutus
...
error: a 'x86_64-darwin' with features {} is required to build
'/nix/store/702sbav1zzlzckkrrb42v38axrlizmn0-cabal.project.drv',
but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test, uid-range}
So I think there is additional work to be done beyond https://github.com/NixOS/nix/pull/6988 and https://github.com/NixOS/nix/pull/7759
Where in the codebase would this be fixed? src/nix/flake.cc?
https://github.com/NixOS/nix/blob/a15b2c01c0bac226ed34d8ba7e10a563c4a54890/src/nix/flake.cc
It seems like using nixConfig might work around this issue:
nixConfig = {
allow-import-from-derivation = "true"; # TODO doesn't work?
};
https://github.com/NixOS/nix/pull/4189
I see this done for example here:
https://github.com/hasktorch/hasktorch/blob/7b63d730964a44a6bcdd853cd5b140a24e210298/flake.nix#L16
but my nix flake show still fails with
error: cannot build '/nix/store/h91k9g6ppgwncazpli9rz82y1xl0w9zj-source.drv' during evaluation because the option 'allow-import-from-derivation' is disabled
Thanks
I see the same error with Nix 2.16
$ nix flake check github:hasktorch/hasktorch
...
error: a 'x86_64-darwin' with features {} is required to build
'/nix/store/h3prp5ng7ghxcv9xcyf0bdkrjnvclilr-alex-3.2.4-r1-src.drv',
but I am a 'x86_64-linux' with features
I see that repo uses haskell.nix. I have raised the same issue there: https://github.com/input-output-hk/haskell.nix/issues/1825
Perhaps there are two overlapping issues here both causing nix flake check to fail; something with IFD in nix itself, and something specifically in haskell.nix.
@DavHau , thanks for providing this example https://github.com/NixOS/nix/issues/4265#issuecomment-1253831566
With Nix 2.16, the result is:
$ nix flake check
warning: The check omitted these incompatible systems: aarch64-darwin, aarch64-linux, x86_64-darwin
Use '--all-systems' to check all.
and
$ nix flake check --all-systems
error:
… while checking flake output 'checks'
at /nix/store/dbppismymjc6382g4v6d6sb99pjby37b-source/lib.nix:73:15:
....
error: a 'aarch64-darwin' with features {} is required to build
'/nix/store/fqbrhssl2h3064277p8a9yjz8m4qsskc-hi.nix.drv',
but I am a 'x86_64-linux' with features {benchmark, big-parallel, kvm, nixos-test, uid-range}
So this is good news.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
https://discourse.nixos.org/t/help-understanding-templates-haskell-nix/30990/1
I remember this issue since forever. Can we add a simple flag filtering outputs for just one system? As simple partial workaround, like:
$ nix flake show --system=x86_64-linux
├───checks
│ └───x86_64-linux
│ ├───"homeConfiguraton_zmrocze@omen": derivation 'home-manager-generation'
│ └───pre-commit: derivation 'pre-commit-run'
├───devShells
│ └───x86_64-linux
│ ├───default: development environment 'nix-shell'
├───homeConfigurations: unknown
└───nixosConfigurations
├───omen: NixOS configuration
This is still helpful for local development, i.e. when I'm including all outputs from some dynamically defined flake and I don't know the attribute names.
The problem was expected to be resolved in version 2.16, but it persists in version 2.19.1. The issue occurs specifically during nix flake check in haskell.nix. I don't know what steps to take to address this. My current approach involves removing support for all other systems and any form of cross-compilation.
Wasn't the whole point of flakes to make cross-system management viable because Hydra couldn't manage the prior system? Removing it seems like giving up one of the primary motivators that led to inconvenience in almost every other area of functionality.