What packages will get updated?

I somewhat got started with NixOS and Nix - but I am still at a loss on how to control which package versions are actually installed and will get installed. Before I do

nix flake update && nixos-rebuild switch

How can I know which (system) packages are installed and will get updated with the rebuild?

How can I hold package version if I need to?

And on my quest to find what system package version are actually installed I came across:

nix-store -q --references /run/current-system
nix-store -q --references /run/booted-system

Why are they different?

So if you use flake, you can run:

$ nix eval --inputs-from . --raw nixpkgs#hello
/nix/store/zwnmwns242s7zzm2f4p0ndqdsxw1jb78-hello-2.12.1

and it will tell you the current version of hello in the flake located at the current path.

More generally, you can also look at the flake.lock file:

$ cat /etc/nixos/flake.lock
{
  "nodes": {
    "nixpkgs": {
      "locked": {
        "lastModified": 1675115703,
        "narHash": "sha256-4zetAPSyY0D77x+Ww9QBe8RHn1akvIvHJ/kgg8kGDbk=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "2caf4ef5005ecc68141ecb4aac271079f7371c44",
        "type": "github"
      },
      "original": {
        "id": "nixpkgs",
        "ref": "nixos-unstable",
        "type": "indirect"
      }
    },
    "root": {
      "inputs": {
        "nixpkgs": "nixpkgs"
      }
    }
  },
  "root": "root",
  "version": 7
}

or run:

$ nix flake info
Resolved URL:  git+file:///etc/nixos
Locked URL:    git+file:///etc/nixos?ref=refs%2fheads%2fmaster&rev=a9cbc07dc20920bdfef45fe11ea9b555861bcfd2
Description:   The configuration of my system
Path:          /nix/store/zj1sa8c6dyaxw44n8chn5yq2zcb5igbj-source
Revision:      a9cbc07dc20920bdfef45fe11ea9b555861bcfd2
Revisions:     55
Last modified: 2023-07-14 19:58:37
Inputs:
└───nixpkgs: github:NixOS/nixpkgs/2caf4ef5005ecc68141ecb4aac271079f7371c44

to get the hash of nixpkgs in use. You can see that on this example, it depends on 2caf4ef5005ecc68141ecb4aac271079f7371c44. From this, you have multiple ways to check the version of a package (maybe more that I don’t know):

  1. You can use:
    $ nix eval --raw "github:NixOS/nixpkgs/2caf4ef5005ecc68141ecb4aac271079f7371c44#hello"
    /nix/store/zwnmwns242s7zzm2f4p0ndqdsxw1jb78-hello-2.12.1
    
    So here you see that it provides the version 2.12.1.
  2. Another option (works best on small flake repositories) is to run something like nix flake show "github:NixOS/nixpkgs/2caf4ef5005ecc68141ecb4aac271079f7371c44" and it will list all packages available in this package. By default it will hide all “legacy” (non-flake) inputs, that you need to enable with --legacy, but note that the list might be huge for nix.
  3. You can also evaluate it in in interactive shell, like:
    $ nix repl
    nix-repl> :lf github:NixOS/nixpkgs/2caf4ef5005ecc68141ecb4aac271079f7371c44
    nix-repl> legacyPackages.aarch64-linux.hello.version
    "2.12.1"
    
  4. If you feel adventurous, you can also directly checkout the corresponding version on github and read the source of the program…

To know what package you will get after the rebuild, one option is to simply backup the current flake.lock (I typically use git for that, possibly using git stash if you don’t want to commit it), then run again nix flake update, and then follow again the above instructions. You can also realize that nix flake update will pick the latest commit in nixos-unstable (cf the nodes > nixpkgs > original > ref id from above), and then go to https://status.nixos.org/ to check the current commit pointed to by nixos-unstable. Once you have it, follow again the above instructions.

You might also like Nix Package Versions to find which channel contains which version.

Note also that if you install the same package from different sources (e.g. from home-manager, or custom $PATH…), you might use the version from this source instead of the system-installed package. To be sure, just run:

$ readlink -f $(which firefox)
/nix/store/xldghvr9g34x470l93pzdvrkxp1qbqv7-firefox-109.0.1/bin/firefox

so that you can know exactly where your executable is run from.

The difference between /run/current-system and /run/booted-system is that you might have upgraded your system since you booted, so booted-system might point to an older repository. For instance, the kernel you are currently running is the one from booted-system, not current-system.

There isn’t really an easy way, it basically requires doing a full evaluation anyway. So instead, just do that, then compare (see below).

as noted, the system closure link at the time you last booted may have been updated (or rolled back) since. The difference between closures (basicaly, comparing the two lists above with more useful formatting) can be seen with nix store diff-closures …

