3 Commits
Author SHA1 Message Date
Hartmut Bauer 328936748e Restore, List Archives, Content 2025-04-13 02:36:47 +02:00
Hartmut Bauer ab61e0e916 Fix log+backup acls 2025-04-13 00:10:00 +02:00
Hartmut Bauer 80c5bb0ff0 Release 2.1.0 2025-04-11 23:03:47 +02:00
10 changed files with 170 additions and 101 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2025 hb
Copyright (c) 2025 Hartmut Bauer
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-1
View File
@@ -24,5 +24,4 @@ daily/nathan/backup.1 20GB/ 0:40h
...
backup.7
weekly/synology 320GB/ 9:30h
logs/<hostname>/
```
+35 -35
View File
@@ -1,26 +1,26 @@
### TODOs
- code cleanup (-> export!)
- test export
- Doku
- (x) code cleanup (-> export!)
- (x) test export
DB-Dump
(x) new for postgres
(x) jede db einzeln?
(x) +mariadb
(-) hooks für weitere
- (x) new for postgres
- (x) jede db einzeln?
- (x) +mariadb
- (-) hooks für weitere
nextcloud:
(x) vol/nextcloud/data/data/hb zeigt auf NAS-share
(x) -> alles auf Server
- (x) vol/nextcloud/data/data/hb zeigt auf NAS-share
- (x) -> alles auf Server
backup MAC
(x) ccc 2x 2TB intern (weekly)
(x) ccc 2x 2TB extern
(x) TODO: SSDs auf Verschlüsselung umstellen
(x) TODO: Kalendereintrag für wöchentlichen backup
- (x) ccc 2x 2TB intern (weekly)
- (x) ccc 2x 2TB extern
- (x) TODO: SSDs auf Verschlüsselung umstellen
- (x) TODO: Kalendereintrag für wöchentlichen backup
nas-backup daily
- (x) tar, gpg to nas
@@ -33,36 +33,36 @@ nas-backup daily
- (x) TODO: script (python?)
nas-backup weekly 1
(x) media/books, media/music/_all + _hoerspiel -> tar, gpg nach //backup
(x) TODO: s. nas-backup daily
- (x) media/books, media/music/_all + _hoerspiel -> tar, gpg nach //backup
- (x) TODO: s. nas-backup daily
logging
(x) für auto-fns mail()
(x) mail() loggt in extra Datei und ruft log(), für std log
(x) Name std log in mail() ausgeben
(-) mail log lokal anlegen (wo?)
(-) am Ende von auto mail log in mail und file löschen -> py-script
(x) alle Programme müssen stdout/stderr auf std log umleiten
(x) für jeden Lauf neue log datei (+date)
(-) Name der log Datei bei !auto auf stderr ausgeben (damit stdout ggf. geparst werden kann, alt.: param --machine)
(x) log file in nfs/backups/log/$HOST_NAME-$(date '+%Y-%m-%d_%H%M').log
(x) bei jedem Lauf alte logs löschen (7d?) -> wie?
(-) evtl. logs lokal ablegen und am Ende auf NAS kopieren
- (x) für auto-fns mail()
- (x) mail() loggt in extra Datei und ruft log(), für std log
- (x) Name std log in mail() ausgeben
- (-) mail log lokal anlegen (wo?)
- (-) am Ende von auto mail log in mail und file löschen -> py-script
- (x) alle Programme müssen stdout/stderr auf std log umleiten
- (x) für jeden Lauf neue log datei (+date)
- (-) Name der log Datei bei !auto auf stderr ausgeben (damit stdout ggf. geparst werden kann, alt.: param --machine)
- (x) log file in nfs/backups/log/$HOST_NAME-$(date '+%Y-%m-%d_%H%M').log
- (x) bei jedem Lauf alte logs löschen (7d?) -> wie?
- (-) evtl. logs lokal ablegen und am Ende auf NAS kopieren
backup server+nas extern
(x) rsync nas-backup 2x HDD intern (weekly) (5TB?)
(x) TODO: script (python?) mit HD-Erkennung
(x) TODO: zusätzliche HDD
(x) TODO: Kalendereintrag, s. backup MAC
- (x) rsync nas-backup 2x HDD intern (weekly) (5TB?)
- (x) TODO: script (python?) mit HD-Erkennung
- (x) TODO: zusätzliche HDD
- (x) TODO: Kalendereintrag, s. backup MAC
export backups
(x) rsync nas-backup 2x 2TB HDD extern
(x) TODO: script, s. backup server+nas
- (x) rsync nas-backup 2x 2TB HDD extern
- (x) TODO: script, s. backup server+nas
export serien
(x) rsync dir 1x 5TB HDD extern
(x) TODO: vorhandenes script in neue Routine einbauen
- (x) rsync dir 1x 5TB HDD extern
- (x) TODO: vorhandenes script in neue Routine einbauen
export video
(x) rsync dir 1x 5TB HDD extern
(x) TODO: s. export serien
- (x) rsync dir 1x 5TB HDD extern
- (x) TODO: s. export serien
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/eval bash
#NAS_ROOT=/Users/hb/mnt/nas/backups
+1 -1
View File
@@ -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"
+83 -23
View File
@@ -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"
@@ -131,6 +153,17 @@ stop_docker() {
return $?
}
# Zugriffsrechte für Logs und Backups setzen
#
fix_acls() {
log $DEBUG "$DBG fix_acls()"
log $DEBUG "$DBG chmod -R a+r $NAS_ROOT"
chmod -R a+r $NAS_ROOT >>$LOG_FILE 2>&1
log $DEBUG "$DBG chmod -R a+r $LLOG_FILE_PATH"
chmod -R a+r $LLOG_FILE_PATH >>$LOG_FILE 2>&1
}
# Script per ssh auf Server $1 im Hintergrund starten
#
# ssh start in background
@@ -419,6 +452,7 @@ backup_daily() {
is_error $?
mail_log $INFO ">>>>>>>>>> end of auto backup"
fix_acls
send_mail_log "Daily Backup"
# ggf. weekly backup starten (z.ZT. nur auf NAS)
@@ -437,6 +471,7 @@ backup_weekly() {
is_error $?
mail_log $INFO ">>>>>>>>>> end of auto backup"
fix_acls
send_mail_log "Weekly Backup"
}
@@ -462,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 ------
@@ -498,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 -----
+33 -38
View File
@@ -3,37 +3,28 @@
# entrypoint for all actions
#
VER="2.0.4"
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 <archive> '
echo " show contents of archive"
echo ' -r, --restore <archive> <file(s)> '
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 <archive> '
echo " show contents of archive (path from $NAS_ROOT)"
echo ' -r, --restore <archive> <file(s)> '
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
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/eval bash
NAS_ROOT=/volume1/nfs/backups
#NAS_ROOT=/volume1/nfs/backups
HAS_WEEKLY=true
backup_daily1() {
+12
View File
@@ -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!"