aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-30 01:49:09 -0400
committerCraig Jennings <c@cjennings.net>2026-06-30 01:49:09 -0400
commita84dbf8cc221c16cb576cfb3cd50c60869e0a638 (patch)
tree0ebb43ab7ba38b2f97d75ecc1a44b3db9a02ee23
parentad986255431631ad5c5cd47e2c9cb90df715040b (diff)
downloadarchsetup-a84dbf8cc221c16cb576cfb3cd50c60869e0a638.tar.gz
archsetup-a84dbf8cc221c16cb576cfb3cd50c60869e0a638.zip
docs: file ZFS pre-pacman snapshot installer step from home handoff
The pre-pacman snapshot script accumulated 53 unpruned snapshots on velox since April — nothing prunes them, and Sanoid ignores the non-autosnap_ names. The fix is a self-pruning script (KEEP=10), but the home handoff confirmed the live script isn't archsetup-authored (it's hand-placed on velox), so incorporating it is a net-new ZFS-root installer step rather than a patch to an existing one. Filed as a [#B] feature with the design notes and the script preserved in docs/design, since it still needs the trigger hook file and a ZFS-root VM test before it can land.
-rw-r--r--docs/design/2026-06-29-zfs-pre-snapshot-installer.org87
-rw-r--r--todo.org5
2 files changed, 92 insertions, 0 deletions
diff --git a/docs/design/2026-06-29-zfs-pre-snapshot-installer.org b/docs/design/2026-06-29-zfs-pre-snapshot-installer.org
new file mode 100644
index 0000000..413bfa5
--- /dev/null
+++ b/docs/design/2026-06-29-zfs-pre-snapshot-installer.org
@@ -0,0 +1,87 @@
+#+TITLE: ZFS pre-pacman snapshot installer step (durable retention)
+#+DATE: 2026-06-29
+#+SOURCE: handoff from the home project, 2026-06-29
+
+* Problem
+
+A pacman =PreTransaction= hook snapshots =zroot/ROOT/default@pre-pacman_<ts>=
+before every transaction, but nothing prunes them. Sanoid doesn't manage them
+(they aren't =autosnap_= names), so they accumulated to 53 on velox between
+April and the 2026-06-29 health check. Unbounded, they fill the pool over time.
+
+* What's actually on velox vs. archsetup
+
+The live =/usr/local/bin/zfs-pre-snapshot= is *not* authored by archsetup —
+=git grep= for its content (=MIN_INTERVAL=, the pre-pacman =LOCKFILE= logic)
+finds nothing tracked. The =PreTransaction= hooks in the archsetup monolith
+(~lines 910, 1907, 1942) are the live-update guard, a different hook. The
+script appears hand-placed on velox.
+
+The 2026-01-17 security doc line "ZFS pre-pacman snapshots (already in
+install-archzfs)" is therefore *out of date* — archsetup does not install this.
+Incorporating the fix is a NET-NEW installer step, not a patch to an existing
+one. Correct that stale doc line as part of the work.
+
+velox was patched live (pruned to 10, script replaced with the self-pruning
+version below); live backup at =/usr/local/bin/zfs-pre-snapshot.bak-2026-06-29=.
+
+* Proposed installer step
+
+In the archzfs / ZFS-on-root install path, gated to ZFS-root installs (velox is
+the only ZFS daily driver; ratio is btrfs), install:
+
+1. =/etc/pacman.d/hooks/zfs-snapshot.hook= — the =PreTransaction= hook that
+ runs the script. *Not included in the handoff* — source it from velox
+ (=/etc/pacman.d/hooks/zfs-snapshot.hook=) or write it.
+2. =/usr/local/bin/zfs-pre-snapshot= — the =KEEP=10= self-pruning version
+ below.
+
+Tests live in archsetup, so this wants an archsetup session and a ZFS-root VM
+test (=make test FS_PROFILE=zfs=), not a cross-project edit from home.
+
+* The script (KEEP=10 self-pruning version)
+
+#+begin_src bash
+#!/bin/bash
+POOL="zroot"
+DATASET="$POOL/ROOT/default"
+LOCKFILE="/tmp/.zfs-pre-snapshot.lock"
+MIN_INTERVAL=60
+KEEP=10 # how many pre-pacman snapshots to retain (rollback safety for recent transactions)
+
+# Skip if a snapshot was created within the last 60 seconds
+if [ -f "$LOCKFILE" ]; then
+ last=$(stat -c %Y "$LOCKFILE" 2>/dev/null || echo 0)
+ now=$(date +%s)
+ if (( now - last < MIN_INTERVAL )); then
+ exit 0
+ fi
+fi
+
+TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
+SNAPSHOT_NAME="pre-pacman_$TIMESTAMP"
+
+if zfs snapshot "$DATASET@$SNAPSHOT_NAME"; then
+ echo "Created snapshot: $DATASET@$SNAPSHOT_NAME"
+ touch "$LOCKFILE"
+
+ # Retention: keep only the most recent $KEEP pre-pacman snapshots, destroy older ones.
+ # Sanoid does not manage these (they aren't autosnap_), so prune them here at creation time.
+ zfs list -H -o name -t snapshot -s creation "$DATASET" 2>/dev/null \
+ | grep '@pre-pacman_' \
+ | head -n -"$KEEP" \
+ | while read -r old; do
+ zfs destroy "$old" && echo "Pruned old snapshot: $old"
+ done
+else
+ echo "Warning: Failed to create snapshot" >&2
+fi
+#+end_src
+
+* Open items before implementation
+
+- Source or write =/etc/pacman.d/hooks/zfs-snapshot.hook= (the trigger).
+- Decide the exact insertion point in the ZFS-root install path.
+- Add a ZFS-root VM test asserting the hook + script land and the script
+ self-prunes past =KEEP=.
+- Correct the stale 2026-01-17 security-doc line.
diff --git a/todo.org b/todo.org
index daf3625..c5720cb 100644
--- a/todo.org
+++ b/todo.org
@@ -21,6 +21,11 @@ The vocabulary is open — topic tags are coined as needed — so these are conv
- *Effort / autonomy*: =:quick:= a spare-moment fix (minutes, not a sitting); =:solo:= Claude can carry it end to end — there's a build path, a test path, and no upfront decision needed (a leftover manual spot-check doesn't disqualify it).
- *Topic / area* (open): the subsystem a task touches — e.g. =:hyprland:= =:waybar:= =:mpd:= =:music:= =:network:= =:tooling:= =:llm:= =:eask:= =:pocketbook:= =:cmail:=. Coin a new one when it aids filtering.
* Archsetup Open Work
+** TODO [#B] ZFS pre-pacman snapshot installer step (ZFS-root) :feature:zfs:
+Add a ZFS-root-gated installer step that installs the pre-pacman snapshot pacman hook plus a self-pruning =/usr/local/bin/zfs-pre-snapshot= (KEEP=10). The script is hand-placed on velox, not authored by archsetup, so a reinstall loses it; snapshots accumulated unbounded (53 since April) because nothing prunes them and Sanoid ignores non-autosnap_ names. Gate to ZFS-root (velox; ratio is btrfs). Also correct the stale 2026-01-17 security-doc line claiming it's "already in install-archzfs". Needs the hook file (source from velox) and a ZFS-root VM test.
+
+Design notes and the KEEP=10 script: [[file:docs/design/2026-06-29-zfs-pre-snapshot-installer.org]]. Origin: home handoff 2026-06-29.
+
** TODO [#B] Scrolling/Carousel layout: frame fit + wrap-around :hyprland:
:PROPERTIES:
:LAST_REVIEWED: 2026-06-13