vigilar/scripts/backup.sh
Aaron D. Lee ebcc49b474 Add kiosk setup and deployment scripts (Phases 5 + 9)
Phase 5 — RPi Kiosk:
- setup_kiosk.sh: full RPi OS Lite setup (X11, Chromium kiosk mode,
  auto-login, DPMS disabled, GPU memory split, screen rotation)
- kiosk.service: systemd unit for reliable auto-start
- update_kiosk.sh: reconfigure URL/rotation/resolution without re-setup
- Handles both Bullseye and Bookworm RPi OS versions

Phase 9 — Hardening + Deployment:
- install.sh: full server setup (apt/pacman, vigilar user, venv,
  directories, permissions, mosquitto config, systemd units)
- gen_cert.sh: TLS cert via mkcert or openssl fallback
- gen_vapid_keys.sh: VAPID keys for Web Push notifications
- setup_nut.sh: NUT configuration with USB UPS auto-detection
- backup.sh: SQLite snapshot + config archive, cron-ready
- uninstall.sh: clean removal with data preservation option
- vigilar.service: hardened systemd unit (ProtectSystem, NoNewPrivileges,
  PrivateTmp, syscall filtering)
- vigilar-mosquitto.conf: localhost-only MQTT broker config

All scripts idempotent, bash -n validated, support Debian + Arch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 23:25:03 -04:00

94 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Vigilar — Backup script
# Backs up SQLite database, config, and secrets to a dated tar.gz archive.
# Suitable for cron: 0 3 * * * /opt/vigilar/scripts/backup.sh
DATA_DIR="/var/vigilar/data"
CONFIG_DIR="/etc/vigilar"
BACKUP_DEST="${VIGILAR_BACKUP_DIR:-/var/vigilar/backups}"
RETENTION_DAYS="${VIGILAR_BACKUP_RETENTION_DAYS:-30}"
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
ARCHIVE_NAME="vigilar-backup-${TIMESTAMP}.tar.gz"
info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; }
ok() { printf '\033[1;32m[ OK ]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; }
fail() { printf '\033[1;31m[FAIL]\033[0m %s\n' "$*" >&2; exit 1; }
main() {
info "=== Vigilar Backup ==="
# Create backup destination
sudo mkdir -p "$BACKUP_DEST"
# Collect files to back up
local items=()
# SQLite database
if [[ -d "$DATA_DIR" ]]; then
# Use sqlite3 .backup for a consistent snapshot if sqlite3 is available
local db_file="${DATA_DIR}/vigilar.db"
if [[ -f "$db_file" ]] && command -v sqlite3 &>/dev/null; then
local db_snapshot="/tmp/vigilar-backup-${TIMESTAMP}.db"
info "Creating consistent database snapshot"
sqlite3 "$db_file" ".backup '${db_snapshot}'"
items+=("$db_snapshot")
elif [[ -f "$db_file" ]]; then
warn "sqlite3 not found, copying database file directly (may be inconsistent if running)"
items+=("$db_file")
fi
# Also back up any WAL/SHM files
for f in "${db_file}-wal" "${db_file}-shm"; do
if [[ -f "$f" ]]; then
items+=("$f")
fi
done
else
warn "Data directory ${DATA_DIR} not found, skipping database"
fi
# Config directory (includes secrets, certs, toml)
if [[ -d "$CONFIG_DIR" ]]; then
items+=("$CONFIG_DIR")
else
warn "Config directory ${CONFIG_DIR} not found, skipping config"
fi
if [[ ${#items[@]} -eq 0 ]]; then
fail "Nothing to back up"
fi
# Create archive
local archive_path="${BACKUP_DEST}/${ARCHIVE_NAME}"
info "Creating archive: ${archive_path}"
sudo tar -czf "$archive_path" "${items[@]}" 2>/dev/null
# Secure the backup (contains secrets)
sudo chmod 0600 "$archive_path"
sudo chown root:root "$archive_path"
# Clean up temp db snapshot
if [[ -f "/tmp/vigilar-backup-${TIMESTAMP}.db" ]]; then
rm -f "/tmp/vigilar-backup-${TIMESTAMP}.db"
fi
local size
size="$(du -h "$archive_path" | cut -f1)"
ok "Backup complete: ${archive_path} (${size})"
# Prune old backups
if [[ "$RETENTION_DAYS" -gt 0 ]]; then
info "Pruning backups older than ${RETENTION_DAYS} days"
local pruned
pruned="$(sudo find "$BACKUP_DEST" -name 'vigilar-backup-*.tar.gz' -mtime +"$RETENTION_DAYS" -delete -print | wc -l)"
if [[ "$pruned" -gt 0 ]]; then
ok "Pruned ${pruned} old backup(s)"
fi
fi
}
main "$@"