3.7 KiB
zfs-pacman-hook
Arch Linux pacman hook for automatic ZFS snapshots
Setup
Get started like so:
- Install dependency
jq
- Clone repo into arbitrary path
<repo>
- Make
pacman-zfs-snapshot.sh
executablechmod +x <repo>/pacman-zfs-snapshot.sh
- Symlink to files, for example
Note that while you may choose arbitrary locations for symlinks thesudo ln -s <repo>/pacman-zfs-snapshot.sh /usr/local/bin/pacman-zfs-snapshot sudo ln -s <repo>/pacman-zfs-snapshot-install.hook /usr/share/libalpm/hooks/pacman-zfs-snapshot-install.hook sudo ln -s <repo>/pacman-zfs-snapshot-remove.hook /usr/share/libalpm/hooks/pacman-zfs-snapshot-remove.hook sudo ln -s <repo>/pacman-zfs-snapshot-upgrade.hook /usr/share/libalpm/hooks/pacman-zfs-snapshot-upgrade.hook sudo ln -s <repo>/pacman-zfs-snapshot.conf /etc/pacman-zfs-snapshot.conf
pacman-zfs-snapshot-*.hook
files reference/usr/local/bin/pacman-zfs-snapshot
. Change that accordingly if you need to. - For datasets you want auto-snapshotted add property
space.quico:auto-snapshot=true
With any other property and any other value datasets will not be auto-snapshotted.zfs set space.quico:auto-snapshot=true zpool/root/archlinux
- Adjust
pacman-zfs-snapshot.conf
to your liking. You may want to setdo_dry_run='true'
for a start and just reinstall a benign package to get a feel for what this hook would do.
What's it do?
In pacman
on every PreTransaction
, meaning right before any actual operation on a package begins, we trigger a ZFS snapshot. By default we identify the active system dataset by doing findmnt / --noheadings --output source
. If exactly one source returns that is the exact name of a ZFS dataset in an imported zpool we create a snapshot on it. If no source returns we silently exit. If more than one source returns we raise an error and halt the pacman
transaction.
We retain two different snapshot chains, one for pacman
transactions that only affect what we are calling trivial packages and a separate chain for important packages. By default only the exact regular expression package name match ^(linux)$
is considered important. Whenever an important package is affected by a transaction a snapshot goes into the corresponding chain. In all other cases - when an important package is not affected - snapshots go into the trivial chain.
The trivial snapshot chain by default keeps 15 snapshots, the important chain keeps 5. The thought process here is that you will likely not futz around with a kernel every day whereas you may very well install arbitrary packages multiple times a day. Snapshots should keep you safe for a couple of days hence the defaults of 5 and 15 snapshots, respectively.
You may optionally include more ZFS datasets in this snapshot mechanism. Have a look at pacman-zfs-snapshot.conf
, its comments should be clear enough to get you going.
Development
Conventional commits
This project uses Conventional Commits for its commit messages.
Commit types
Commit types besides fix
and feat
are:
build
: Project structure, directory layout, build instructions for roll-outrefactor
: Keeping functionality while streamlining or otherwise improving function flowtest
: Working on test coveragedocs
: Documentation for project or components
Commit scopes
The following scopes are known for this project. A Conventional Commits commit message may optionally use one of the following scopes or none:
conf
: How we deal with script configscript
: Any other script work that doesn't specifically fall into the above scopeshook
: Configuring the hook(s)meta
: Affects the project's repo layout, readme content, file names etc.