Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
912d4b9434 | ||
|
|
a8a00a9f46 | ||
|
|
15f77b6bf5 | ||
|
|
42af16928f | ||
|
|
39bdfbd021 | ||
|
|
0cb2748447 | ||
|
|
02f82e8147 | ||
|
|
d26f7700bd | ||
|
|
328936748e | ||
|
|
ab61e0e916 |
No files matched your search
@@ -1,3 +1,4 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
cp -v *.sh ../../bin/backup
|
cp -v *.sh ../../bin/backup
|
||||||
|
cp -v save-conf ../../bin
|
||||||
Executable
+3
@@ -0,0 +1,3 @@
|
|||||||
|
#!/usr/bin/eval bash
|
||||||
|
|
||||||
|
# nothing to do
|
||||||
Executable
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# falls das nochmal gebraucht wird
|
||||||
|
|
||||||
|
HERE=$(dirname $0)
|
||||||
|
DOCKER=/usr/bin/docker
|
||||||
|
|
||||||
|
ORACLEDUMP="$DOCKER exec -i oracle /opt/oracle/product/18c/dbhomeXE/bin/expdp"
|
||||||
|
ORACLECONNECT="sbsdb_master/sbsdbpwd@//localhost:1521/xepdb1"
|
||||||
|
ORACLEDATAPUMP=/var/docker/vol/oracle/dump
|
||||||
|
|
||||||
|
function dump_oracle() {
|
||||||
|
mkdir -p $HERE/oracle > /dev/null 2>&1
|
||||||
|
echo "$(date) - Oracle dump"
|
||||||
|
$ORACLEDUMP $ORACLECONNECT dumpfile=sbsdb_dump:sbsdb.dmp logfile=sbsdb_dump:sbsdb.log reuse_dumpfiles=yes
|
||||||
|
mv $ORACLEDATAPUMP/* $HERE/oracle
|
||||||
|
}
|
||||||
|
|
||||||
|
dump_oracle
|
||||||
+8
-9
@@ -1,7 +1,8 @@
|
|||||||
#!/usr/bin/eval bash
|
#!/usr/bin/eval bash
|
||||||
|
|
||||||
|
USER_CONTAINERS=
|
||||||
|
ROOT_CONTAINERS="pihole"
|
||||||
|
|
||||||
NAS_ROOT=/var/srv/nas/backups
|
|
||||||
BACKUP_TARGET=/var/docker/tmp
|
BACKUP_TARGET=/var/docker/tmp
|
||||||
NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY"
|
NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY"
|
||||||
|
|
||||||
@@ -16,17 +17,15 @@ backup_daily2() {
|
|||||||
|
|
||||||
|
|
||||||
before_backup() {
|
before_backup() {
|
||||||
stop_docker
|
stop_containers
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
after_backup() {
|
after_backup() {
|
||||||
start_docker
|
let local rc=0
|
||||||
local dock=$?
|
start_containers
|
||||||
|
let rc=rc+$?
|
||||||
copy_to_nas "$BACKUP_TARGET" "$NAS_TARGET"
|
copy_to_nas "$BACKUP_TARGET" "$NAS_TARGET"
|
||||||
local copy=$?
|
let rc=rc+$?
|
||||||
if [ $dock -eq 0 ] && [ $copy -eq 0 ]; then
|
return $rc
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
+157
-53
@@ -1,5 +1,16 @@
|
|||||||
HOST_NAME=$(hostname -s)
|
HOST_NAME=$(hostname -s)
|
||||||
DAY=$(date +%u) # MO == 1
|
DAY=$(date +%u) # 1-7, MO is 1
|
||||||
|
WEEKLY_DAY=7 # SA->SO
|
||||||
|
|
||||||
|
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%S')"
|
||||||
|
LOG_FILE="${log_file_name}.log"
|
||||||
|
LOG_KEEP_DAYS=14
|
||||||
|
|
||||||
|
RESTORE_PATH="$NAS_MOUNT_POINT/Server/restore"
|
||||||
|
|
||||||
BACKUP_MASTER_CHECK="/var/docker/vol/proxy"
|
BACKUP_MASTER_CHECK="/var/docker/vol/proxy"
|
||||||
|
|
||||||
@@ -7,14 +18,16 @@ NAS_HOSTNAME=synology
|
|||||||
NAS_IP=10.4.2.20
|
NAS_IP=10.4.2.20
|
||||||
NAS_SCRIPT=/volume1/nfs/Server/bin/backup/main.sh
|
NAS_SCRIPT=/volume1/nfs/Server/bin/backup/main.sh
|
||||||
|
|
||||||
WEEKLY_DAY=1 # SO->MO
|
|
||||||
|
|
||||||
PASSPHRASE=L1rfCXu8PHMQsGL0HJWwzQYpCT7f5VboislOTHMaEV
|
PASSPHRASE=L1rfCXu8PHMQsGL0HJWwzQYpCT7f5VboislOTHMaEV
|
||||||
EXT=tgz.gpg
|
EXT=tgz.gpg
|
||||||
LIST_EXT=txt
|
LIST_EXT=list
|
||||||
|
|
||||||
DOCKER="/usr/bin/docker compose -f /var/docker/run/docker-compose.yml --ansi never"
|
DOCKER="/usr/bin/docker compose -f /var/docker/run/docker-compose.yml --ansi never"
|
||||||
SYNO_USB=/usr/syno/bin/synousbdisk
|
SYNO_USB=/usr/syno/bin/synousbdisk
|
||||||
|
SYSTEMCTL_USER="/usr/bin/systemctl --user --machine=container@"
|
||||||
|
SYSTEMCTL="/usr/bin/systemctl"
|
||||||
|
CONTAINER_EXEC_USER=" sudo -u container podman exec"
|
||||||
|
CONTAINER_EXEC="podman exec"
|
||||||
|
|
||||||
LOG_RECIPIENT=hb242@pm.me
|
LOG_RECIPIENT=hb242@pm.me
|
||||||
INFO=INFO
|
INFO=INFO
|
||||||
@@ -71,11 +84,12 @@ send_mail_log() {
|
|||||||
|
|
||||||
# Alte Logs löschen
|
# Alte Logs löschen
|
||||||
#
|
#
|
||||||
|
# Dateien älter als $LOG_KEEP_DAYS Tage löschen
|
||||||
|
#
|
||||||
prune_logs() {
|
prune_logs() {
|
||||||
log $DEBUG "$DBG prune_logs()"
|
log $DEBUG "$DBG prune_logs()"
|
||||||
# Dateien älter als 14 Tage löschen
|
log $DEBUG "$DBG > find \"$LOG_FILE_PATH\" -type f -mtime +$LOG_KEEP_DAYS -delete"
|
||||||
log $DEBUG "$DBG > find \"$LOG_FILE_PATH\" -type f -mtime +14 -delete"
|
find "$LOG_FILE_PATH" -type f -mtime +$LOG_KEEP_DAYS -delete >>$LOG_FILE 2>&1
|
||||||
find "$LOG_FILE_PATH" -type f -mtime +14 -delete >>$LOG_FILE 2>&1
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
# Fehler nur protokollieren, kein Grund abzubrechen
|
# Fehler nur protokollieren, kein Grund abzubrechen
|
||||||
mail_log $ERROR "$ERR error deleting old log files."
|
mail_log $ERROR "$ERR error deleting old log files."
|
||||||
@@ -85,6 +99,7 @@ prune_logs() {
|
|||||||
# ----- db dump -----
|
# ----- db dump -----
|
||||||
|
|
||||||
dump_mariadb() {
|
dump_mariadb() {
|
||||||
|
return 0
|
||||||
log $DEBUG "$DBG dump_mariadb( $@ )"
|
log $DEBUG "$DBG dump_mariadb( $@ )"
|
||||||
local dump_dir=$1
|
local dump_dir=$1
|
||||||
local mysqlconnect="--user=root --password=snafu"
|
local mysqlconnect="--user=root --password=snafu"
|
||||||
@@ -99,17 +114,20 @@ dump_mariadb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dump_postgresql() {
|
dump_postgresql() {
|
||||||
|
local pg_container=$1
|
||||||
|
local dump_dir=$2
|
||||||
log $DEBUG "$DBG dump_postgresql( $@ )"
|
log $DEBUG "$DBG dump_postgresql( $@ )"
|
||||||
local dump_dir=$1
|
delete_dir $dump_dir
|
||||||
|
check_directory $dump_dir
|
||||||
|
|
||||||
# users and roles
|
# users and roles
|
||||||
log $DEBUG "$DBG > \$DOCKER exec -u=postgres postgres pg_dumpall --globals-only"
|
log $DEBUG "$DBG > \$CONTAINER_EXEC_USER -u=postgres $pg_container pg_dumpall --globals-only"
|
||||||
$DOCKER exec -u=postgres postgres pg_dumpall --globals-only > $dump_dir/_globals.sql 2>>$LOG_FILE
|
$CONTAINER_EXEC_USER -u=postgres $pg_container pg_dumpall --globals-only > $dump_dir/_globals.sql 2>>$LOG_FILE
|
||||||
|
|
||||||
log $DEBUG "$DBG \$DOCKER exec -u=postgres postgres psql -t -c \"select datname from pg_database where not datistemplate\""
|
log $DEBUG "$DBG \$CONTAINER_EXEC_USER -u=postgres $pg_container psql -t -c \"select datname from pg_database where not datistemplate\""
|
||||||
for db in $($DOCKER exec -u=postgres postgres psql -t -c "select datname from pg_database where not datistemplate" 2>>$LOG_FILE); do
|
for db in $($CONTAINER_EXEC_USER -u=postgres $pg_container psql -t -c "select datname from pg_database where not datistemplate" 2>>$LOG_FILE); do
|
||||||
log $DEBUG "$DBG > \$DOCKER exec -u=postgres postgres pg_dump --create $db"
|
log $DEBUG "$DBG > \$CONTAINER_EXEC_USER -u=postgres $pg_container pg_dump --create $db"
|
||||||
$DOCKER exec -u=postgres postgres pg_dump --create $db > $dump_dir/$db.sql 2>>$LOG_FILE
|
$CONTAINER_EXEC_USER -u=postgres $pg_container pg_dump --create $db > $dump_dir/$db.sql 2>>$LOG_FILE
|
||||||
is_error $? false && return 1
|
is_error $? false && return 1
|
||||||
done
|
done
|
||||||
return 0
|
return 0
|
||||||
@@ -117,18 +135,75 @@ dump_postgresql() {
|
|||||||
|
|
||||||
# ----- helper functions -----
|
# ----- helper functions -----
|
||||||
|
|
||||||
start_docker() {
|
# Für Backup und Export muss das Script mit root-Rechten
|
||||||
log $DEBUG "$DBG start_docker()"
|
# ausgeführt werden.
|
||||||
log $DEBUG "$DBG > \$DOCKER up -d"
|
#
|
||||||
$DOCKER up -d >>$LOG_FILE 2>&1
|
check_root() {
|
||||||
return $?
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_docker() {
|
start_containers() {
|
||||||
log $DEBUG "$DBG stop_docker()"
|
local let rc=0
|
||||||
|
log $DEBUG "$DBG start_containers()"
|
||||||
|
if [ -f /var/docker/run/docker-compose.yml ]; then
|
||||||
|
log $DEBUG "$DBG > \$DOCKER up -d"
|
||||||
|
$DOCKER up -d >>$LOG_FILE 2>&1
|
||||||
|
let rc=rc+$?
|
||||||
|
fi
|
||||||
|
if [ -d /var/containers ]; then
|
||||||
|
do_start_stop_containers start
|
||||||
|
let rc=rc+$?
|
||||||
|
fi
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_containers() {
|
||||||
|
local let rc=0
|
||||||
|
log $DEBUG "$DBG stop_containers()"
|
||||||
|
if [ -f /var/docker/run/docker-compose.yml ]; then
|
||||||
log $DEBUG "$DBG > \$DOCKER down"
|
log $DEBUG "$DBG > \$DOCKER down"
|
||||||
$DOCKER down >>$LOG_FILE 2>&1
|
$DOCKER down >>$LOG_FILE 2>&1
|
||||||
return $?
|
let rc=rc+$?
|
||||||
|
fi
|
||||||
|
if [ -d /var/containers ]; then
|
||||||
|
do_start_stop_containers stop
|
||||||
|
let rc=rc+$?
|
||||||
|
fi
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
|
do_start_stop_containers() {
|
||||||
|
local cmd=$1
|
||||||
|
local let rc=0
|
||||||
|
log $DEBUG "$DBG do_start_stop_containers() $cmd"
|
||||||
|
if [ ! -z "$ROOT_CONTAINERS" ]; then
|
||||||
|
log $DEBUG "$DBG > $SYSTEMCTL $cmd $ROOT_CONTAINERS"
|
||||||
|
$SYSTEMCTL $cmd $ROOT_CONTAINERS >>$LOG_FILE 2>&1
|
||||||
|
let rc=rc+$?
|
||||||
|
fi
|
||||||
|
if [ ! -z "$USER_CONTAINERS" ]; then
|
||||||
|
log $DEBUG "$DBG > $SYSTEMCTL_USER $cmd $USER_CONTAINERS"
|
||||||
|
$SYSTEMCTL_USER $cmd $USER_CONTAINERS >>$LOG_FILE 2>&1
|
||||||
|
let rc=rc+$?
|
||||||
|
fi
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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 $LOG_FILE_PATH"
|
||||||
|
chmod -R a+r $LOG_FILE_PATH >>$LOG_FILE 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Script per ssh auf Server $1 im Hintergrund starten
|
# Script per ssh auf Server $1 im Hintergrund starten
|
||||||
@@ -362,7 +437,7 @@ do_auto_backup() {
|
|||||||
local rc
|
local rc
|
||||||
|
|
||||||
if ! $func$count 2>/dev/null ; then # Seiteneffekt: $func$count wird ausgeführt
|
if ! $func$count 2>/dev/null ; then # Seiteneffekt: $func$count wird ausgeführt
|
||||||
mail_log $ERROR "$ERR keine Backup-Function $func$count() für $HOST_NAME."
|
log $ERROR "$ERR keine Backup-Function $func$count() für $HOST_NAME."
|
||||||
exit 1 # kein Mail-Benachrichtigung!
|
exit 1 # kein Mail-Benachrichtigung!
|
||||||
fi
|
fi
|
||||||
set_log_info
|
set_log_info
|
||||||
@@ -409,6 +484,13 @@ backup_daily() {
|
|||||||
prune_logs
|
prune_logs
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ggf. weekly backup parallel starten (z.ZT. nur auf NAS)
|
||||||
|
if [ $HAS_WEEKLY -a $WEEKLY_DAY -eq $DAY ]; then
|
||||||
|
log $DEBUG "$DBG starting weekly backup"
|
||||||
|
sleep 2 # wg. log name
|
||||||
|
nohup $THIS_SCRIPT -w >>$LOG_FILE 2>&1 </dev/null &
|
||||||
|
fi
|
||||||
|
|
||||||
mail_log $INFO ">>>>>>>>>> daily auto backup $VER for $HOST_NAME <<<<<<<<<<"
|
mail_log $INFO ">>>>>>>>>> daily auto backup $VER for $HOST_NAME <<<<<<<<<<"
|
||||||
|
|
||||||
do_auto_backup backup_daily
|
do_auto_backup backup_daily
|
||||||
@@ -419,13 +501,9 @@ backup_daily() {
|
|||||||
is_error $?
|
is_error $?
|
||||||
|
|
||||||
mail_log $INFO ">>>>>>>>>> end of auto backup"
|
mail_log $INFO ">>>>>>>>>> end of auto backup"
|
||||||
|
fix_acls
|
||||||
send_mail_log "Daily Backup"
|
send_mail_log "Daily Backup"
|
||||||
|
|
||||||
# ggf. weekly backup starten (z.ZT. nur auf NAS)
|
|
||||||
if [ $HAS_WEEKLY -a $WEEKLY_DAY -eq $DAY ]; then
|
|
||||||
log $DEBUG "$DBG starting weekly backup"
|
|
||||||
nohup $THIS_SCRIPT -w >>$LOG_FILE 2>&1 </dev/null &
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
backup_weekly() {
|
backup_weekly() {
|
||||||
mail_log $INFO ">>>>>>>>>> weekly auto backup $VER for $HOST_NAME <<<<<<<<<<"
|
mail_log $INFO ">>>>>>>>>> weekly auto backup $VER for $HOST_NAME <<<<<<<<<<"
|
||||||
@@ -437,6 +515,7 @@ backup_weekly() {
|
|||||||
is_error $?
|
is_error $?
|
||||||
|
|
||||||
mail_log $INFO ">>>>>>>>>> end of auto backup"
|
mail_log $INFO ">>>>>>>>>> end of auto backup"
|
||||||
|
fix_acls
|
||||||
send_mail_log "Weekly Backup"
|
send_mail_log "Weekly Backup"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,21 +541,50 @@ test_integrity() {
|
|||||||
|
|
||||||
# Restore aus Archiv
|
# 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
|
# $2 ff. - zurückzusichernde Dateien/Verzeichnisse
|
||||||
#
|
#
|
||||||
# returns 0 for success, 1 otherwise
|
|
||||||
#
|
|
||||||
restore() {
|
restore() {
|
||||||
log $DEBUG "$DBG restore( $@ )"
|
log $DEBUG "$DBG restore( $@ )"
|
||||||
local archive=$1
|
local archive=$1
|
||||||
shift 1
|
shift
|
||||||
log $DEBUG "$DBG > gpg --batch --decrypt --passphrase xxxx \"$archive\" | tar -xzv $@"
|
echo "--- Restore ---"
|
||||||
gpg --batch --decrypt --passphrase $PASSPHRASE "$archive" 2>>$LOG_FILE | tar -xzv $@ >/dev/null 2>>$LOG_FILE
|
echo "--- archive: $archive"
|
||||||
|
echo "--- files: $@"
|
||||||
|
echo "--- to: $RESTORE_PATH"
|
||||||
|
echo
|
||||||
|
echo "Restore started 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[@]}
|
check_pipe_rc ${PIPESTATUS[@]}
|
||||||
return $?
|
is_error $?
|
||||||
|
mail_log $INFO ">>>>>>>>>> end of restore"
|
||||||
|
send_mail_log "Restore"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ----- archive content ------
|
# ----- archive content ------
|
||||||
@@ -498,41 +606,37 @@ create_list() {
|
|||||||
|
|
||||||
# Liste der Archives auf stdout ausgeben
|
# 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.
|
# z.B.
|
||||||
# $1 = /volume1/nfs/backups
|
# $NAS_ROOT = /volume1/nfs/backups
|
||||||
# ...
|
# ...
|
||||||
# /daily/synology/backup.3/volume1-nfs-Server.tgz.gpg
|
# /daily/synology/backup.3/volume1-nfs-Server.tgz.gpg
|
||||||
# /weekly/synology/volume1-media-books.tgz.gpg
|
# /weekly/synology/volume1-media-books.tgz.gpg
|
||||||
#
|
#
|
||||||
# $1 - Verzeichnis unter dem alle Backups liegen
|
|
||||||
#
|
|
||||||
# returns 0 for success, 1 otherwise
|
# returns 0 for success, 1 otherwise
|
||||||
#
|
#
|
||||||
list_archives() {
|
list_archives() {
|
||||||
log $DEBUG "$DBG list_archives( $@ )"
|
log $DEBUG "$DBG list_archives()"
|
||||||
local target=$1
|
local target=$1
|
||||||
local targ=${target//\//\\\/} # slashes escapen
|
local targ=${NAS_ROOT//\//\\\/} # slashes escapen
|
||||||
log $DEBUG "$DBG > find \"$target\" -type f -name \"*.$EXT\" | grep \"${HOST_NAME}/\" | sed -E \"s/^$targ//\""
|
log $DEBUG "$DBG > find \"$NAS_ROOT\" -type f -name \"*.$EXT\" | 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
|
find "$NAS_ROOT" -type f -name "*.$EXT" 2>>$LOG_FILE | sed -E "s/^$targ//" 2>>$LOG_FILE
|
||||||
check_pipe_rc ${PIPESTATUS[@]}
|
check_pipe_rc ${PIPESTATUS[@]}
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
# Inhalt des Archivs $2 auf stdout ausgeben
|
# Inhalt des Archivs $1 auf stdout ausgeben
|
||||||
#
|
#
|
||||||
# $1 - Verzeichnis unter dem alle Backups liegen
|
# $1 - Archiv-Datei mit Pfad ab $NAS_ROOT
|
||||||
# $2 - Archiv-Datei mit Pfad ab $1
|
|
||||||
#
|
#
|
||||||
# returns 0 for success, 1 otherwise
|
# returns 0 for success, 1 otherwise
|
||||||
#
|
#
|
||||||
list_archive_content() {
|
list_archive_content() {
|
||||||
log $DEBUG "$DBG list_archive_content( $@ )"
|
log $DEBUG "$DBG list_archive_content( $@ )"
|
||||||
local root=$1
|
local archive=$1
|
||||||
local archive=$2
|
log $DEBUG "$DBG > cat \"$NAS_ROOT/${archive/#\//}.$LIST_EXT\""
|
||||||
log $DEBUG "$DBG > cat \"$root/${archive/#\//}.$LIST_EXT\""
|
cat "$NAS_ROOT/${archive/#\//}.$LIST_EXT" 2>>$LOG_FILE
|
||||||
cat "$root/${archive/#\//}.$LIST_EXT" 2>>$LOG_FILE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ----- export -----
|
# ----- export -----
|
||||||
@@ -791,8 +895,8 @@ do_export() {
|
|||||||
mail_log $INFO ">>> "
|
mail_log $INFO ">>> "
|
||||||
|
|
||||||
mail_log $INFO "$INF exporting $source_path -> $mount_point"
|
mail_log $INFO "$INF exporting $source_path -> $mount_point"
|
||||||
log $DEBUG "$DBG rsync -rti --one-file-system --delete --stats --exclude=@eaDir $source_path $mount_point"
|
log $DEBUG "$DBG rsync -rti --one-file-system --delete --stats --exclude=@eaDir --exclude='*'.$LIST_EXT $source_path $mount_point"
|
||||||
rsync -rti --one-file-system --delete --stats --exclude=@eaDir $source_path $mount_point >>$LOG_FILE 2>&1
|
rsync -rti --one-file-system --delete --stats --exclude=@eaDir --exclude='*'.$LIST_EXT $source_path $mount_point >>$LOG_FILE 2>&1
|
||||||
is_error $?
|
is_error $?
|
||||||
|
|
||||||
mail_log $INFO "$INF unmounting USB device $device."
|
mail_log $INFO "$INF unmounting USB device $device."
|
||||||
|
|||||||
@@ -3,37 +3,35 @@
|
|||||||
# entrypoint for all actions
|
# entrypoint for all actions
|
||||||
#
|
#
|
||||||
|
|
||||||
VER="2.1.0"
|
# 2.111 05.05.2025 - Fix DB-Dump
|
||||||
|
# 2.1.10 05.05.2025 - Postgres-Dump auf podman umgestellt
|
||||||
|
# 2.1.9 02.05.2025 - DB-Dump erweitert, damit Dumps für mehrere postgres möglich sind
|
||||||
|
# 2.1.8 30.04.2025 - systemctl start/stop eingebaut
|
||||||
|
# 2.1.7 29.04.2025 - 1. Schritt zur Umstellung auf podman
|
||||||
|
# 2.1.6 29.04.2025 - weekly backup Sa->SO
|
||||||
|
|
||||||
show_help() {
|
VER="2.1.10"
|
||||||
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
|
|
||||||
|
|
||||||
HERE=$(dirname "$0")
|
HERE=$(dirname "$0")
|
||||||
THIS_SCRIPT=$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
|
if [ -f $HERE/main.inc.sh ]; then
|
||||||
. $HERE/main.inc.sh
|
. $HERE/main.inc.sh
|
||||||
else
|
else
|
||||||
@@ -56,9 +54,6 @@ else
|
|||||||
exit 102
|
exit 102
|
||||||
fi
|
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=
|
file=
|
||||||
archive=
|
archive=
|
||||||
@@ -71,44 +66,55 @@ while :; do
|
|||||||
;;
|
;;
|
||||||
-d|--daily)
|
-d|--daily)
|
||||||
MAIL_LOG_FILE="${log_file_name}.auto.log"
|
MAIL_LOG_FILE="${log_file_name}.auto.log"
|
||||||
|
check_root
|
||||||
backup_daily
|
backup_daily
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
-w|--weekly)
|
-w|--weekly)
|
||||||
MAIL_LOG_FILE="${log_file_name}.auto.log"
|
MAIL_LOG_FILE="${log_file_name}.auto.log"
|
||||||
|
check_root
|
||||||
backup_weekly
|
backup_weekly
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
-e|--export)
|
-e|--export)
|
||||||
MAIL_LOG_FILE="${log_file_name}.auto.log"
|
MAIL_LOG_FILE="${log_file_name}.auto.log"
|
||||||
|
check_root
|
||||||
export_backups
|
export_backups
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
--list)
|
-l|--list)
|
||||||
list_archives "$NAS_ROOT/daily/$HOST_NAME"
|
list_archives
|
||||||
if [ -d "$NAS_ROOT/weekly/$HOST_NAME" ]; then
|
|
||||||
list_archives "$NAS_ROOT/weekly/$HOST_NAME"
|
|
||||||
fi
|
|
||||||
break;
|
break;
|
||||||
;;
|
;;
|
||||||
--content)
|
-c|--content)
|
||||||
if [ "$2" ]; then
|
if [ "$2" ]; then
|
||||||
list_archive_content "$NAS_ROOT" "$2"
|
list_archive_content "$2"
|
||||||
else
|
else
|
||||||
echo 'ERROR: "--content" requires a non-empty option argument.'
|
echo 'ERROR: "--content" requires the archive name as an argument.'
|
||||||
|
echo
|
||||||
|
show_help
|
||||||
fi
|
fi
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
-r|--restore)
|
-r|--restore)
|
||||||
if [ "$2" ]; then
|
if [ "$2" ]; then
|
||||||
archive=$2
|
archive=$2
|
||||||
shift
|
shift 2
|
||||||
restore "$archive" "$@"
|
restore "$archive" "$@"
|
||||||
else
|
else
|
||||||
echo 'ERROR: "--restore" requires a non-empty option argument.'
|
echo 'ERROR: "--restore" requires at least the archive name as an argument.'
|
||||||
|
echo
|
||||||
|
show_help
|
||||||
fi
|
fi
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
|
--rx)
|
||||||
|
MAIL_LOG_FILE="${log_file_name}.auto.log"
|
||||||
|
check_root
|
||||||
|
shift
|
||||||
|
do_restore $@
|
||||||
|
break
|
||||||
|
;;
|
||||||
--) # End of all options.
|
--) # End of all options.
|
||||||
shift
|
shift
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
NAS_ROOT=/var/srv/nas/backups
|
USER_CONTAINERS="homeassistant-pod codeserver jellyfin pgadmin nextcloud-pod calibre nexus git-pod caddy.socket caddy"
|
||||||
|
ROOT_CONTAINERS=
|
||||||
|
|
||||||
DOCKER_ROOT=/var/docker
|
DOCKER_ROOT=/var/docker
|
||||||
BACKUP_TARGET=$DOCKER_ROOT/tmp
|
BACKUP_TARGET=$DOCKER_ROOT/tmp
|
||||||
NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY"
|
NAS_TARGET="$NAS_ROOT/daily/$HOST_NAME/backup.$DAY"
|
||||||
@@ -22,24 +24,25 @@ backup_daily3() {
|
|||||||
|
|
||||||
|
|
||||||
before_backup() {
|
before_backup() {
|
||||||
dump_mariadb $DOCKER_ROOT/dump/mysql
|
let local rc=0
|
||||||
local mys=$?
|
#dump_mariadb $DOCKER_ROOT/dump/mysql
|
||||||
dump_postgresql $DOCKER_ROOT/dump/postgresql
|
#let rc=rc+$?
|
||||||
local pos=$?
|
dump_postgresql ncd_pg $DOCKER_ROOT/dump/nextcloud
|
||||||
if [ $mys -gt 0 ] || [ $pos -gt 0 ]; then
|
let rc=rc+$?
|
||||||
|
dump_postgresql gitea_pg $DOCKER_ROOT/dump/gitea
|
||||||
|
let rc=rc+$?
|
||||||
|
if [ $rc -gt 0 ]; then
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
stop_docker
|
stop_containers
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
after_backup() {
|
after_backup() {
|
||||||
start_docker
|
let local rc=0
|
||||||
local dock=$?
|
start_containers
|
||||||
|
let rc=rc+$?
|
||||||
copy_to_nas "$BACKUP_TARGET" "$NAS_TARGET"
|
copy_to_nas "$BACKUP_TARGET" "$NAS_TARGET"
|
||||||
local copy=$?
|
let rc=rc+$?
|
||||||
if [ $dock -eq 0 ] && [ $copy -eq 0 ]; then
|
return $rc
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# Archive docker config
|
||||||
|
#
|
||||||
|
# copy this file to docker/run
|
||||||
|
|
||||||
|
SOURCE=/var/docker/run/docker-compose.yml
|
||||||
|
SAVE_DIR=/srv/nas/Server/CoreOS/docker-run
|
||||||
|
SAVE_FILE=$(hostname -s)-docker-compose-$(date '+%Y-%m-%d_%H%M').yml
|
||||||
|
|
||||||
|
cp $SOURCE $SAVE_DIR/$SAVE_FILE
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#!/usr/bin/eval bash
|
#!/usr/bin/eval bash
|
||||||
|
|
||||||
NAS_ROOT=/volume1/nfs/backups
|
|
||||||
HAS_WEEKLY=true
|
HAS_WEEKLY=true
|
||||||
|
|
||||||
backup_daily1() {
|
backup_daily1() {
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
|
||||||
echo "**"
|
|
||||||
echo "** ERROR: script has to be run as superuser!"
|
|
||||||
echo "**"
|
|
||||||
exit 100
|
|
||||||
fi
|
|
||||||
|
|
||||||
HERE=$(dirname "$0")
|
|
||||||
|
|
||||||
if [ -f $HERE/main.inc.sh ]; then
|
|
||||||
. $HERE/main.inc.sh
|
|
||||||
else
|
|
||||||
echo "**"
|
|
||||||
echo "** ERROR: Datei \"$HERE/main.inc.sh\" nicht gefunden. "
|
|
||||||
echo "** Script wird abgebrochen"
|
|
||||||
echo "**"
|
|
||||||
show_help
|
|
||||||
exit 101
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f $HERE/$HOST_NAME.sh ]; then
|
|
||||||
. $HERE/$HOST_NAME.sh
|
|
||||||
else
|
|
||||||
echo "**"
|
|
||||||
echo "** ERROR: Datei \"$HOST_NAME.sh\" nicht gefunden (falscher Rechner?). "
|
|
||||||
echo "** Script wird abgebrochen."
|
|
||||||
echo "**"
|
|
||||||
show_help
|
|
||||||
exit 102
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_file_name="$NAS_ROOT/log/$HOST_NAME-$(date '+%Y-%m-%d_%H%M')"
|
|
||||||
LOG_FILE="${log_file_name}.log"
|
|
||||||
|
|
||||||
# nicht auf calvados
|
|
||||||
#. $HERE/$HOST_NAME
|
|
||||||
|
|
||||||
test() {
|
|
||||||
for i in "$@"; do echo "$i"; done
|
|
||||||
}
|
|
||||||
|
|
||||||
isFunction() { declare -Ff "$1" ; }
|
|
||||||
|
|
||||||
if [ "$HOST_NAME" != "$NAS_HOSTNAME" ]; then
|
|
||||||
run_script_remote $NAS_IP "/volume1/nfs/Server/bin/backup/test.sh -x"
|
|
||||||
#ssh 10.4.2.20 "sudo sh -c 'nohup /volume1/nfs/Server/bin/backup/main.sh -e &>/dev/null < /dev/null &'"
|
|
||||||
exit
|
|
||||||
else
|
|
||||||
echo "klappt $1" > /volume1/nfs/log/backup/remote_run.log
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
exit
|
|
||||||
|
|
||||||
|
|
||||||
list1() {
|
|
||||||
EXCL=("eaDir" "Temporary Items" "lost+found" backups)
|
|
||||||
ONE="erster #1"
|
|
||||||
TWO="zweiter #1"
|
|
||||||
#for i in "${a[@]}"; do echo "$i"; done
|
|
||||||
}
|
|
||||||
list2() {
|
|
||||||
EXCL=("@eaDir" "Temporary Items" "lost+found")
|
|
||||||
ONE="eins2"
|
|
||||||
TWO="zwei2"
|
|
||||||
return 0
|
|
||||||
#for i in "${a[@]}"; do echo "$i"; done
|
|
||||||
}
|
|
||||||
|
|
||||||
fun0() {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
|
||||||
echo "**"
|
|
||||||
echo "** ERROR: script has to be run as superuser!"
|
|
||||||
echo "**"
|
|
||||||
exit 100
|
|
||||||
fi
|
|
||||||
|
|
||||||
fun0
|
|
||||||
rc=$?
|
|
||||||
|
|
||||||
if [ $rc -eq 0 ]; then
|
|
||||||
echo "$rc -eq 0"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#echo "result=$rc0"
|
|
||||||
|
|
||||||
exit
|
|
||||||
Reference in new issue
Block a user