nix-git/NixOS.md

13 KiB

NixOS

This document contains general notes about NixOS that are independent of my NixOS configuration.

Table of Contents

Misc

  • There is controversy about flakes, rather use channels (e.g. with niv)
  • Prins, P., Suresh, J. and Dolstra, E., "Nix fixes dependency hell on all Linux distributions," Archived December 26, 2008, at the Wayback Machine linux.com, December 22, 2008

Upgrade from 23.05 to 23.11

Change the tracking branch of nixpkgs from 23.05 to 23.11:

niv modify nixpkgs      --branch   nixos-23.11
niv modify home-manager --branch release-23.11

Update home.stateVersion to home.stateVersion = "23.11"; in order to match the NixOS channel. Read the corresponding release notes: https://nix-community.github.io/home-manager/release-notes.xhtml#sec-release-23.11

Read the release notes. GNOME 45: Notably, Loupe has replaced Eye of GNOME as the default image viewer, Snapshot has replaced Cheese as the default camera application, and Photos will no longer be installed.

Updating with nixos-rebuild boot and rebooting is recommended.

niv update && colmena build --on yodaTux   -v --show-trace && colmena apply-local --sudo   boot
niv update && colmena build --on remoteTab -v --show-trace && colmena apply --on remoteTab boot
niv update && colmena build --on @server   -v --show-trace && colmena apply --on @server   boot

Update channel (for nix-shell usage in a terminal):

sudo nix-channel --list
#=> nixos https://nixos.org/channels/nixos-23.05
sudo nix-channel --add https://nixos.org/channels/nixos-23.11 nixos
sudo nix-channel --update

niv: Dependency management

niv:

Easy dependency management for Nix projects.

Nix is a very powerful tool for building code and setting up environments. niv complements it by making it easy to describe and update remote dependencies (URLs, GitHub repos, etc). It is a simple, practical alternative to Nix flakes.

https://github.com/nmattia/niv

Niv is an easy dependency management for Nix projects with package pinning.

https://github.com/mikeroyal/NixOS-Guide

Initialize:

niv init

Change the tracking branch of nixpkgs from unstable to 23.05:

niv modify nixpkgs --branch nixos-23.05

Add nixpkgs unstable:

niv add NixOS/nixpkgs -n unstable -b nixpkgs-unstable

Add Home Manager with niv

Home Manager:

[Home Manager] allows declarative configuration of user specific (non-global) packages and dotfiles.

To avoid breaking users' configurations, Home Manager is released in branches corresponding to NixOS releases ( e.g. release-23.05).

Home Manager provides both the channel-based setup and the flake-based one.

https://github.com/nix-community/home-manager

Check your channel:

sudo nix-channel --list
#=> nixos https://nixos.org/channels/nixos-23.05

Use the corresponding branch:

niv add nix-community/home-manager -n home-manager -b release-23.05

Add NUR with niv

The Nix User Repository (NUR) is community-driven meta repository for Nix packages.

... packages are built from source and are not reviewed by any Nixpkgs member.

https://github.com/nix-community/NUR

niv add nix-community/NUR -n NUR

Garbage collection

This is automated in base.nix with the nix.gc option.

Run manually for all profiles:

sudo nix-collect-garbage --delete-older-than 14d

Remove leftover EFI entries of removed generations:

sudo /run/current-system/bin/switch-to-configuration boot

System information

nix-info -m
 - system: `"x86_64-linux"`
 - host os: `Linux 6.1.51, NixOS, 23.05 (Stoat), 23.05.3242.da5adce0ffaf`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.13.5`
 - channels(root): `"nixos-23.05"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

Search for packages

Search for options

Search which package owns a file

# Note how your shell prefix changes.
nix-shell -p nix-index
# Either build the index manually (requires >12GB RAM):
nix-index
# Or download weekly build:
mkdir -p ~/.cache/nix-index/ && wget -q -N https://github.com/nix-community/nix-index-database/releases/latest/download/index-x86_64-linux -O ~/.cache/nix-index/files

# Then search for a file
nix-locate --whole-name '/bash'

List files of package

Example for nano:

find $(nix-build '<nixpkgs>' -A nano --no-link)

Excerpt of the result:

/nix/store/jqvxmx65mfinbsm6db9kmcqmphl44xhp-nano-7.2/share/nano
/nix/store/jqvxmx65mfinbsm6db9kmcqmphl44xhp-nano-7.2/share/nano/asm.nanorc
/nix/store/jqvxmx65mfinbsm6db9kmcqmphl44xhp-nano-7.2/share/nano/autoconf.nanorc

Compare two versions of NixOS system profile

Get latest system profile. This is the profile (usually) being active after booting the system:

ls -1 /nix/var/nix/profiles/ | sort -t'-' -n -k2 | tail -n 1
#=> 120

Compare current with previous profile:

