How to make nixos-rebuild output more informative?

Is there a way or program to make the output of nixos-rebuild more informative? I know that there are wrappers for apt and was wondering, if there is some equivalent for nixos-rebuild.

For example, i find this output not very informative:

these 103 paths will be fetched (423.69 MiB download, 1619.10 MiB unpacked):
  /nix/store/1hhmxhh93qp8aww6j2qqh72lcriv0k05-libffi-3.4.4
  /nix/store/28hk6fsm5mg8xj7ddlvwyydic2g35cxx-libkrb5-1.20.1
  /nix/store/2vsv1ki605a8qvs14ph60y4w7gxbkfp9-openssl-3.0.8
  /nix/store/3adp7aji8fpw9411qlp64fgyxx8pc585-NetworkManager-l2tp-gnome-1.20.4
  /nix/store/3gwimpdqk27isvxsgina5xybjflyyach-gcr-4.0.0
  /nix/store/40mzr00j7sjvwggd9pckfhk8qx4wnl99-openssl-3.0.8-dev
  /nix/store/42yzmnqbj8fi20zgp7rxdwfv6kk9ajyi-mirrors-list
  /nix/store/4hb4s91sia0zs26ajh654k523cjm7hbx-gnome-online-accounts-3.46.0
  /nix/store/4lb8906i1jc9z8zzljr6nbkd1d6gpid0-nixos-icons-2021-02-24
  /nix/store/4mx71d5kvvpv3a0j9q979vhxjn26gsss-ncurses-6.3-p20220507
  /nix/store/57q08wfkq603h0qsa978k09mv52iq307-libXrender-0.9.10
  /nix/store/5bqmx4d4719cy330amxjaq8xl9gi4a2c-libglvnd-1.5.0
  /nix/store/5g1fm2l1fdl0rky6551bvmp83ca9i4ib-mailcap-2.1.53
  /nix/store/5l49zw0jayqg5z3pd2vwzvph9rl5l1dr-cpupower-6.1.12
  /nix/store/5vnk8bsc2hrjn4xr6h5q6s3h4p2v51b3-bzip2-1.0.8
  /nix/store/6763yyy3d1i9xzkj1hhn4w2m9mq9qvmg-libgdata-0.18.1
  /nix/store/6lq12qdg6dyv3fcml12fynd38jiaixk7-gcr-3.41.1
  /nix/store/7kfspi8yvp1rfdr7i64pg4kb09chvp84-python3.10-img2pdf-0.4.4
  /nix/store/7r0gwbcl4himb62psghasi889jljq971-xz-5.2.7
  /nix/store/7snqq8cgc2mpv91x5xqwwy37dn40l890-curl-7.86.0
  /nix/store/8cpp7s99av1pv8gra6mq7bwbgpwfadva-webkitgtk-2.38.4+abi=4.1
  /nix/store/8djdrg1jjp23cfkc9daaaqm91jqcf005-libxcrypt-4.4.30
  /nix/store/90psnl5wkizbbih04f5sh71v3kb73x47-imagemagick-7.1.0-62
  /nix/store/98x9ppsn4gwl8nb4rv616cn151n3qfy4-libssh2-1.10.0
  /nix/store/9j4gsr5r8f07d0fp67nv71j8ys0r7xd2-linux-6.1.12
  /nix/store/9rjkadvh838sh48gyij22nfqm2lxpg3r-NetworkManager-openconnect-1.2.8
  /nix/store/a6ah6j78ncbszzvx9s245glcvbs9hkma-libXext-1.3.4
  /nix/store/aar4izry5b8nlv334nxcm7c85ii7649a-curl-7.86.0-dev
  /nix/store/aq6i9f39093r4ay6c7g9h8v9xiikgghl-kitty-0.26.2-terminfo
  /nix/store/b4m97d9icar7nkb29v93jxia5c6b661c-expat-2.5.0
  /nix/store/b66d1b11wghahz13ia997q1ysmsiii1h-nghttp2-1.51.0
  /nix/store/ck3g5ah8q43x90axhxxq8f6w6v6b2dif-libpciaccess-0.16
  /nix/store/ddcmfj2jshv0ghrhn3396n85zwcdkjg4-libGL-1.5.0
  /nix/store/dpjwzv61d39646mq0fms344934srmzsw-hook
  /nix/store/dv1d3vw9hhsq79p6j2jyxigr8ng9gbyf-kitty-0.26.2
...

I would rather like to see the individual package size, old version → new version, the packages grouped together according to their dependency on each other, coloring etc. if possible. Is there a way to do that?

1 Like

old version → new version

For a nix-build in isolation, this does not make a lot of sense: there can be multiple versions of a package in the store, and in your current system. nix-build does not necessarily know whether you’re “upgrading” to a newer version, or adding one besides the existing one.

That said, there are tools like nvd or nix store diff-closures that allow you to compare two derivations.

For your other points, they do seem like reasonable requests. nix-output-monitor for one seems to have a dependency tree view.

2 Likes

It works, thank you! It’s very interesting to see more of what nix is doing. :slightly_smiling_face:

For reference, i installed nix-output-monitor and am now running sudo nixos-rebuild switch --upgrade &| nom (i’m using fish).

For listing changes after upgrading, I find this useful:

2 Likes

I stole this from a colleague: https://github.com/R-VdP/nixos-config/blob/09d5c694db53d4ddfeefdc81e551a496f0cdf455/modules/update-diff.nix

It gives me a nice overview of what changed between the old generation and the new.

(You need to have the nix-command experimental feature enabled in order to use the new nix CLI.)

