Pinning NixOS with npins

I have a small improvement that I found while wrangling nixos-rebuild-ng ignoring the NIX_PATH I gave it.

In my rebuild script I have the rebuild step with these 2 lines (written in fish):

set -l nixpkgs_path (nix-instantiate --json --eval npins/default.nix -A nixpkgs.outPath | jq -r .)
sudo nixos-rebuild switch -I nixos-config=/home/$USER/nixos-config/configuration.nix -I nixpkgs=$nixpkgs_path 2>&1 | tee rebuild.log

and in my config I have a pinning.nix module

{
  config,
  pkgs,
  ...
}: let
  sources = import ./npins;
in {
  # kill channels
  nix = {
    channel.enable = false;
    nixPath = [
      "nixpkgs=/etc/nixos/nixpkgs"
      "nixos-config=/home/USERNAME/nixos-config/configuration.nix"
    ];
  };
  environment.etc = {
    "nixos/nixpkgs".source = builtins.storePath pkgs.path;
  };

  # pinning
  nixpkgs = {
    config = {
      packageOverrides = pkgs: {
        unstable = import sources.nixpkgs-unstable {config = config.nixpkgs.config;};
        vpncpin = import sources.nixpkgs-vpncpin {config = config.nixpkgs.config;};
      };
    };
  };
}

overlays are useful for readability when I use them elsewhere.

For anyone reading the 2 blog posts mentioned originally, this and the discussion here It basically boils down to:

  • No flake features, eval for nixos-rebuild is done using Jade’s one liner with nix-instantiate
  • pin using npins
  • give nixos-rebuild the latest nixpkgs by passing -I which bypasses all other includes
  • make <nixpkgs> be consistent across the system (see piegames) blog
  • I also use overrides for the imported pins, but feel free to integrate however you like

see my full config here

EDIT:
save yourself the next headache and point the command-not-found to the correct database

programs.command-not-found.dbPath = "/etc/nixos/nixpkgs/programs.sqlite";

now, why is this hardcoded to point to the root nixos channel is beyond me, but yeah that fixes the

DBI connect('dbname=/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite','',...) failed: unable to open database file at /run/current-system/sw/bin/command-not-found line 13.
cannot open database `/nix/var/nix/profiles/per-user/root/channels/nixos/programs.sqlite' at /run/current-system/sw/bin/command-not-found line 13.

there seems to be some activity on the module in nixpkgs (including explicit fish integration :DD), but I don’t care enough to override it so I’ll just wait until 25.11. This works well enough

5 Likes