# https://discourse.nixos.org/t/how-to-know-what-nixpkgs-changes-affect-me/18142/6
prev="$(ls -r /nix/var/nix/profiles/ | grep -E 'system\-' | sed -n '2 p')"
curr=/nix/var/nix/profiles/system
nix --extra-experimental-features nix-command store diff-closures /nix/var/nix/profiles/"${prev}" "${curr}"
# https://stackoverflow.com/a/36641298
prev="$(ls -1 /nix/var/nix/profiles/ | sort -t'-' -n -k2 | tail -n 2 | head -n 1)"
curr="$(ls -1 /nix/var/nix/profiles/ | sort -t'-' -n -k2 | tail -n 1)"
nix --extra-experimental-features nix-command store diff-closures /nix/var/nix/profiles/"${prev}" /nix/var/nix/profiles/"${curr}"

Compare two arbitrary system profiles:

nix --extra-experimental-features nix-command store diff-closures /nix/var/nix/profiles/system-110-link /nix/var/nix/profiles/system-116-link
cpupower: 6.1.47 → 6.1.51
element-desktop: 1.11.38 → 1.11.40, +2218.9 KiB
element-web: 1.11.38 → 1.11.40, -73.1 KiB
exempi: 2.6.3 → 2.6.4
firefox: 116.0.3 → 117.0
firefox-unwrapped: 116.0.3 → 117.0, -292.6 KiB
gnome-shell-extension-openweather: ∅ → 121, +590.5 KiB
hm_fontconfigconf.d10hmfonts.conf: ∅ → ε
initrd: ∅ → ε
initrd-linux: 6.1.47 → 6.1.51
libcap: 2.68 → 2.69
linux: 6.1.47, 6.1.47-modules → 6.1.51, 6.1.51-modules, -11.8 KiB
meld: ∅ → 3.22.0, +3858.5 KiB
net-snmp: 5.9.3 → 5.9.4
nixos-system-yodaTab: 23.05.3085.2ab91c8d65c0 → 23.05.3242.da5adce0ffaf
openjdk: +19.5 KiB
python3.10-pygobject: +27.0 KiB
stage: ∅ → 1-init.sh, +29.5 KiB
tor-browser-bundle-bin: 12.5.2 → 12.5.3, +18.1 KiB
user: +2885.0 KiB

NixOS configuration debugging

Evaluating parts of the configuration.

First, start nix repl:

nix repl --file '<nixpkgs/nixos>' -I nixos-config=hosts/$(hostname)/configuration.nix

Example: config.home-manager

config.home-manager.
# Press `TAB`
#=> config.home-manager.backupFileExtension  config.home-manager.useUserPackages
#=> config.home-manager.extraSpecialArgs     config.home-manager.users
#=> config.home-manager.sharedModules        config.home-manager.verbose
#=> config.home-manager.useGlobalPkgs

Example: The home variable:

config.home-manager.users.yoda.home

Example: The value of one config option

# The following option is set to `"${config.xdg.dataHome}/.histfile";`
# where `config` is the Home Manager configuration.

config.home-manager.users.yoda.programs.zsh.history.path
#=> "/home/yoda/.local/share/.histfile"

Show Nix configuration

nix --extra-experimental-features nix-command show-config

Evaluate NixOS configuration to JSON

See also section "NixOS Configuration Debugging"!

This evaluates configuration.nix (single module):

NIXPKGS_ALLOW_UNFREE=1 nix-instantiate --strict --json --eval -E '
import ./hosts/yodaTab/configuration.nix  {
  config = {};
  pkgs = import <nixpkgs> {};
  lib = import <nixpkgs/lib>;
}
' > evaluated-config.json

Then open evaluated-config.json.

Evaluate expressions

nix-instantiate --eval -E 'with import <nixpkgs> { }; vscode.version'
#=> "1.78.2"

Shell wrapper:

nix-eval() { nix-instantiate --eval -E "with import <nixpkgs> {}; ${*}"; }

Examples:

nix-eval 'vscode.version'
#=> "1.78.2"
nix-eval 'lib.forEach [ 1 2 ] (x: toString x)'
#=> [ "1" "2" ]
nix-eval 'lib.head [1 2]'
#=> 1
nix-eval 'lib.head (
  lib.forEach [ 1 2 ] (x: toString x)
)'
#=> "1"
nix-eval 'lib.head (
  lib.forEach [ {a=1;} {a=2;} ] (x: x.a)
)'
#=> 1
nix-eval 'lib.attrsets.mergeAttrsList [{a=1;} {b=2;}]'
#=> { a = 1; b = 2; }
nix-eval '{ a=1; }.b or 2'
#=> 2
nix-eval '{ a=false; }.a or true'
#=> false
nix-eval '{ a=1; }?a'
#=> true
nix-eval 'with lib.strings; concatMapStrings (x: " -a " + x + " -i 600") ["sda" "sdc"]'
#=> " -a sda -i 600 -a sdc -i 600"

Escape strings

Double-quoted strings (e.g. "foo bar"):

"  -> \"
\  -> \\
${ -> \${

Indented strings (e.g. ''foo bar''):

  • ${ -> ''${
  • '' -> '''

URIs can be written without quotes (e.g. http://example.org/foo.bar).

Run AppImages

# Note how your shell prefix changes.
nix-shell -p appimage-run
# Inside the shell, you can run an AppImage:
appimage-run ~/Downloads/ubports-installer_0.10.0_linux_x86_64.AppImage

Additional resources

Nix Pills

It provides a tutorial introduction into the Nix package manager and Nixpkgs package collection, in the form of short chapters called 'pills'.

Papers

Papers about Nix: