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>
94 lines
3.0 KiB
Bash
Executable File
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 "$@"
|