Nix basic questions

Hi there, I’ve got a few basic questions if I may.

Whenever I run nix-store --query … or nix search …, it shows the output in what seems similar to less. Is it possible to make them output to stdout instead?

Also, I’m confused about deleting derivations with --ignore-livess.
I’m following the nix-pills derivation and using nix-repl I create a dummy derivation:

nix-repl> d = derivation { name = “name”; builder = “builder”; system = builtins.currentSystem; }
nix-repl> d
«derivation /nix/store/pzr2q12fdx6rc6bznlnkny64a8akqmkb-name.drv»

Without existing nix-repl I try to delete the derivation on another terminal but I get the following error:

nix-store --delete /nix/store/pzr2q12fdx6rc6bznlnkny64a8akqmkb-name.drv --ignore-liveness
0 store paths deleted, 0.00 MiB freed
error: you are not allowed to ignore liveness

Is this expected? when am I allowed to ignore the liveness?

Thank you!

1 Like

if the output of these commands are used in a script, then they will write to stdout directly. If used interactively, these commands will call less automatically for easy reading. If you want to bypass less interactively, you can add | cat at the end: the commands will detect that their output is used instead of just displayed and will get rid of less.

1 Like

I think the repl session keeps a dependency to the derivations it builds and nix-store --delete refuses to delete derivations that are depended upon:

With the option --ignore-liveness, reachability from the roots is ignored. However, the path still won’t be deleted if there are other paths in the store that refer to it (i.e., depend on it).

Or, if you do not want a pipeline, most unix-y programs respect the PAGER variable. So, something like

$ PAGER= nix search foo

Also does the trick.


what does “reachability from the roots” mean?

Thank you both! Adding the cat works but I might just unset PAGER on my shellInit so I won’t have to do it everytime :smiley:

To avoid disasters, better do not manually delete stuff from the nix store. Only delete stuff via nix-collect-garbage. This is always safe and you don’t risk deleting essential components.

Yeah that sounds reasonable, though there might be times were I might want to remove just one specific thing? Example, I use a nix-shell for development and if I run nix-collect-gargage then the next time I run nix-shell it has to rebuild again.

On another subject, is there a way to enable the build output on nix repl? I’m running the example here but rather than:

these derivations will be built:
building '/nix/store/i76pr1cz0za3i9r6xq518bqqvd2raspw-foo.drv'...
declare -x HOME="/homeless-shelter"
declare -x NIX_BUILD_CORES="4"
declare -x NIX_BUILD_TOP="/tmp/nix-build-foo.drv-0"
declare -x NIX_LOG_FD="2"
declare -x NIX_STORE="/nix/store"
declare -x OLDPWD
declare -x PATH="/path-not-set"
declare -x PWD="/tmp/nix-build-foo.drv-0"
declare -x SHLVL="1"
declare -x TEMP="/tmp/nix-build-foo.drv-0"
declare -x TEMPDIR="/tmp/nix-build-foo.drv-0"
declare -x TMP="/tmp/nix-build-foo.drv-0"
declare -x TMPDIR="/tmp/nix-build-foo.drv-0"
declare -x builder="/nix/store/q1g0rl8zfmz7r371fp5p42p4acmv297d-bash-4.4-p19/bin/bash"
declare -x name="foo"
declare -x out="/nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-foo"
declare -x system="x86_64-linux"
warning: you did not specify '--add-root'; the result might be removed by the garbage collector

this derivation produced the following outputs:
  out -> /nix/store/gczb4qrag22harvv693wwnflqy7lx5pb-foo

I get:

nix-repl> :b d
[1 built, 0.0 MiB DL]

this derivation produced the following outputs:
  out -> /nix/store/x7fgwg4hib7dvpawifqb7k2pm3v06pq4-foo

I suggest you read the nix pills. A root is a derivation that has been marked so it is never garbage collected. Roots are stored in /nix/var/nix/gcroots. X is “Reachable from the roots” means that there is at least one root derivation that depends on X. As a result, if X is reachable from a root, it can’t be deleted.

common solution is to use lorri GitHub - target/lorri: Your project's nix-env

It will handle gcroots automatically for you. And build the derivation in the background.


there’s a separate NIX_PAGER variable you can set to for example cat in your shellInit if you want to not break stuff where it would make sense to use a pager

1 Like

hmm again following the pill here
I build the derivation with nix-build simple.nix but again I cannot delete it with the nix-store --delete:

finding garbage collector roots...
0 store paths deleted, 0.00 MiB freed
error: cannot delete path '/nix/store/b6f10ibzc0dmgqiny5h3lgs8gj01ikmf-foo' since it is still alive
> nix-store --delete /nix/store/b6f10ibzc0dmgqiny5h3lgs8gj01ikmf-foo --ignore-liveness
0 store paths deleted, 0.00 MiB freed
error: you are not allowed to ignore liveness

