#!/bin/sh # Managed by Ansible: HomeLab PBS backup audit (L0 freshness) set -eu LOG_FILE="{{ backup_audit_log_file }}" METRICS_DIR="{{ backup_audit_metrics_dir }}" METRICS_FILE="$METRICS_DIR/homelab_backup_audit_pbs.prom" METRICS_TMP=$(mktemp "$METRICS_FILE.XXXXXX") STATUS=OK NOW_EPOCH=$(date +%s) trap 'rm -f "$METRICS_TMP"' EXIT publish_metrics() { chmod 0644 "$METRICS_TMP" mv "$METRICS_TMP" "$METRICS_FILE" } ts() { date '+%Y-%m-%dT%H:%M:%S%z'; } log() { echo "[$(ts)] [pbs] $*" | tee -a "$LOG_FILE"; } get_latest_snapshot() { pvesm list pbs --vmid "$1" 2>/dev/null \ | tail -n +2 \ | awk '{print $1}' \ | sort -t/ -k4 \ | tail -1 } {% for entry in backup_audit_pbs_vmids %} audit_vmid_{{ entry.vmid }}() { vmid={{ entry.vmid }} max_age={{ entry.max_age_hours }} latest=$(get_latest_snapshot "$vmid") if [ -z "$latest" ]; then log "FAIL L0: vmid $vmid — no snapshots in PBS" printf 'homelab_backup_audit_snapshot_age_hours{profile="pbs",vmid="%s"} -1\n' "$vmid" >> "$METRICS_TMP" printf 'homelab_backup_audit_snapshot_success{profile="pbs",vmid="%s"} 0\n' "$vmid" >> "$METRICS_TMP" STATUS=FAIL return fi ts_str=$(printf '%s' "$latest" | sed -n 's#.*/\([0-9T:Z-]*\)$#\1#p') snap_epoch=$(date -d "$ts_str" +%s 2>/dev/null || echo 0) age_hours=$(( (NOW_EPOCH - snap_epoch) / 3600 )) if [ "$age_hours" -gt "$max_age" ]; then log "FAIL L0: vmid $vmid — latest snapshot age ${age_hours}h > ${max_age}h (snapshot: $ts_str)" printf 'homelab_backup_audit_snapshot_success{profile="pbs",vmid="%s"} 0\n' "$vmid" >> "$METRICS_TMP" STATUS=FAIL else log "OK L0: vmid $vmid — latest snapshot age ${age_hours}h" printf 'homelab_backup_audit_snapshot_success{profile="pbs",vmid="%s"} 1\n' "$vmid" >> "$METRICS_TMP" fi printf 'homelab_backup_audit_snapshot_age_hours{profile="pbs",vmid="%s"} %s\n' "$vmid" "$age_hours" >> "$METRICS_TMP" } audit_vmid_{{ entry.vmid }} {% endfor %} if [ "$STATUS" = "OK" ]; then log "AUDIT PASSED" printf 'homelab_backup_audit_success{profile="pbs"} 1\n' >> "$METRICS_TMP" printf 'homelab_backup_audit_timestamp_seconds{profile="pbs"} %s\n' "$NOW_EPOCH" >> "$METRICS_TMP" publish_metrics exit 0 else log "AUDIT FAILED" printf 'homelab_backup_audit_success{profile="pbs"} 0\n' >> "$METRICS_TMP" printf 'homelab_backup_audit_timestamp_seconds{profile="pbs"} %s\n' "$NOW_EPOCH" >> "$METRICS_TMP" publish_metrics exit 1 fi