Skip to content

{nix,lix}: add withNixDebug overrideable#331794

Closed
philiptaron wants to merge 3 commits intoNixOS:masterfrom
philiptaron:issue-328229/build-nix-with-NIX_DEBUG
Closed

{nix,lix}: add withNixDebug overrideable#331794
philiptaron wants to merge 3 commits intoNixOS:masterfrom
philiptaron:issue-328229/build-nix-with-NIX_DEBUG

Conversation

@philiptaron
Copy link
Contributor

@philiptaron philiptaron commented Aug 2, 2024

Motivation for change

The Nixpkgs stdenv documents an environment variable called NIX_DEBUG but provides no mechanism to set it. After a thorough search through Nix and Nixpkgs history, it must be set inside Nix when the derivation build environment is concocted.

What's the value of this environment variable? It allows the nixpkgs stdenv to produce more verbose logging output, allowing curious users such as myself deeper insight into how the stdenv works and what the impact of my changes might be.

Why does Nix itself have to be recompiled? Any other solution changes the input hash of the derivation, and changing the stdenv's hash means recompiling a lot.

The upstream Nix and Lix projects provide no such functionality to edit the environment variables while building. Nor really should they. This is a fast path to unsoundness in the general case. (We'll leave FODs and impureEnvVars alone.)

What would better look like?

Both projects support structured output logging (through the @nix { "action": "msg", "level": "[0-7]", "msg": "some message" } special messages output to the file descriptor that $NIX_LOG_FD points to.

I haven't deeply explored how these log messages show up in the nix-build, nix build, and family of Nix tools, nor how they get persisted to disk or propagated over the network for remote builders.

My intuition, and those of everyone I've spoken to on Matrix about this, is that better looks like using this structured logging functionality to always output diagnostic logging from the nixpkgs stdenv, then using the log level filtering behavior to control how and where it's displayed.

Description of changes

This is a complete hack: a set of patches to each Nix and Lix that allows a variant version that sets the NIX_DEBUG environment value to the user's choice.

I (@philiptaron) do not honestly believe this PR will or even ought to be merged. It exists in part to have something that people can search for if they also wonder how the heck to set NIX_DEBUG to get this diagnostic logging.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.11 Release Notes (or backporting 23.11 and 24.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

The patch was produced by running the following script in the nixpkgs root:

```nix
let
  pkgs = import ./. { };
  inherit (pkgs) stdenv lib git lixVersions;
  derivationsOnly =
    name: value:
    let
      result = builtins.tryEval value;
    in
    result.success && lib.isDerivation result.value;
  derivations = lib.unique (lib.attrValues (lib.filterAttrs derivationsOnly lixVersions));
in
map (
  package:
  stdenv.mkDerivation {
    name = "set-NIX_DEBUG-on-${package.name}.patch";
    inherit (package) src;
    nativeBuildInputs = [ git ];
    buildPhase = ''
      export HOME=$(mktemp -d)
      git init .
      git add -A .
      git config --global user.email "nixpkgs"
      git config --global user.name "nixpkgs"
      git commit -m "initial"

      grep -r -l -Z -e 'env."NIX_LOG_FD".*"2"' src | \
        xargs -0 sed -i '/NIX_LOG_FD.*2/a \    env["NIX_DEBUG"] = "@NIX_DEBUG@";'
    '';

    installPhase = ''
      git diff | sed '/index/d' > $out
    '';
  }
) derivations
```
The patch was produced by running the following script in the nixpkgs root:

```nix
let
  pkgs = import ./. { };
  inherit (pkgs) stdenv lib git nixVersions;
  derivationsOnly =
    name: value:
    let
      result = builtins.tryEval value;
    in
    result.success && lib.isDerivation result.value;
  derivations = lib.unique (lib.attrValues (lib.filterAttrs derivationsOnly nixVersions));
in
map (
  package:
  stdenv.mkDerivation {
    name = "set-NIX_DEBUG-on-${package.name}.patch";
    inherit (package) src;
    nativeBuildInputs = [ git ];
    buildPhase = ''
      export HOME=$(mktemp -d)
      git init .
      git add -A .
      git config --global user.email "nixpkgs"
      git config --global user.name "nixpkgs"
      git commit -m "initial"

      grep -r -l -Z -e 'env."NIX_LOG_FD".*"2"' src | \
        xargs -0 sed -i '/NIX_LOG_FD.*2/a \    env["NIX_DEBUG"] = "@NIX_DEBUG@";'
    '';

    installPhase = ''
      git diff | sed '/index/d' > $out
    '';
  }
) derivations
```
@github-actions github-actions bot added the 8.has: documentation This PR adds or changes documentation label Aug 2, 2024
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-linux: 1 This PR causes 1 package to rebuild on Linux. labels Aug 2, 2024
@wegank wegank added the 2.status: merge conflict This PR has merge conflicts with the target branch label Sep 10, 2024
@Atemu
Copy link
Member

Atemu commented Nov 29, 2024

What happened to this? Did you upstream this instead?

@philiptaron
Copy link
Contributor Author

Nothing happened. I just don't like holding onto PRs that won't be merged. Eventually, we'll have to try out structured logging and performing the filtering in Nix itself. When next I need to do stdenv development, I'll do a similar process to this PR to rebuild Nix or Lix with the NIX_DEBUG environment variable set.

@Atemu
Copy link
Member

Atemu commented Nov 29, 2024

Fair enough, thanks :)

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/community-team-updates/56458/11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2.status: merge conflict This PR has merge conflicts with the target branch 8.has: documentation This PR adds or changes documentation 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-linux: 1 This PR causes 1 package to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants