101 lines
2.8 KiB
Bash
Executable File
101 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
HOMELAB_STATE_DIR="${HOMELAB_STATE_DIR:-${XDG_DATA_HOME:-${HOME}/.local/share}/homelab}"
|
|
GITEA_BACKUP_DIR="${LAB_GITEA_BACKUP_DIR:-/home/jv/backups/gitea}"
|
|
GITEA_DRILL_DIR="${GITEA_RESTORE_DRILL_DIR:-/home/jv/backups/gitea-restore-drills}"
|
|
TOFU_BACKUP_DIR="${HOMELAB_TOFU_STATE_BACKUP_DIR:-${HOMELAB_STATE_DIR}/tofu-state-backups}"
|
|
PIHOLE_CONFIG_FILES="${PIHOLE_CONFIG_FILES:-infra/rpi-services/adlists.txt infra/rpi-services/local-dns-records.txt infra/rpi-services/cname-records.txt infra/rpi-services/static-dhcp-hosts.txt}"
|
|
MAX_GITEA_AGE_HOURS="${LAB_BACKUP_MAX_GITEA_AGE_HOURS:-36}"
|
|
MAX_TOFU_AGE_HOURS="${LAB_BACKUP_MAX_TOFU_AGE_HOURS:-168}"
|
|
MAX_DRILL_AGE_HOURS="${LAB_BACKUP_MAX_DRILL_AGE_HOURS:-744}"
|
|
|
|
failures=0
|
|
warnings=0
|
|
|
|
section() {
|
|
printf '\n== %s ==\n' "$1"
|
|
}
|
|
|
|
latest_file() {
|
|
local dir="$1"
|
|
local pattern="$2"
|
|
|
|
if [ -d "$dir" ]; then
|
|
find "$dir" -maxdepth 1 -type f -name "$pattern" -printf '%T@ %p\n' 2>/dev/null |
|
|
sort -n |
|
|
tail -1 |
|
|
sed 's/^[^ ]* //'
|
|
fi
|
|
}
|
|
|
|
file_age_hours() {
|
|
local path="$1"
|
|
python3 - "$path" <<'PY'
|
|
import os
|
|
import sys
|
|
import time
|
|
|
|
path = sys.argv[1]
|
|
age = int((time.time() - os.path.getmtime(path)) / 3600)
|
|
print(age)
|
|
PY
|
|
}
|
|
|
|
check_latest() {
|
|
local label="$1"
|
|
local dir="$2"
|
|
local pattern="$3"
|
|
local max_age_hours="$4"
|
|
local severity="${5:-fail}"
|
|
local latest
|
|
local age_hours
|
|
|
|
latest="$(latest_file "$dir" "$pattern" || true)"
|
|
printf '%-30s ' "$label"
|
|
if [ -z "$latest" ]; then
|
|
printf '%s - missing in %s\n' "$severity" "$dir"
|
|
if [ "$severity" = "fail" ]; then
|
|
failures=$((failures + 1))
|
|
else
|
|
warnings=$((warnings + 1))
|
|
fi
|
|
return 0
|
|
fi
|
|
|
|
age_hours="$(file_age_hours "$latest")"
|
|
if [ "$age_hours" -le "$max_age_hours" ]; then
|
|
printf 'ok - age=%sh path=%s\n' "$age_hours" "$latest"
|
|
else
|
|
printf '%s - age=%sh max=%sh path=%s\n' "$severity" "$age_hours" "$max_age_hours" "$latest"
|
|
if [ "$severity" = "fail" ]; then
|
|
failures=$((failures + 1))
|
|
else
|
|
warnings=$((warnings + 1))
|
|
fi
|
|
fi
|
|
}
|
|
|
|
section "Backup Freshness"
|
|
check_latest "Gitea backup" "$GITEA_BACKUP_DIR" 'gitea-*.zip' "$MAX_GITEA_AGE_HOURS" fail
|
|
check_latest "OpenTofu state backup" "$TOFU_BACKUP_DIR" 'tofu-state-*.tgz' "$MAX_TOFU_AGE_HOURS" warn
|
|
check_latest "Restore drill report" "$GITEA_DRILL_DIR" 'restore-drill-*.txt' "$MAX_DRILL_AGE_HOURS" warn
|
|
|
|
section "Repo Managed Pi-hole Inputs"
|
|
for file in $PIHOLE_CONFIG_FILES; do
|
|
printf '%-30s ' "$file"
|
|
if [ -s "$file" ]; then
|
|
printf 'ok\n'
|
|
else
|
|
printf 'warn - missing or empty\n'
|
|
warnings=$((warnings + 1))
|
|
fi
|
|
done
|
|
|
|
section "Summary"
|
|
printf 'failures=%s warnings=%s\n' "$failures" "$warnings"
|
|
|
|
if [ "$failures" -gt 0 ]; then
|
|
exit 1
|
|
fi
|