I guess it makes sense because the result symlink is still pointing to it… and so the only way I found was to manually delete the result symlink in the current directory rm -rf ./result and then nix-store --delete works. Is this the expected way of doing it?

Yes. It would be awkward to have a symlink to a store path which got cleaned up. So by default nix-build and nix build will add the out-link to gcroots.

ls -l /nix/var/nix/gcroots/auto/
lrwxrwxrwx 35 root 21 Aug  6:15 0vpiyrvl976b8j2hlqnqvig6hbp0z4gb -> /home/jon/projects/nixpkgs/result-2
lrwxrwxrwx 28 root 22 Aug  6:05 0ww9casxaqrggrrrhiyvyvncmfpaapja -> /tmp/nix-build-6568-0/result
lrwxrwxrwx 29 root 20 Aug  8:39 0xnlrcwp8x60frmm16z0g7cs7bgai42p -> /tmp/nix-build-11767-0/result
lrwxrwxrwx 29 root 18 Aug  8:35 081bbsp6b9z6wvl34xlpawd0g88dpyc0 -> /tmp/nixos-rebuild.iUMCtr/nix
lrwxrwxrwx 40 root 29 Mar 22:43 091y4anlzmzcd39398aca4yihx2vfpmw -> /home/jon/projects/nixpkgs-update/result
1 Like

Thank you, that command was really helpful, I had some time today to get back to nix and could not get my dummy package to build again and had forgotten where the result was and this helped me out!

Is it possible to add nixos tests to a derivation?
Eg I tried adding it like this:

derivation {
 name = ...
 system = ...
 tests = nixosTest ./tests/test.nix

It seemed to run the test once but now it’s not running and I can’t see anything on “/nix/var/nix/gcroots/auto/”?

you should use stdenv.mkDerivation when possible.

And yes you can add nixosTests. Here’s an example: nixpkgs/default.nix at c5911744de78e8dd104320fde177dfe2b7b49d85 · NixOS/nixpkgs · GitHub

What is the passthru?

I tried adding something like it to my derivation with “ = nixosTest ./test/test.nix” but it fails to build:
error: cannot coerce a set to a string, at /tmp/foo/foo.nix:3:3
(use ‘–show-trace’ to show detailed location information)

with (import <nixpkgs> {});
derivation {
  name = "foo";
  builder = "${bash}/bin/bash";
  args = [ ./ ];
  inherit gcc coreutils;
  src = ./foo.c;
  system = builtins.currentSystem; = nixosTest ./test/test.nix;

passthru is a useful attribute to pass information along during evaluation. However, passthru along with a few other attrs will be filtered out by mkDerivation when passing arguments to derivation, thus avoids the attrs from influencing the build.

       derivationArg =
        (removeAttrs attrs
          ["meta" "passthru" "pos"
           "checkInputs" "installCheckInputs"
           "__impureHostDeps" "__propagatedImpureHostDeps"
           "sandboxProfile" "propagatedSandboxProfile"])

like I said above, you should prefer to use mkDerivation, but it looks like your sample code is from nix-pills which is just trying to go through the motions of making your own stdenv.mkDerivation.

nix-pills is a good resource to know how nix works at a lower level, but higher level concepts like introducing nixos tests into a nix expression should probably be using the latest paradigms.

NOTE: the usage of passthru is still largely conventional. The use of passthru.tests I think is the only convention that has really been adopted broadly. However, I’ve seen passthru.tests refer to a single test, an array of tests, and an attrset of tests, so it’s still not standard what the shape is. However, all 3 of those structures can be evaluated by nix-build

Thanks, I’ve switched to mkDerivation now:

with import <nixpkgs> {};

stdenv.mkDerivation rec {
  name = "moo-${version}";
  version = "0.0.1";

  src = ./.;

  buildInputs = [ bash cowsay ];

  test = nixosTest ./test/test.nix;
  #passthru.tests.moo = nixosTest ./test/test.nix;

  installPhase = ''
    mkdir $out
    cowsay installed

When using test = nixosTest ./test/test.nix; the tests run once when using nix-build but then they stop running when running nix-build again even after removing the result?
I tried passthru.tests.moo = nixosTest ./test/test.nix; and although there is no error, nothing seems to happen.

Looking at the source, this error message occurs with a multi-user install; nix-daemon simply refuses to support the --ignore-liveness flag.

I expect running this with sudo would work as I believe root just modifies the store directly, though don’t quote me on that.

The other convention I’m aware of is passthru.updateScript, which is a path to a script that will be invoked when using nix-shell maintainers/scripts/update.nix in order to update derivations whose updates can be scripted (e.g. such as npm packages).