munin/scripts/backup.sh
Thomas Adamek 466f1e40af Workspaces, Änderungshistorie, Papierkorb, Nutzungsübersicht, Hilfe
Umsetzung der Ausbaustufen 2.1, 3.6, 3.8, 3.9, 4.1, 4.2, 4.4, 4.6,
5.1–5.4 (Details in AUSBAUSTUFEN.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 07:44:52 +02:00

79 lines
3.3 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Sichert die zentrale Kontroll-Datenbank und jede Workspace-Datei einzeln.
#
# sqlite3 .backup ist dafür gebaut, auch während der Server im WAL-Modus
# schreibt (siehe AUSBAUSTUFEN.md 4.4 und README.md "Datensicherung") — eine
# einfache Dateikopie wäre hier riskant.
#
# Jede Sicherung landet in einem eigenen, zeitgestempelten Ordner. Da jeder
# Workspace seine eigene Datei ist, lässt sich später auch nur eine einzelne
# Abteilung gezielt wiederherstellen, ohne die übrigen anzufassen.
#
# ── Aufruf ───────────────────────────────────────────────────────────────────
#
# scripts/backup.sh [Datenverzeichnis] [Sicherungsverzeichnis]
#
# Beide Pfade lassen sich auch über die Umgebungsvariablen DATA_DIR und
# BACKUP_DIR setzen (Vorgaben: "data" und "backups") — praktisch für einen
# Cronjob, der ohnehin feste Pfade mitgibt.
#
# ── Beispiel für Cron ────────────────────────────────────────────────────────
#
# Täglich um 3 Uhr, mit 14 Tagen Aufbewahrung:
#
# 0 3 * * * DATA_DIR=/srv/munin/data BACKUP_DIR=/srv/backups RETENTION_DAYS=14 \
# /srv/munin/scripts/backup.sh >> /var/log/munin-backup.log 2>&1
#
# Ohne RETENTION_DAYS bleibt jede Sicherung liegen — lieber zu viel als
# versehentlich eine noch gebrauchte Sicherung verlieren.
#
# ── Wiederherstellen ─────────────────────────────────────────────────────────
#
# Server stoppen, die gewünschte .db-Datei aus einem Sicherungsordner an ihren
# Platz unter DATA_DIR zurückkopieren, Server wieder starten. Für einen
# einzelnen Workspace reicht dessen Datei unter workspaces/ — die
# Kontroll-Datenbank bleibt davon unberührt.
set -euo pipefail
datenverzeichnis="${1:-${DATA_DIR:-data}}"
sicherungsverzeichnis="${2:-${BACKUP_DIR:-backups}}"
stempel="$(date +%Y-%m-%dT%H-%M-%S)"
ziel="$sicherungsverzeichnis/$stempel"
if ! command -v sqlite3 >/dev/null 2>&1; then
echo "sqlite3 ist nicht installiert — ohne dieses Werkzeug keine sichere Sicherung im laufenden Betrieb." >&2
exit 1
fi
if [ ! -d "$datenverzeichnis" ]; then
echo "Datenverzeichnis $datenverzeichnis existiert nicht." >&2
exit 1
fi
mkdir -p "$ziel/workspaces"
sichern() {
sqlite3 "$1" ".backup '$2'"
}
if [ -f "$datenverzeichnis/control.db" ]; then
sichern "$datenverzeichnis/control.db" "$ziel/control.db"
echo "control.db gesichert"
else
echo "Warnung: $datenverzeichnis/control.db nicht gefunden — übersprungen." >&2
fi
anzahl=0
for datei in "$datenverzeichnis"/workspaces/*.db; do
[ -e "$datei" ] || continue # kein Workspace vorhanden (glob lief leer)
sichern "$datei" "$ziel/workspaces/$(basename "$datei")"
anzahl=$((anzahl + 1))
done
echo "$anzahl Workspace-Datei(en) gesichert nach $ziel"
# Alte Sicherungen aufräumen, falls eine Aufbewahrungsfrist gesetzt ist.
if [ -n "${RETENTION_DAYS:-}" ]; then
find "$sicherungsverzeichnis" -mindepth 1 -maxdepth 1 -type d -mtime "+$RETENTION_DAYS" -print -exec rm -rf {} \;
fi