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>
79 lines
3.3 KiB
Bash
Executable file
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
|