From ca8c2854a9dc9074747839aae53bc0a9c1ee1f3b Mon Sep 17 00:00:00 2001 From: patrick Date: Fri, 22 Aug 2025 00:05:43 +0200 Subject: [PATCH] v2.04 --- miyagi-backup.sh | 136 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 123 insertions(+), 13 deletions(-) diff --git a/miyagi-backup.sh b/miyagi-backup.sh index d72e0f4..16acea2 100644 --- a/miyagi-backup.sh +++ b/miyagi-backup.sh @@ -46,6 +46,10 @@ if [[ -n "${CONFIG_FILE:-}" ]]; then PBSHOST BACKUPSTORE BACKUPSTOREPBS BACKUPEXCLUDE REPLEXCLUDE ) +if [[ "${DYNROUTE,,}" == "yes" ]]; then + REQUIRED_VARS+=(DDNS_GATEWAY) +fi + MISSING_VARS=() for var in "${REQUIRED_VARS[@]}"; do if [[ -z "${!var:-}" ]]; then @@ -77,19 +81,18 @@ get_sourcehostname() { } zfs_replace() { - local replace_detected=false - for pool in $(zpool list -H -o name); do - if zpool status "$pool" 2>/dev/null | grep -qiE "replacing|in replacing|scan: replacing"; then - log "Replace-Vorgang läuft im Pool: $pool" - replace_detected=true - fi - done + local status + status=$(zpool status) - if $replace_detected; then + if echo "$status" | grep -q 'scan: resilver in progress'; then return 0 - else - return 1 fi + + if echo "$status" | grep -qE 'replacing-[0-9]'; then + return 0 + fi + + return 1 } wait_replace() { @@ -99,7 +102,7 @@ wait_replace() { log "ZFS Replace-Vorgang erkannt – warte unbegrenzt auf Abschluss..." while true; do - if ! zfs_replace_in_progress; then + if ! zfs_replace; then log "Replace abgeschlossen nach $waited_minutes Minuten – fahre jetzt herunter." return 0 fi @@ -185,8 +188,71 @@ run_zsync() { run_remote_updates() { if [[ "${UPDATES,,}" == "yes" ]]; then log "Running updates on local system..." - apt update && apt dist-upgrade -y || log "Error during local updates" + TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S") + SNAPSHOT_TAG="pve-update-via-miyagi" + MAX_SNAPSHOTS=5 + ZFS_DATASETS=("rpool/ROOT" "rpool/pveconf") + REBOOT_FLAG="${REBOOT^^}" + LOGFILE="/var/log/proxmox_update.log" + + log_msg() { + local level="$1" + local message="$2" + local timestamp + timestamp=$(date +"%Y-%m-%d %H:%M:%S") + echo "[$timestamp] $message" + echo "[$timestamp] [$level] $message" >> "$LOGFILE" + } + + # Prüfen, ob Updates verfügbar sind + if ! apt update | tee -a "$LOGFILE" | grep -qi "upgradable"; then + log_msg "INFO" "Keine Updates verfügbar." + return + fi + + log_msg "INFO" "Updates verfügbar. Erstelle Snapshots." + + for dataset in "${ZFS_DATASETS[@]}"; do + snapshot="${dataset}@${SNAPSHOT_TAG}-${TIMESTAMP}" + log_msg "INFO" "Erstelle Snapshot: $snapshot" + zfs snapshot "$snapshot" + + # Alte Snapshots bereinigen + log_msg "INFO" "Bereinige alte Snapshots in $dataset" + old_snaps=$(zfs list -t snapshot -o name -s creation | grep "^${dataset}@${SNAPSHOT_TAG}-") + snap_count=$(echo "$old_snaps" | wc -l) + if (( snap_count > MAX_SNAPSHOTS )); then + snaps_to_delete=$(echo "$old_snaps" | head -n $((snap_count - MAX_SNAPSHOTS))) + while IFS= read -r snap; do + log_msg "INFO" "Lösche alten Snapshot: $snap" + zfs destroy "$snap" + done <<< "$snaps_to_delete" + fi + done + + # System-Upgrade + log_msg "INFO" "Starte dist-upgrade" + if ! apt dist-upgrade -y | tee -a "$LOGFILE"; then + log_msg "ERROR" "Fehler während dist-upgrade" + return 1 + fi + + log_msg "INFO" "Starte autoremove" + apt autoremove -y | tee -a "$LOGFILE" + + # Kernel-Update prüfen + if apt list --upgradable 2>/dev/null | grep -q "linux-image-"; then + log_msg "WARN" "Kernel-Update erkannt. Neustart empfohlen." + if [[ "$REBOOT_FLAG" == "YES" ]]; then + log_msg "INFO" "REBOOT=YES erkannt. System wird neugestartet." + reboot + fi + else + log_msg "INFO" "Update abgeschlossen. Kein Neustart erforderlich." + fi + + # PBS-Host-Update if [[ "${BACKUPSERVER,,}" == "yes" ]]; then log "Running updates on PBS host ($PBSHOST)..." ssh root@"$PBSHOST" apt update && ssh root@"$PBSHOST" apt dist-upgrade -y || { @@ -195,6 +261,7 @@ run_remote_updates() { else log "PBS updates skipped (BACKUPSERVER=$BACKUPSERVER)" fi + else log "Updates disabled (UPDATES=$UPDATES)" fi @@ -426,7 +493,6 @@ shutdown_now() { return fi fi - send_piggyback send_piggyback_external send_checkzfs_external @@ -550,11 +616,55 @@ wait() { sleep 60 fi } +set_dynamic_route() { + local ddns_hostname="$SOURCEHOST" + local gateway="$DDNS_GATEWAY" + local dns_server="1.1.1.1" + + if [[ -z "$ddns_hostname" || -z "$gateway" ]]; then + log "Fehler: SOURCEHOST oder DDNS_GATEWAY nicht gesetzt" + return 1 + fi + + log "Setze temporäre Route zu DNS-Server $dns_server via $gateway..." + if ! ip route | grep -q "^$dns_server"; then + ip route add "$dns_server" via "$gateway" \ + && log "Route zu $dns_server via $gateway gesetzt" \ + || log "Fehler beim Setzen der DNS-Route" + else + log "Route zu $dns_server bereits vorhanden" + fi + + log "Löse IP von $ddns_hostname über DNS $dns_server..." + CURRENT_IP=$(dig +short @"$dns_server" "$ddns_hostname") + + if [[ -z "$CURRENT_IP" ]]; then + log "Fehler: Konnte IP für $ddns_hostname nicht auflösen" + return 1 + fi + + log "Ermittelte IP: $CURRENT_IP – setze Route via $gateway..." + if ! ip route | grep -q "^$CURRENT_IP"; then + ip route add "$CURRENT_IP" via "$gateway" \ + && log "Route erfolgreich gesetzt: $CURRENT_IP via $gateway" \ + || log "Fehler beim Setzen der Route zu $CURRENT_IP" + else + log "Route zu $CURRENT_IP bereits vorhanden" + fi +} # Main execution: if [[ $# -eq 0 ]]; then if [[ -n "$CONFIG_FILE" ]]; then wait log "Running full backup using configuration file: $CONFIG_FILE" + + if [[ "${DYNROUTE,,}" == "yes" ]]; then + log "DYNROUTE ist aktiviert – setze dynamische Route für $SOURCEHOST..." + set_dynamic_route + else + log "DYNROUTE ist deaktiviert oder nicht gesetzt." + fi + write_zsync_config run_zsync