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

nix flake templates are not evaluated properly #11309

Open
EvysGarden opened this issue Aug 16, 2024 · 5 comments
Open

nix flake templates are not evaluated properly #11309

EvysGarden opened this issue Aug 16, 2024 · 5 comments
Labels
bug flakes new-cli Relating to the "nix" command

Comments

@EvysGarden
Copy link

EvysGarden commented Aug 16, 2024

Describe the bug
derivations in flake templates are not properly evaluated?

Steps To Reproduce
Consider the following code:

{
  outputs = { self, nixpkgs }:
    let
      pkgs = import nixpkgs { system = "x86_64-linux"; };
      templatePackage = pkgs.stdenv.mkDerivation {
        name = "foo-template-package";
        src = ./.;
        installPhase = ''
          mkdir -p $out
          echo yo > $out/foo
        '';
      };
    in
    {
      templates = {
        foo = {
          path = "${templatePackage}";
        };
      };
    };
}

Calling nix flake init -t ".#foo" gives me the following error:

error: opening directory '/nix/store/<some-hash>-foo-template-package': No such file or directory

Expected behavior
The derivation should be actually build so that the path exists.

nix-env --version output
nix-env (Nix) 2.18.5

Priorities

Add 👍 to issues you find important.

@EvysGarden EvysGarden added the bug label Aug 16, 2024
@EvysGarden
Copy link
Author

EvysGarden commented Aug 16, 2024

the template output is not system-specific (unlike for example packages). Also something that doesn't really make sense to me as it should be possible to build templates and building may not be system-agnostic.

Something like outputs.templates.${system}.foo.path = "${pkgs.hello}" should be possible i feel like

@con-f-use
Copy link

con-f-use commented Aug 16, 2024

This is probably a symptom of the larger issue #4945 and a "works as intended", because when flakes were made, people didn't want to implement it and/or didn't want to over-complicate the template feature. I agree with EvysGarden, that it's surprising behavior and at the very least has a weird error message that, if nothing else, should be improved. Additionally template evaluation is a desirable feature for implementation, imho, but might be pretty involved given the implementation of flakes i nix.

@roberth roberth added new-cli Relating to the "nix" command flakes labels Aug 16, 2024
@tomberek
Copy link
Contributor

It would take a build2 call, similar to https://github.com/NixOS/nix/blob/master/src/nix/profile.cc#L371. Notice that rumming "build" on that installable does work. And yes, templates were not intended to require a build but rather be system agnostic.

This getString https://github.com/NixOS/nix/blob/master/src/nix/flake.cc#L890 does not force a build to occur. This means that the interpretation of the template type will not perform a build.

About the topic of changing this; it does seem good to limit the scope of templates to something that cannot build. More complicated initialization can be had with an App, where it is clearer to the user that they might run arbitrary code. The proposal here is somewhat of an intermediate, not run arbitrary code, but only an arbitrary build.

Random idea. Add support for this flow? It makes it clear that this template might need an arbitrary build.

  1. nix build flake#template
  2. nix flake init -t ./result

or use the style from dream2nix

  1. nix flake init flake#template
  2. nix run .#initialize

I'm not sure. I see value in having the more limited computation/attack-surface mechanism. Options:

  1. Add better error message, templates remain a simple no-computation copy.
  2. Support a build, either directly or via a workflow above. May require adding a system to attrPath.
  3. Encourage apps for more complicated (eg. destination based)

@EvysGarden
Copy link
Author

I will use one of the proposed ways for now. In general tho I disagree with the sentiment that templates should be system-agnostic copies. The init part implies that the directory will be initialized for the specific workflow. Having additional steps occur after running nix flake init seems unnecessary to me.

The init step implies code execution. Just like a nix build would. I feel like a security perspective is not an excuse here.

Furthermore are templates by default from known sources and if those are compromised, it's not an issue of flakes.

@shelvacu
Copy link

shelvacu commented Aug 27, 2024

As it is now, if the path refers to a derivation output that just so happens to have been built and is in the nix store, the command works fine. This makes init from a template "impure" since it can fail, then you build something else, then it works, then you nix store gc, then it fails. I think to prevent this we have to ensure the path is within the flake's closure.

edit: for a super simple repro, try: (x86_64 only)

# this fails
nix flake check github:shelvacu/flake-template-weirdness

nix flake build --no-link github:shelvacu/flake-template-weirdness#deriv

# this succeeds
nix flake check github:shelvacu/flake-template-weirdness

trueNAHO added a commit to trueNAHO/asciidoctor.nix that referenced this issue Nov 12, 2024
Hardcode file injections and revert commit c32c9a6 ("flake:
templates: inject additional files") due to Nix's current inability to
evaluate derivations in templates [1].

To reduce maintenance, examples omit hardcoded README.adoc files.

[1]: NixOS/nix#11309
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug flakes new-cli Relating to the "nix" command
Projects
None yet
Development

No branches or pull requests

5 participants