Impure derivations do not work with flakes #389

Closed
opened 2024-06-11 06:14:44 +00:00 by irenes · 2 comments
Owner

Describe the bug

With the impure-derivations feature, derivations with __impure = true; are supposed to be able to do impure things such as accessing the global environment, regardless of whether nix is invoked with --impure or not. However, when the derivation is a package output of a flake, this doesn't work and instead gives a purity error.

Steps To Reproduce

  1. Prepare a system with the impure-derivations experimental feature enabled. You may also need ca-derivations.
  2. Set up flake.nix and package.nix as below. To make it work as a flake you may need to create a git repo and add these two files to it.
  3. Invoke nix build.
  4. See error.

Expected behavior

The derivation would build successfully.

nix --version output

nix (Lix, like Nix) 2.90.0-lixpre20240527-0b91a4b

Additional context

Building with --impure makes it work.

It is very likely that what's happening is that certain builtins are removed and others are given different behavior, as a global property at invocation time.

I'm not honestly certain, with lazy evaluation and all, how this could possibly work even without flakes. My attempt to create a minimal test to see how it works without flakes resulted instead in #388, so maybe impure derivations just don't work at all? Hmm hmm.

Files

flake.nix

{
  inputs = {
    nixpkgs = {
      type = "github";
      owner = "NixOS";
      repo = "nixpkgs";
      ref = "nixos-24.05";
    };
  };

  outputs = { self, nixpkgs }:
  let supportedSystems = [ "aarch64-linux" "x86_64-linux" ];
      forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
      nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
  in {
    packages = forAllSystems (system: let pkgs = nixpkgsFor.${system}; in {
      default = pkgs.callPackage ./package.nix { };
    });
  };
}

package.nix

{ pkgs ? import <nixpkgs> { },
  stdenv ? pkgs.stdenv,
  coreutils ? pkgs.coreutils,
  ... }:

stdenv.mkDerivation {
  name = "foo";

  args = [ "-c" "${coreutils}/bin/date > $out" ];
  foo = builtins.readFile /tmp/z;

  __impure = true;
}
## Describe the bug With the impure-derivations feature, derivations with __impure = true; are supposed to be able to do impure things such as accessing the global environment, regardless of whether nix is invoked with --impure or not. However, when the derivation is a package output of a flake, this doesn't work and instead gives a purity error. ## Steps To Reproduce 1. Prepare a system with the impure-derivations experimental feature enabled. You may also need ca-derivations. 2. Set up flake.nix and package.nix as below. To make it work as a flake you may need to create a git repo and add these two files to it. 3. Invoke `nix build`. 4. See error. ## Expected behavior The derivation would build successfully. ## `nix --version` output nix (Lix, like Nix) 2.90.0-lixpre20240527-0b91a4b ## Additional context Building with `--impure` makes it work. It is very likely that what's happening is that certain builtins are removed and others are given different behavior, as a global property at invocation time. I'm not honestly certain, with lazy evaluation and all, how this could possibly work even without flakes. My attempt to create a minimal test to see how it works without flakes resulted instead in #388, so maybe impure derivations just don't work at all? Hmm hmm. ## Files flake.nix ``` { inputs = { nixpkgs = { type = "github"; owner = "NixOS"; repo = "nixpkgs"; ref = "nixos-24.05"; }; }; outputs = { self, nixpkgs }: let supportedSystems = [ "aarch64-linux" "x86_64-linux" ]; forAllSystems = nixpkgs.lib.genAttrs supportedSystems; nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; }); in { packages = forAllSystems (system: let pkgs = nixpkgsFor.${system}; in { default = pkgs.callPackage ./package.nix { }; }); }; } ``` package.nix ``` { pkgs ? import <nixpkgs> { }, stdenv ? pkgs.stdenv, coreutils ? pkgs.coreutils, ... }: stdenv.mkDerivation { name = "foo"; args = [ "-c" "${coreutils}/bin/date > $out" ]; foo = builtins.readFile /tmp/z; __impure = true; } ```
irenes added the
bug
label 2024-06-11 06:14:44 +00:00
Owner

This is working as intended. builtins.readFile is run client side, and is affected by --impure, and that is the error you are seeing.

Impure derivations are another thing entirely unrelated to --impure: they are derivations that are rebuilt every time and have network access. They're like a less evil version of __noChroot input-addressed derivations, as I understand it.

The intended use case is that you have an impure derivation somewhere in your build process for scuffed garbage, and then you have content-addressed dependents that prevent anything below it being rebuilt, providing early cutoff (see Build Systems à la Carte by Peyton-Jones).

This is working as intended. `builtins.readFile` is run client side, and is affected by `--impure`, and that is the error you are seeing. Impure derivations are another thing entirely unrelated to `--impure`: they are derivations that are rebuilt every time and have network access. They're like a less evil version of `__noChroot` input-addressed derivations, as I understand it. The intended use case is that you have an impure derivation somewhere in your build process for scuffed garbage, and then you have content-addressed dependents that prevent anything below it being rebuilt, providing early cutoff (see Build Systems à la Carte by Peyton-Jones).
jade closed this issue 2024-06-11 06:46:28 +00:00
Author
Owner

oh. huh. interesting... so the two concepts of pure evaluation are different. drat :) but that makes sense.

oh. huh. interesting... so the two concepts of pure evaluation are different. drat :) but that makes sense.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#389
No description provided.