Systemsicherung at und ppa s erweitert
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
#!/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."
|
||||
Reference in New Issue
Block a user