From df36126617c709b927458927f3d0caa86a9b2869 Mon Sep 17 00:00:00 2001 From: Cayce Date: Wed, 28 Oct 2026 21:09:59 +0000 Subject: [PATCH] =?UTF-8?q?backup:=20freshness=20check=20=E2=80=94=20alert?= =?UTF-8?q?=20when=20last=20backup=20is=20older=20than=2026h=20(Tanda=20B,?= =?UTF-8?q?=20point=204)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /usr/local/bin/cayce-check-backup-freshness (from deploy/backup/check-freshness.sh): exits 1 if the newest /var/backups/cayce/YYYY-MM-DD/ dir has mtime older than 26h, or if no backups exist while the age recipient IS configured (backups expected). Info-exit-0 when backups have never been configured. Not attached to a timer (only cayce-backup.timer was authorized); documented for manual or cron use. Verified: fresh dir => OK 0h exit 0; dir with 2-day mtime => ALERT 48h exit 1; no-dir + recipient => ALERT; no-dir + no-recipient => INFO. --- deploy/backup/check-freshness.sh | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100755 deploy/backup/check-freshness.sh diff --git a/deploy/backup/check-freshness.sh b/deploy/backup/check-freshness.sh new file mode 100755 index 0000000..012ddc1 --- /dev/null +++ b/deploy/backup/check-freshness.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# check-backup-freshness — alert if the newest backup is older than 26h. +# +# Exit 0 = fresh (or no backups ever made and NONE expected yet) +# Exit 1 = stale: last backup dir older than MAX_HOURS, or no dir at all +# while the age recipient is configured (backups should exist). +# +# Wire it anywhere you like (cron, another timer, or run manually from the +# Mac after the daily pull). Not attached to any timer by itself — the only +# authorized timer in Tanda B is cayce-backup.timer. +set -euo pipefail + +BACKUP_ROOT="/var/backups/cayce" +MAX_HOURS=26 +RECIPIENT_FILE="/etc/cayce-backup/age-recipient.pub" + +newest="$(find "$BACKUP_ROOT" -mindepth 1 -maxdepth 1 -type d -name "2*-*-*" 2>/dev/null | sort | tail -1 || true)" + +if [[ -z "$newest" ]]; then + if [[ -f "$RECIPIENT_FILE" ]]; then + echo "ALERT: no backups exist although the age recipient is configured" >&2 + exit 1 + fi + echo "INFO: no backups yet (age recipient not configured) — nothing to alert" + exit 0 +fi + +hours=$(( ( $(date +%s) - $(stat -c %Y "$newest") ) / 3600 )) +if (( hours > MAX_HOURS )); then + echo "ALERT: last backup ($newest) is ${hours}h old (max ${MAX_HOURS}h)" >&2 + exit 1 +fi +echo "OK: last backup ($newest) is ${hours}h old"