From 328936748ecd68dd1bebab950214d8208939537b Mon Sep 17 00:00:00 2001 From: Hartmut Bauer Date: Sun, 13 Apr 2025 02:36:47 +0200 Subject: [PATCH] Restore, List Archives, Content --- calvados.sh | 3 ++ hamiller.sh | 2 +- main.inc.sh | 97 +++++++++++++++++++++++++++++++++++++++-------------- main.sh | 71 ++++++++++++++++++--------------------- nathan.sh | 2 +- synology.sh | 2 +- test.sh | 12 +++++++ 7 files changed, 123 insertions(+), 66 deletions(-) create mode 100644 calvados.sh diff --git a/calvados.sh b/calvados.sh new file mode 100644 index 0000000..034550d --- /dev/null +++ b/calvados.sh @@ -0,0 +1,3 @@ +#!/usr/bin/eval bash + +#NAS_ROOT=/Users/hb/mnt/nas/backups diff --git a/hamiller.sh b/hamiller.sh index 72340d0..2181247 100755 --- a/hamiller.sh +++ b/hamiller.sh @@ -1,7 +1,7 @@ #!/usr/bin/eval bash -NAS_ROOT=/var/srv/nas/backups +#NAS_ROOT=/var/srv/nas/backups BACKUP_TARGET=/var/docker/tmp NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY" diff --git a/main.inc.sh b/main.inc.sh index 52fd7c1..4ad439b 100755 --- a/main.inc.sh +++ b/main.inc.sh @@ -1,6 +1,15 @@ HOST_NAME=$(hostname -s) DAY=$(date +%u) # MO == 1 +NAS_MOUNT_POINT="$(realpath $HERE/../../..)" # Server/bin/backup +NAS_ROOT="$NAS_MOUNT_POINT/backups" + +LOG_FILE_PATH="$NAS_MOUNT_POINT/Server/log/backup" +log_file_name="$LOG_FILE_PATH/$HOST_NAME-$(date '+%Y-%m-%d_%H%M')" +LOG_FILE="${log_file_name}.log" + +RESTORE_PATH="$NAS_MOUNT_POINT/Server/restore" + BACKUP_MASTER_CHECK="/var/docker/vol/proxy" NAS_HOSTNAME=synology @@ -117,6 +126,19 @@ dump_postgresql() { # ----- helper functions ----- +# Für Backup und Export muss das Script mit root-Rechten +# ausgeführt werden. +# +check_root() { + if [ "$(id -u)" -ne 0 ]; then + log $ERROR "$ERR script must be run as superuser." + echo "****" + echo "***** script must be run as superuser! *****" + echo "****" + exit 100 + fi +} + start_docker() { log $DEBUG "$DBG start_docker()" log $DEBUG "$DBG > \$DOCKER up -d" @@ -430,8 +452,8 @@ backup_daily() { is_error $? mail_log $INFO ">>>>>>>>>> end of auto backup" - send_mail_log "Daily Backup" fix_acls + send_mail_log "Daily Backup" # ggf. weekly backup starten (z.ZT. nur auf NAS) if [ $HAS_WEEKLY -a $WEEKLY_DAY -eq $DAY ]; then @@ -449,8 +471,8 @@ backup_weekly() { is_error $? mail_log $INFO ">>>>>>>>>> end of auto backup" - send_mail_log "Weekly Backup" fix_acls + send_mail_log "Weekly Backup" } # ----- integrity ----- @@ -475,21 +497,50 @@ test_integrity() { # Restore aus Archiv # -# Wird nach pwd ausgegeben! +# Wird nach $RESTORE_PATH ausgegeben und mit root-Rechten +# auf der NAS ausgeführt. # -# $1 - Archiv, ggf. mit Pfad +# $1 - Archiv, mit Pfad ab $NAS_ROOT # $2 ff. - zurückzusichernde Dateien/Verzeichnisse # -# returns 0 for success, 1 otherwise -# restore() { log $DEBUG "$DBG restore( $@ )" local archive=$1 - shift 1 - log $DEBUG "$DBG > gpg --batch --decrypt --passphrase xxxx \"$archive\" | tar -xzv $@" - gpg --batch --decrypt --passphrase $PASSPHRASE "$archive" 2>>$LOG_FILE | tar -xzv $@ >/dev/null 2>>$LOG_FILE + shift + echo "--- Restore ---" + echo "--- archive: $archive" + echo "--- files: $@" + echo "--- to: $RESTORE_PATH" + echo + echo "Restore runs on NAS, see e-mail" + echo + run_script_remote $NAS_IP "$NAS_SCRIPT --rx $archive $@" +} + +# Restore +# +# Beim Restore einzelner Dateien wird nur die ownership der Datei +# restored, nicht die des Pfades zur Datei! +# +do_restore() { + if [ "$HOST_NAME" != "$NAS_HOSTNAME" ]; then + restore $@ + exit + fi + + local archive=$1 + shift + mail_log $INFO ">>>>>>>>>> restore $VER for $HOST_NAME <<<<<<<<<<" + mail_log $INFO ">>> restore from: $archive" + mail_log $INFO ">>> files : $@" + mail_log $INFO ">>> restore to : $RESTORE_PATH" + mail_log $INFO ">>> log file : $LOG_FILE" + log $DEBUG "$DBG > gpg --batch --decrypt --passphrase xxxx \"$NAS_ROOT/${archive/#\//}\" | tar -xzv --directory $RESTORE_PATH $@" + gpg --batch --decrypt --passphrase $PASSPHRASE "$NAS_ROOT/${archive/#\//}" 2>>$LOG_FILE | tar -xzv --directory $RESTORE_PATH $@ >>$LOG_FILE 2>&1 check_pipe_rc ${PIPESTATUS[@]} - return $? + is_error $? + mail_log $INFO ">>>>>>>>>> end of restore" + send_mail_log "Restore" } # ----- archive content ------ @@ -511,41 +562,37 @@ create_list() { # Liste der Archives auf stdout ausgeben # -# Zeigt alle Archive incl. Verzeichnis (ohne $1) an +# Zeigt alle Archive incl. Verzeichnis (ohne $NAS_ROOT) an # # z.B. -# $1 = /volume1/nfs/backups +# $NAS_ROOT = /volume1/nfs/backups # ... # /daily/synology/backup.3/volume1-nfs-Server.tgz.gpg # /weekly/synology/volume1-media-books.tgz.gpg # -# $1 - Verzeichnis unter dem alle Backups liegen -# # returns 0 for success, 1 otherwise # list_archives() { - log $DEBUG "$DBG list_archives( $@ )" + log $DEBUG "$DBG list_archives()" local target=$1 - local targ=${target//\//\\\/} # slashes escapen - log $DEBUG "$DBG > find \"$target\" -type f -name \"*.$EXT\" | grep \"${HOST_NAME}/\" | sed -E \"s/^$targ//\"" - find "$target" -type f -name "*.$EXT" 2>>$LOG_FILE | grep "${HOST_NAME}/" 2>>$LOG_FILE | sed -E "s/^$targ//" 2>>$LOG_FILE + local targ=${NAS_ROOT//\//\\\/} # slashes escapen + log $DEBUG "$DBG > find \"$NAS_ROOT\" -type f -name \"*.$EXT\" | sed -E \"s/^$targ//\"" + find "$NAS_ROOT" -type f -name "*.$EXT" 2>>$LOG_FILE | sed -E "s/^$targ//" 2>>$LOG_FILE check_pipe_rc ${PIPESTATUS[@]} return $? } -# Inhalt des Archivs $2 auf stdout ausgeben +# Inhalt des Archivs $1 auf stdout ausgeben # -# $1 - Verzeichnis unter dem alle Backups liegen -# $2 - Archiv-Datei mit Pfad ab $1 +# $1 - Archiv-Datei mit Pfad ab $NAS_ROOT # # returns 0 for success, 1 otherwise # list_archive_content() { log $DEBUG "$DBG list_archive_content( $@ )" - local root=$1 - local archive=$2 - log $DEBUG "$DBG > cat \"$root/${archive/#\//}.$LIST_EXT\"" - cat "$root/${archive/#\//}.$LIST_EXT" 2>>$LOG_FILE + local archive=$1 + log $DEBUG "$DBG > cat \"$NAS_ROOT/${archive/#\//}.$LIST_EXT\"" + cat "$NAS_ROOT/${archive/#\//}.$LIST_EXT" 2>>$LOG_FILE } # ----- export ----- diff --git a/main.sh b/main.sh index 313b18a..445841b 100755 --- a/main.sh +++ b/main.sh @@ -3,37 +3,28 @@ # entrypoint for all actions # -VER="2.1.0" - -show_help() { - echo "usage: $0 options" - echo " -d, --daily start daily backup on local machine" - echo " -w, --weekly start weekly backup on local machine" - echo " --list list archives" - echo ' --content ' - echo " show contents of archive" - echo ' -r, --restore ' - echo " restore files from archive to pwd" - echo " -h, -?. --help show this help" - echo " " - echo " Script muss auf dem jeweiligen Server ausgeführt werden (ggf. via ssh)." - echo " " -} - -# -# Script muss unter root bzw. sudo laufen, sonst gibt es jede Menge Probleme -# mit Zugriff auf die diversen Verzeichnisse. -# -if [ "$(id -u)" -ne 0 ]; then - echo "**" - echo "** ERROR: script has to be run as superuser!" - echo "**" - exit 100 -fi +VER="2.1.2" HERE=$(dirname "$0") THIS_SCRIPT=$0 +show_help() { + echo "Server Backup $VER" + echo "usage: $0 options" + echo " -d, --daily start daily backup on local machine" + echo " -w, --weekly start weekly backup on local machine" + echo " -e, --export export backups to USB-HDD" + echo " -l, --list list archives" + echo ' -c, --content ' + echo " show contents of archive (path from $NAS_ROOT)" + echo ' -r, --restore ' + echo " restore files from archive to $RESTORE_PATH" + echo " -h, -?. --help show this help" + echo " " + echo " -d, -w, -e must be run as superuser." + echo " " +} + if [ -f $HERE/main.inc.sh ]; then . $HERE/main.inc.sh else @@ -56,9 +47,6 @@ else exit 102 fi -LOG_FILE_PATH="$(realpath $HERE/../../../log/backup)" -log_file_name="$LOG_FILE_PATH/$HOST_NAME-$(date '+%Y-%m-%d_%H%M')" -LOG_FILE="${log_file_name}.log" file= archive= @@ -71,29 +59,29 @@ while :; do ;; -d|--daily) MAIL_LOG_FILE="${log_file_name}.auto.log" + check_root backup_daily break ;; -w|--weekly) MAIL_LOG_FILE="${log_file_name}.auto.log" + check_root backup_weekly break ;; -e|--export) MAIL_LOG_FILE="${log_file_name}.auto.log" + check_root export_backups break ;; - --list) - list_archives "$NAS_ROOT/daily/$HOST_NAME" - if [ -d "$NAS_ROOT/weekly/$HOST_NAME" ]; then - list_archives "$NAS_ROOT/weekly/$HOST_NAME" - fi + -l|--list) + list_archives break; ;; - --content) + -c|--content) if [ "$2" ]; then - list_archive_content "$NAS_ROOT" "$2" + list_archive_content "$2" else echo 'ERROR: "--content" requires a non-empty option argument.' fi @@ -102,13 +90,20 @@ while :; do -r|--restore) if [ "$2" ]; then archive=$2 - shift + shift 2 restore "$archive" "$@" else echo 'ERROR: "--restore" requires a non-empty option argument.' fi break ;; + --rx) + MAIL_LOG_FILE="${log_file_name}.auto.log" + check_root + shift + do_restore $@ + break + ;; --) # End of all options. shift break diff --git a/nathan.sh b/nathan.sh index a24a249..573be54 100755 --- a/nathan.sh +++ b/nathan.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -NAS_ROOT=/var/srv/nas/backups +#NAS_ROOT=/var/srv/nas/backups DOCKER_ROOT=/var/docker BACKUP_TARGET=$DOCKER_ROOT/tmp NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY" diff --git a/synology.sh b/synology.sh index 09f60cc..00101a5 100755 --- a/synology.sh +++ b/synology.sh @@ -1,6 +1,6 @@ #!/usr/bin/eval bash -NAS_ROOT=/volume1/nfs/backups +#NAS_ROOT=/volume1/nfs/backups HAS_WEEKLY=true backup_daily1() { diff --git a/test.sh b/test.sh index a277fd4..a06644b 100755 --- a/test.sh +++ b/test.sh @@ -1,5 +1,17 @@ #!/usr/bin/env bash +fn() { + echo "all: $@" + echo "#1: $1" + shift + echo "rest: $@" +} + + +fn eins zwei drei +exit + + if [ "$(id -u)" -ne 0 ]; then echo "**" echo "** ERROR: script has to be run as superuser!"