nix icon indicating copy to clipboard operation
nix copied to clipboard

nix flake check breaks on IFD in multi-platform flake

Open Kha opened this issue 5 years ago • 12 comments

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.

Kha avatar Nov 16 '20 11:11 Kha

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.

matthewbauer avatar Nov 23 '20 18:11 matthewbauer

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

nixos-discourse avatar Dec 05 '20 20:12 nixos-discourse

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.

nrdxp avatar Apr 10 '21 19:04 nrdxp

this problem also applies to nix flake show

colonelpanic8 avatar Jul 27 '21 10:07 colonelpanic8

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?

colonelpanic8 avatar Jul 28 '21 06:07 colonelpanic8

just for reference the iohk cardano-node flake also exhibits the same 'problem/issue/feature'.

nix flake show github:input-output-hk/cardano-node

nixinator avatar Nov 03 '21 13:11 nixinator

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

nixos-discourse avatar Apr 20 '22 18:04 nixos-discourse

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.

yajo avatar May 16 '22 09:05 yajo

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.

anka-213 avatar May 18 '22 05:05 anka-213

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

ParetoOptimalDev avatar Sep 20 '22 21:09 ParetoOptimalDev

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";};
    });
}

DavHau avatar Sep 21 '22 14:09 DavHau

For checks actually a similar solution as implemented in #6988 could be of any use?

NobbZ avatar Sep 21 '22 16:09 NobbZ

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?

EncodePanda avatar Oct 18 '22 08:10 EncodePanda

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.

TLATER avatar Oct 19 '22 11:10 TLATER

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

peterbecich avatar Feb 06 '23 00:02 peterbecich

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

peterbecich avatar Feb 07 '23 04:02 peterbecich

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

peterbecich avatar Feb 14 '23 07:02 peterbecich

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

peterbecich avatar May 27 '23 20:05 peterbecich

Where in the codebase would this be fixed? src/nix/flake.cc?

https://github.com/NixOS/nix/blob/a15b2c01c0bac226ed34d8ba7e10a563c4a54890/src/nix/flake.cc

peterbecich avatar Jun 04 '23 07:06 peterbecich

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

jamesdbrock avatar Jun 06 '23 01:06 jamesdbrock

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.

peterbecich avatar Jun 06 '23 02:06 peterbecich

@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.

peterbecich avatar Jul 09 '23 00:07 peterbecich

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

nixos-discourse avatar Jul 27 '23 10:07 nixos-discourse

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.

zmrocze avatar Dec 12 '23 13:12 zmrocze

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.

klarkc avatar Jan 12 '24 00:01 klarkc

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.

Dessix avatar Jan 12 '24 00:01 Dessix