Remove Snapper timeline snapshots leaked by earlier defaults
Installs from before the Snapper setup was normalized ran hourly timeline snapshots. Newer configs stopped creating them but never deleted the existing ones, and number cleanup skips snapshots marked Cleanup=timeline, so they sit there forever: one machine installed from the 2026-05-11 ISO had accumulated 592 of them, silently pinning 219 GB of disk. The limine-snapper-sync limit-mismatch warning that would have surfaced this is disabled by default since the notifier migration. Delete leaked timeline snapshots in batches of 20 (a single mass delete can die on a DBus timeout partway through), and only when TIMELINE_CREATE="no" so anyone who deliberately re-enabled timeline snapshotting keeps their setup untouched. The drain is best effort: a batch that fails is skipped rather than aborting the migration run and everything queued behind it, since the next run re-lists whatever is left.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
echo "Remove Snapper timeline snapshots leaked by earlier defaults"
|
||||
|
||||
SNAPPER_CONFIG_PATH="${OMARCHY_SNAPPER_CONFIG_PATH:-/etc/snapper/configs/root}"
|
||||
|
||||
as_root() {
|
||||
if (( EUID == 0 )); then
|
||||
"$@"
|
||||
else
|
||||
sudo "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
command -v snapper >/dev/null || exit 0
|
||||
[[ -f $SNAPPER_CONFIG_PATH ]] || exit 0
|
||||
|
||||
# Only clean up when timeline snapshotting is off, as Omarchy configures it.
|
||||
# Anyone who deliberately turned it back on keeps their snapshots.
|
||||
grep -qFx 'TIMELINE_CREATE="no"' "$SNAPPER_CONFIG_PATH" || exit 0
|
||||
|
||||
# Earlier installs ran hourly timeline snapshots. Later configs stopped
|
||||
# creating them but never deleted the existing ones, and number cleanup
|
||||
# skips snapshots marked Cleanup=timeline, so they pile up forever:
|
||||
# hundreds of snapshots pinning 100+ GB of extents on long-running machines.
|
||||
leaked=$(as_root snapper -c root --csvout list --columns number,cleanup 2>/dev/null | awk -F, '$2 == "timeline" { print $1 }' || true)
|
||||
[[ -n $leaked ]] || exit 0
|
||||
|
||||
echo "Deleting $(wc -w <<<"$leaked") leaked timeline snapshots (disk space is reclaimed in the background)"
|
||||
|
||||
# Delete in small batches; one big delete can die on a DBus timeout partway.
|
||||
# A failed batch must not take the rest of the migration run down with it, so
|
||||
# the drain is best effort: whatever survives is picked up by the next run.
|
||||
batch=()
|
||||
for number in $leaked; do
|
||||
batch+=("$number")
|
||||
if (( ${#batch[@]} == 20 )); then
|
||||
as_root snapper -c root delete "${batch[@]}" || true
|
||||
batch=()
|
||||
fi
|
||||
done
|
||||
|
||||
if (( ${#batch[@]} > 0 )); then
|
||||
as_root snapper -c root delete "${batch[@]}" || true
|
||||
fi
|
||||
Reference in New Issue
Block a user