Skip to content

$ cat ./posts/arch/pacman-hooks-for-reproducible-systems.hook

-rw-r--r-- 1.6K #arch #pacman

Pacman hooks for reproducible systems

by chris · 2 min read · /arch


A pacman hook is an ini file in /etc/pacman.d/hooks/ that runs a command when a transaction touches something you care about. They are the cleanest extension point in the package manager, and almost nobody uses them.

1. Snapshot before every upgrade

# /etc/pacman.d/hooks/00-btrfs-snapshot.hook
[Trigger]
Operation = Upgrade
Operation = Remove
Type = Package
Target = *

[Action]
Description = Snapshotting root before transaction...
When = PreTransaction
Exec = /usr/bin/btrfs subvolume snapshot -r / /.snapshots/pre-pacman
AbortOnFail

AbortOnFail is the important line: if the snapshot fails, the upgrade does not proceed. A rollback plan that silently stops existing is not a rollback plan.

2. React to what actually changed

Triggers match paths as well as package names, so a hook can fire only when a specific file is touched:

[Trigger]
Operation = Upgrade
Type = Path
Target = usr/lib/modules/*/vmlinuz

[Action]
When = PostTransaction
Exec = /usr/local/bin/rebuild-dkms-and-sign

3. Keep them boring

Hooks run as root, in the middle of a transaction, with the package database locked. A hook that calls the network can hang an upgrade indefinitely; one that itself calls pacman deadlocks. Keep the command local, fast and idempotent, and log to the journal so there is something to read when an upgrade takes ninety seconds longer than expected.

Kept small, three or four hooks turn a rolling-release machine into something you can upgrade on a Friday.

← cd .. fris@linux:~/blog$ man arch