So you can use:

  • nix store diff-closures /run/*-system to see what has been upgraded after switching. I use this for general review and mostly to see if I need a reboot or DE restart. (Note that booted sorts before current)
  • nixos-rebuild build to build, but not switch to, a new generation, followed by nix store diff-closures /run/current-system /etc/nixos/result to see the differences in the new build before switching.
4 Likes

Thanks for the help, folks.

The difference here makes sense now:

nix-store -q --references /run/current-system
nix-store -q --references /run/booted-system

As for nix eval --inputs-from . --raw nixpkgs#hello it feels easier to just use nix-store -q --references /run/current-system and maybe grep. Still it’s a little awkward. I guess the fact that all is sha based makes the versions just so much less important.

I am just wondering how one deals with security related updates.
As in “Do I have version x with the proper patch applied?”

This is gold :heart::

nix store diff-closures /run/*-system
nixos-rebuild build 
nix store diff-closures /run/current-system /etc/nixos/result

Thanks for that!

2 Likes

Technically, you can know the exact derivations of all softwares used to build your whole system via:

$ nix show-derivation -r /run/current-system

(warning: it will print all derivations used in the system, so it will be huge!)
To find the patches of a single package, you can do something like:

$ nix show-derivation $(readlink -f $(which firefox)) | grep patches
"patches": "",

Note that this will only contain patches specified via the patches field of mkDerivation, and if firefox is not the main derivation that builds firefox, but rather a wrapper around another derivation, you might not see the patches. In that case, you can either inspect more precisely the derivation, or run it recursively to know all patches applied to dependencies:

$ nix show-derivation -r $(readlink -f $(which firefox)) | grep patches

If you want to be more precise, you can inspect the derivation and realize that it depends on /nix/store/xp13460p5bk7464v3ircgqqvzdmpigyp-firefox-unwrapped-109.0.1.drv (which is the unwrapped firefox), and indeed on that one you can see the precise patches that were applied:

$ nix show-derivation /nix/store/xp13460p5bk7464v3ircgqqvzdmpigyp-firefox-unwrapped-109.0.1.drv  | grep patches
      "patches": "/nix/store/2x0h67cqxa7bnffb63q2scly64rb2nlp-env_var_for_system_dir-ff86.patch /nix/store/7zf2qf5fkyb5pv9yzg89a9rzrcffhzaw-no-buildconfig-ffx96.patch",

and read them precisely with:

$ cat /nix/store/2x0h67cqxa7bnffb63q2scly64rb2nlp-env_var_for_system_dir-ff86.patch
diff -r 22fc47c968f2 toolkit/xre/nsXREDirProvider.cpp
--- a/toolkit/xre/nsXREDirProvider.cpp  Mon Dec 14 15:09:17 2020 +0000
+++ b/toolkit/xre/nsXREDirProvider.cpp  Tue Feb 23 23:38:56 2021 +0100
@@ -11,6 +11,7 @@
 
 #include "jsapi.h"
 #include "xpcpublic.h"
+#include "prenv.h"
 
 #include "nsIAppStartup.h"
 #include "nsIFile.h"
@@ -305,7 +306,8 @@
       "/usr/lib/mozilla"_ns
 #    endif
       ;
-  rv = NS_NewNativeLocalFile(dirname, false, getter_AddRefs(localDir));
+  const char* pathVar = PR_GetEnv("MOZ_SYSTEM_DIR");
+  rv = NS_NewNativeLocalFile((pathVar && *pathVar) ? nsDependentCString(pathVar) : reinterpret_cast<const nsCString&>(dirname), false, getter_AddRefs(localDir));
 #  endif
 
   if (NS_SUCCEEDED(rv)) {

But often, it might be simpler to just look at the source code of nixpkgs in the repository.

Technically, you can know the exact derivations of all softwares used to build your whole system via:

That is pretty cool - but also quite overwhelming to consume (as a whole) :slight_smile:

Does NixOS have a security team or who is keeping track of CVEs an such?
Or is this all up to the individual package maintainers?

I am basically trying to figure out run NixOS servers that should be stable enough and receive security patches/fixes - without necessarily just upgrading to the latest and greatest.
And how to cover the usual server maintenance tasks.

You can implement it so that it shows this automatically after you switched.
There’s maybe a way to show it after you’ve built it as well:

I combine it with nix-output-monitor which shows as well a lot of information.

https://search.nixos.org/packages?channel=23.05&show=nix-output-monitor&from=0&size=50&sort=relevance&type=packages&query=nix-output-monitor

1 Like

I’m not an expert on security in NixOs, but here are a few pointers:

1 Like