2 Likes

This doesn’t work for me, do you know why?

~ ❯ nvd diff $(ls -d1v /nix/var/nix/profiles/system-*-link|tail -n 2)                                                                
Path does not exist: v0.10.1 [+git]

If i run

~ ❯ sudo unbuffer nixos-rebuild switch --upgrade &| nom && nvd diff /run/current-system result                                        7s
unpacking channels...
building Nix...
building the system configuration...
activating the configuration...
setting up /etc...
reloading user units for sperber...
setting up tmpfiles
Finished at 17:01:19 after 7s
Path does not exist: result

it also doesn’t work. This doesn’t work either:

~ ❯ nvd diff result-old result-new
Path does not exist: result-old

@R-VdP could you please elaborate on what i have to do to use it in my configuration.nix so that it is run after each nixos-rebuild? I’m still learning Nixos and have never seen this before…

I tried to enable experimental-features like this:

  nix = {
    settings = { auto-optimise-store = true; };
    extraOptions = "experimental-features = true";
    gc = {
      automatic = true;
      dates = "daily";
      options = "--delete-older-than 7d";
    };
  };

But it’s failing… :pensive:

Yeah, it should be something like

nix = {
  settings.experimental-features = [ "nix-command" ];
};

and then you can put the contents of the module that I shared earlier, in configuration.nix:

system.activationScripts.diff = ''
  if [[ -e /run/current-system ]]; then
    echo "NixOS system closure diff:"
    ${pkgs.nix}/bin/nix store diff-closures /run/current-system "$systemConfig"
  fi
'';

Or you copy the module in a separate file next to configuration.nix, and in configuration.nix you say imports = [ ./update-diff.nix ];

Does that makes things clearer?

1 Like

It works, thank you! :slightly_smiling_face:

I found a way to tweak its legibility a bit. It’s not perfect but still an improvement.

TLDR for Noobs like me, add the following to configuration.nix:

nix.settings.experimental-features = [ "nix-command" ];
 system.activationScripts.diff = ''
    if [[ -e /run/current-system ]]; then
      if [[ -n $(${pkgs.nix}/bin/nix store diff-closures /run/current-system "$systemConfig") ]]; then echo; ${pkgs.nix}/bin/nix store diff-closures /run/current-system "$systemConfig" | grep -w "→" | grep -w "KiB" | column --table --separator " ,:" | ${pkgs.choose}/bin/choose :1 -4: | ${pkgs.gawk}/bin/awk '{s=$0; gsub(/\033\[[ -?]*[@-~]/,"",s); print s "\t" $0}' | sort -k5,5gr | ${pkgs.choose}/bin/choose 6: | column --table
      Sum=$(${pkgs.nix}/bin/nix store diff-closures /run/current-system "$systemConfig" | grep -w "→" | grep -w "KiB" | column --table --separator " ,:" | ${pkgs.choose}/bin/choose -2 | ${pkgs.ansifilter}/bin/ansifilter | tr "\n" " " | ${pkgs.gawk}/bin/awk 'NR == 1 { $0 = "0" $0 }; 1' | ${pkgs.bc}/bin/bc -l)
      if (( $(echo "$Sum != 0" | ${pkgs.bc}/bin/bc -l) )); then
      SumMiB=$(echo "scale=2; $Sum/1024" | ${pkgs.bc}/bin/bc -l)
      echo -en "\nSum: "
      if (( $(echo "$SumMiB > 0" | ${pkgs.bc}/bin/bc -l) )); then TERM=xterm-256color ${pkgs.ncurses}/bin/tput setaf 1; elif (( $(echo "$SumMiB < 0" | ${pkgs.bc}/bin/bc -l) )); then TERM=xterm-256color ${pkgs.ncurses}/bin/tput setaf 2; fi
      echo -e "$SumMiB MiB\n"
      TERM=xterm-256color ${pkgs.ncurses}/bin/tput setaf 7
      fi
    fi
  '';

If you want to have further information while building:

Add nix-output-monitor to your environment.systemPackages.

Alias the following commands to upgrade Nixos:

sudo nixos-rebuild switch --upgrade &| nom && fish (in fish)
sudo nixos-rebuild switch --upgrade |& nom && bash (in bash)

nom will blank out the sudo password prompt. It will only appear briefly. You can still enter the pasword and press enter. It will proceed as normal.

Bonus tip: nix-tree is a very useful application to examine your packages, their sizes and their dependencies.

5 Likes

Can you confirm that if you want to use the activationScript, then you need to have gawk, ansifilter, bc, choose, ncurses, nom, and xterm installed? Am I missing anything?

You don’t need to have all of them installed. If you add the activation script, NixOS will install the referenced packages automatically (same for systemd units).

If you want to use nom, then you have to install it explicitly because you’ll be executing it in the terminal as part of an alias.

1 Like

I like GitHub - viperML/nh: Yet another nix cli helper a lot, which uses nvd (mentioned by @justinas) under the hood:

4 Likes

The way I fixed the sudo thing (which was annoying because I’d forget I needed to type that and wonder why it was taking so long) was to add this as my alias:

sudo ls /dev/null > /dev/null 2>&1 && sudo nixos-rebuild switch --flake /home/wonko/projects/nix/WonkoOS#deepthought |& nom

one way I work around it is to prebuild the config and then switch:

nom build \
      .#nixosConfigurations.HOSTNAME.config.system.build.toplevel
nixos-rebuild switch --flake .#HOSTNAME --use-remote-sudo

I may pay the eval cost twice and also a lot of copies because I use several --override-input but until a better fix that will do