mirror of
https://github.com/fscotto/infra.git
synced 2026-09-27 11:02:47 +00:00
52 lines
1.9 KiB
Django/Jinja
52 lines
1.9 KiB
Django/Jinja
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
export PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
|
|
|
readonly pool={{ atlas_zfs_pool | quote }}
|
|
readonly mount_root={{ atlas_mount_root | quote }}
|
|
readonly snapshot_prefix={{ atlas_usb_backup_snapshot_prefix | quote }}
|
|
readonly marker=/run/atlas-usb-backup/snapshot-name
|
|
|
|
[[ -e "$marker" ]] || exit 0
|
|
[[ -f "$marker" && ! -L "$marker" ]] || {
|
|
printf 'Unsafe Atlas USB snapshot marker; leaving snapshots unchanged\n' >&2
|
|
exit 2
|
|
}
|
|
IFS= read -r snapshot_name <"$marker"
|
|
[[ "$snapshot_name" =~ ^${snapshot_prefix}-[0-9]{8}T[0-9]{6}Z-[0-9]+$ ]] || {
|
|
printf 'Invalid Atlas USB snapshot marker; leaving snapshots unchanged\n' >&2
|
|
exit 2
|
|
}
|
|
|
|
exec 9>/run/lock/atlas-zfs-snapshot.lock
|
|
flock 9
|
|
if zfs list -H -t snapshot -o name "${pool}@${snapshot_name}" >/dev/null 2>&1; then
|
|
# ZFS can leave its on-demand .zfs/snapshot mounts in the host namespace
|
|
# even after the backup's private bind mounts and process have exited.
|
|
snapshot_mounts=()
|
|
snapshot_sources=()
|
|
while IFS=$'\t' read -r dataset dataset_mountpoint; do
|
|
[[ "$dataset_mountpoint" == "$mount_root" || "$dataset_mountpoint" == "$mount_root/"* ]] || continue
|
|
snapshot_mounts+=("${dataset_mountpoint}/.zfs/snapshot/${snapshot_name}")
|
|
snapshot_sources+=("${dataset}@${snapshot_name}")
|
|
done < <(zfs list -H -o name,mountpoint -s name -r "$pool")
|
|
|
|
{% raw %}
|
|
for ((index = ${#snapshot_mounts[@]} - 1; index >= 0; index--)); do
|
|
{% endraw %}
|
|
mounted_source="$(findmnt -rn -M "${snapshot_mounts[$index]}" -o SOURCE || true)"
|
|
[[ -n "$mounted_source" ]] || continue
|
|
[[ "$mounted_source" == "${snapshot_sources[$index]}" ]] || {
|
|
printf 'Unexpected source on Atlas USB snapshot mount: %s\n' \
|
|
"${snapshot_mounts[$index]}" >&2
|
|
exit 2
|
|
}
|
|
umount "${snapshot_mounts[$index]}"
|
|
done
|
|
|
|
zfs destroy -r "${pool}@${snapshot_name}"
|
|
printf 'Removed recursive Atlas USB source snapshot %s@%s after backup exit\n' \
|
|
"$pool" "$snapshot_name"
|
|
fi
|