Files
datensicherung_rsync/system-sicherung.sh
T

118 lines
3.1 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -Eeuo pipefail
DEST_BASE="/run/media/hans/usbsicherung/jacboy_sicherung/system_sicherung"
HOST="$(hostname -s)"
STAMP="$(date +%F_%H-%M-%S)"
TARGET_DIR="${DEST_BASE}/${HOST}/${STAMP}"
LATEST_LINK="${DEST_BASE}/${HOST}/latest"
LOG_DIR="${DEST_BASE}/${HOST}/logs"
LOG_FILE="${LOG_DIR}/netzwerk-backup-${STAMP}.log"
KEEP=20
# Quellen
WG_SRC="/etc/wireguard"
NM_SRC="/etc/NetworkManager/system-connections"
APT_SOURCES_LIST="/etc/apt/sources.list"
APT_SOURCES_D="/etc/apt/sources.list.d"
APT_TRUSTED_D="/etc/apt/trusted.gpg.d"
APT_KEYRINGS="/etc/apt/keyrings"
log() {
local msg="[$(date +%F\\ %T)] $*"
echo "${msg}"
mkdir -p "${LOG_DIR}"
echo "${msg}" >> "${LOG_FILE}"
}
fail() {
log "FEHLER: $*"
exit 1
}
# Root nötig, weil /etc/* und ggf. restriktive Rechte
if [[ ${EUID} -ne 0 ]]; then
fail "Dieses Skript muss mit sudo oder als root ausgeführt werden."
fi
# Ziel prüfen
if [[ ! -d "${DEST_BASE}" ]]; then
fail "Zielbasis ${DEST_BASE} existiert nicht oder ist nicht gemountet."
fi
if [[ ! -w "${DEST_BASE}" ]]; then
fail "Zielbasis ${DEST_BASE} ist nicht beschreibbar."
fi
mkdir -p "${TARGET_DIR}" "${LOG_DIR}"
RSYNC_OPTS=(
-aHAX
--numeric-ids
--delete
--info=stats2,progress2
--human-readable
--partial
)
if [[ -L "${LATEST_LINK}" ]] && [[ -d "$(readlink -f "${LATEST_LINK}")" ]]; then
RSYNC_OPTS+=(--link-dest="$(readlink -f "${LATEST_LINK}")")
log "Verwende link-dest: $(readlink -f "${LATEST_LINK}")"
else
log "Kein vorheriger Snapshot gefunden es wird ein vollständiger Lauf erstellt."
fi
backup_tree() {
local src="$1"
local name="$2"
if [[ -d "${src}" ]]; then
log "Sichere Verzeichnis ${src} -> ${TARGET_DIR}/${name}/"
rsync "${RSYNC_OPTS[@]}" "${src}/" "${TARGET_DIR}/${name}/" | tee -a "${LOG_FILE}"
else
log "Quelle (Verzeichnis) ${src} existiert nicht wird übersprungen."
fi
}
backup_file() {
local src="$1"
local name="$2"
if [[ -f "${src}" ]]; then
log "Sichere Datei ${src} -> ${TARGET_DIR}/${name}"
mkdir -p "$(dirname "${TARGET_DIR}/${name}")"
rsync "${RSYNC_OPTS[@]}" "${src}" "${TARGET_DIR}/${name}" | tee -a "${LOG_FILE}"
else
log "Quelle (Datei) ${src} existiert nicht wird übersprungen."
fi
}
# WireGuard & NetworkManager
backup_tree "${WG_SRC}" "wireguard"
backup_tree "${NM_SRC}" "networkmanager-system-connections"
# APT: sources und Keys
backup_file "${APT_SOURCES_LIST}" "apt/sources.list"
backup_tree "${APT_SOURCES_D}" "apt/sources.list.d"
backup_tree "${APT_TRUSTED_D}" "apt/trusted.gpg.d"
backup_tree "${APT_KEYRINGS}" "apt/keyrings"
# latest-Link aktualisieren
ln -sfn "${TARGET_DIR}" "${LATEST_LINK}"
log "latest-Link zeigt jetzt auf ${TARGET_DIR}"
# Rotation
cd "${DEST_BASE}/${HOST}"
SNAPS=(20*/)
if (( ${#SNAPS[@]} > KEEP )); then
log "Rotationslauf: ${#SNAPS[@]} Snapshots vorhanden, KEEP=${KEEP}."
ls -1dt 20*/ | tail -n +$((KEEP + 1)) | while read -r old; do
log "Lösche alten Snapshot: ${old}"
rm -rf -- "${old}"
done
else
log "Keine Rotation nötig. Snapshots vorhanden: ${#SNAPS[@]}"
fi
log "Netzwerk- und APT-Konfigurationsbackup abgeschlossen."