Files
omarchycn/migrations/1784809452.sh
T
Martin Bastien d548c064ee 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.
2026-07-23 09:10:16 -04:00

44 lines
1.5 KiB
Bash

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