Skip to content

Instantly share code, notes, and snippets.

@noflcl
Created July 27, 2025 20:18
Show Gist options
  • Select an option

  • Save noflcl/2369d1227356a00fc800e9c4c3635aab to your computer and use it in GitHub Desktop.

Select an option

Save noflcl/2369d1227356a00fc800e9c4c3635aab to your computer and use it in GitHub Desktop.
A wrapper script that takes ZFS snapshots prior to nixos-rebuild creating a new system
This wrapper script creates a shell script named `nixos-rebuild-hooked` that reads your `sanoid` config for which datasets are being managed, snapshots them prior to `nixos-rebuild` running. If you are suing `flakes` like I am you can execute rebuild with these features: `nixos-rebuild-hooked switch --flake .`
```nix
{ config, pkgs, ... }:
{
environment.systemPackages = with pkgs; [
(pkgs.writeShellScriptBin "nixos-rebuild-hooked" ''
echo "Running pre-rebuild hook..."
# Get current system generation once
CURRENT_GEN=$(ls -la /nix/var/nix/profiles/system | grep -o 'system-[0-9]*-link' | tail -1)
echo "Current generation: $CURRENT_GEN"
# Get list of datasets from sanoid configuration
echo "Getting datasets from sanoid configuration..."
DATASETS=$(sudo sanoid --verbose --debug --configdir=/etc/sanoid | grep Filesystem | awk '{print $2}')
if [ -z "$DATASETS" ]; then
echo "No datasets found in sanoid configuration"
exit 1
fi
echo "Found datasets:"
echo "$DATASETS"
snapshot_with_prefix() {
local dataset="$1"
local timestamp=$(date +%Y-%m-%d_%H-%M-%S)
local snapshot_name="$dataset@''${CURRENT_GEN}_$timestamp"
echo "Creating snapshot: $snapshot_name"
sudo zfs snapshot -r "$snapshot_name"
}
# Loop through each dataset and create snapshots
while IFS= read -r dataset; do
if [ -n "$dataset" ]; then
snapshot_with_prefix "$dataset"
fi
done <<< "$DATASETS"
echo "Pre-rebuild snapshots complete"
# Run nixos-rebuild
exec /run/current-system/sw/bin/nixos-rebuild "$@"
'')
];
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment